diff --git a/bin/linux32-d/placeholder b/bin/linux32-d/placeholder new file mode 100644 index 00000000..e94296ae --- /dev/null +++ b/bin/linux32-d/placeholder @@ -0,0 +1 @@ +It's safe to delete this file \ No newline at end of file diff --git a/bin/linux32/placeholder b/bin/linux32/placeholder new file mode 100644 index 00000000..e94296ae --- /dev/null +++ b/bin/linux32/placeholder @@ -0,0 +1 @@ +It's safe to delete this file \ No newline at end of file diff --git a/bin/linux64-d/placeholder b/bin/linux64-d/placeholder new file mode 100644 index 00000000..e94296ae --- /dev/null +++ b/bin/linux64-d/placeholder @@ -0,0 +1 @@ +It's safe to delete this file \ No newline at end of file diff --git a/bin/linux64/placeholder b/bin/linux64/placeholder new file mode 100644 index 00000000..e94296ae --- /dev/null +++ b/bin/linux64/placeholder @@ -0,0 +1 @@ +It's safe to delete this file \ No newline at end of file diff --git a/bin/plugins/placeholder b/bin/plugins/placeholder index 5dd98699..e94296ae 100644 --- a/bin/plugins/placeholder +++ b/bin/plugins/placeholder @@ -1 +1 @@ -Keep me! \ No newline at end of file +It's safe to delete this file \ No newline at end of file diff --git a/bin/sqmod.ini b/bin/sqmod.ini index 890b6281..bafe3d12 100644 --- a/bin/sqmod.ini +++ b/bin/sqmod.ini @@ -1,7 +1,29 @@ -[Config] +[Squirrel] StackSize=2048 +ErrorHandling=true +EmptyInit=false + +[Log] +ConsoleDebug=true +ConsoleUser=true +ConsoleSuccess=true +ConsoleInfo=true +ConsoleWarning=true +ConsoleError=true +ConsoleFatal=true +LogFileDebug=true +LogFileUser=true +LogFileSuccess=true +LogFileInfo=true +LogFileWarning=true +LogFileError=true +LogFileFatal=true +ConsoleTimestamp=false +LogFileTimestamp=true +#Filename=mymod.log [Scripts] Source=bootstrap.nut [Options] +MyOption="Hello from config!" diff --git a/bin/win32-d/placeholder b/bin/win32-d/placeholder new file mode 100644 index 00000000..e94296ae --- /dev/null +++ b/bin/win32-d/placeholder @@ -0,0 +1 @@ +It's safe to delete this file \ No newline at end of file diff --git a/bin/win32/placeholder b/bin/win32/placeholder new file mode 100644 index 00000000..e94296ae --- /dev/null +++ b/bin/win32/placeholder @@ -0,0 +1 @@ +It's safe to delete this file \ No newline at end of file diff --git a/bin/win64-d/placeholder b/bin/win64-d/placeholder new file mode 100644 index 00000000..e94296ae --- /dev/null +++ b/bin/win64-d/placeholder @@ -0,0 +1 @@ +It's safe to delete this file \ No newline at end of file diff --git a/bin/win64/placeholder b/bin/win64/placeholder new file mode 100644 index 00000000..e94296ae --- /dev/null +++ b/bin/win64/placeholder @@ -0,0 +1 @@ +It's safe to delete this file \ No newline at end of file diff --git a/cbp/LibTCC.cbp b/cbp/LibTCC.cbp deleted file mode 100644 index d4304700..00000000 --- a/cbp/LibTCC.cbp +++ /dev/null @@ -1,177 +0,0 @@ - - - - - - diff --git a/cbp/ModTCC.cbp b/cbp/ModTCC.cbp deleted file mode 100644 index 9d0a449e..00000000 --- a/cbp/ModTCC.cbp +++ /dev/null @@ -1,446 +0,0 @@ - - - - - - diff --git a/cbp/Module.cbp b/cbp/Module.cbp index d76ad3ef..d3129f45 100644 --- a/cbp/Module.cbp +++ b/cbp/Module.cbp @@ -447,12 +447,13 @@ + + + - - @@ -461,10 +462,6 @@ - - - - @@ -482,6 +479,10 @@ + + + + @@ -496,12 +497,18 @@ - - - - + + + + + + + + + + @@ -517,8 +524,6 @@ - - diff --git a/cbp/default.workspace b/cbp/default.workspace index 10a9093d..aab317a2 100644 --- a/cbp/default.workspace +++ b/cbp/default.workspace @@ -10,7 +10,6 @@ - - + diff --git a/external/TCC/COPYING b/external/TCC/COPYING deleted file mode 100644 index 223ede7d..00000000 --- a/external/TCC/COPYING +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 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. - - - Copyright (C) - - 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/external/TCC/Changelog b/external/TCC/Changelog deleted file mode 100644 index 7cc19c86..00000000 --- a/external/TCC/Changelog +++ /dev/null @@ -1,520 +0,0 @@ -Version 0.9.27: - -Licensing: - -- TinyCC partly relicensed to MIT license - -User interface: - -- define __STDC_HOSTED__ (Michael Matz, Urs Janssen) -- added support for CPATH, C_INCLUDE_PATH and LD_LIBRARY_PATH (Andrew Aladjev -and Urs Janssen) -- added option -norunsrc to control argv[0] with tcc -run (James Lyon) -- improve --with-libgcc configure help (grischka) -- improve error message when memory is full (grischka) -- improve wording about compiler switches in documentation (Thomas Preud'homme) -- use GNU triplet prefix for cross compiler names (Thomas Preud'homme) -- ignore unknown linker optimization and as-needed option (Austin English) - -Features: - -- added ABI tests with native compiler using libtcc (James Lyon) -- added CMake build system with support for cross-compilation (James Lyon) -- improved variable length array support (James Lyon) -- add the possibility to use noname functions by ordinal (YX Hao) -- add a install-strip target to install tcc (Thomas Preud'homme) -- add runtime selection of float ABI on ARM (Thomas Preud'homme) -- add shared lib support on x86-64 (Michael Matz) - -Platforms: -- support Debian GNU/kfreeBSD 64bit userspace (Thomas Preud'homme) -- fix GNU/Hurd interpreter path (Thomas Preud'homme) -- fix configure script for FreeBSD host (Thomas Preud'homme) -- make tcc -run work reliably on ARM by flushing caches (Thomas Preud'homme) -- many x86-64 ABI fixes incl. XMM register passing (James Lyon) -- improve compatibility with mingw's long double (James Lyon) -- avoid .stabstr section name to be truncated on win32 (Roy) -- add support for load/store of _Bool value (Thomas Preud'homme) -- detect instruction with incorrect operands on x86-64 (Thomas Preud'homme) -- improved relocations on ARM (Thomas Preud'homme) -- add va_* macro implementation for ARM (Thomas Preud'homme) -- define __ARM_EABI__, __ARMEL__ and __ARM_PCS_VFP (Thomas Preud'homme) -- provide a runtime library for ARM (Thomas Preud'homme) -- vastly improved support for ARM hard float calling convention -(Thomas Preud'homme, Daniel Glöckner) -- tcc can uses libtcc1 on ARM (Thomas Preud'homme) -- use __fixdfdi for all float to integer conversion (grischka) -- simplify startup code for unix platforms (grischka) -- improve ELF generated on ARM (Thomas Preud'homme) -- add support for thumb to ARM relocation (Thomas Preud'homme) -- fix globbing to match MSVC on Windows (Thomas Preud'homme) -- deprecate FPA and OABI support for ARM (Thomas Preud'homme) -- warn about softfloat not being supported on ARM (Thomas Preud'homme) - -Bug fixes: -- many code clean up (Urs Janssen, grischka) -- fixes of other's patches (grischka, Ramsay Jones, Michael Matz) -- fix documentation about __TINYC__ (Urs Janssen) -- improve build of documentation (Urs Janssen) -- improve build instructions (Jov) -- switch from texi2html to makeinfo --html to build tcc-doc.html (James Lyon) -- improve out of tree build (James Lyon) -- improved passing and returning of struct (James Lyon) -- fix CMake build on i386 and x86-64 (James Lyon) -- fix i386 calling convention issue (James Lyon) -- fix error in Windows build of tests (James Lyon) -- fix x86-64 long double passing (James Lyon) -- fix crash with undefined struct (grischka) -- normalize slashes on win32 to always use backslashes (grischka) -- use runtime function for float to int conversion on i386 (grischka) -- improved documentation for include and lib lookup on win32 (grischka) -- detect redefinition of function (Thomas Preud'homme) -- detect the use of array of functions (Thomas Preud'homme) -- detect use of enumerator with wrong enumeration (Thomas Preud'homme) -- detect redefinition of enumerator or enumeration (Thomas Preud'homme) -- set the user-defined library search paths first (Vittorio Giovara) -- detect usage of incomplete types inside struct/union (Amine Najahi) -- various macro bug fixes (Joseph Poirier) -- avoid wrong trigger of assert on x86-64 platform (Thomas Preud'homme) -- fix NaN comparison (Thomas Preud'homme) -- use libtcc for static linking with runtime library (Thomas Preud'homme) -- fix negation of 0.0 and -0.0 values (Thomas Preud'homme) -- fix use of long long as if condition (Thomas Preud'homme) -- disable bound check if libgcc is used (Thomas Preud'homme) -- error out when casting to void (grischka) -- remove circular dependency in Makefile (grischka) -- stop preventing gcc to do strict aliasing (grischka) -- fix Windows build of tcc (grischka) -- build runtime library for arm cross compiler (Thomas Preud'homme) -- fix installation of arm cross-compiler (Thomas Preud'homme) -- add basic test for cross-compiler (Thomas Preud'homme) -- fix failure when generating PE on x86-64 (Archidemon) -- fix floating point unary minus and plus (Michael Matz) -- add more tests for signed zero float (Michael Matz) -- fix precision of double on x86-64 (Vincent Lefevre) -- fix bound checking of argv with -run switch (Kirill Smelkov) -- work around a wine cmd bug when building tcc on Windows (Austin English) -- reenable some bound check tests (grischka) -- boundtest.c lookup honors VPATH (grischka) -- diff compared to CC in test[123]b? are now errors (grischka) -- fix test3 on Windows (grischka) -- prevent gcc from building (non functional) libtcc.a (grischka) -- fix warning related to PE file generation on x86-64 (grischka) -- stop mixing ordinary and implicit rule in Makefile (Iavael) -- fix integer to double conversion on ARM (Thomas Preud'homme) -- fix parameter passing of structure < 4 bytes on ARM (Thomas Preud'homme) -- disable builtin_frame_address test on ARM due to gcc bug (Thomas Preud'homme) -- fix initialization of struct on ARM (Thomas Preud'homme) -- fix parameter passing of (unsigned) long long bitfield (Thomas Preud'homme) -- improve float to integer tests (Thomas Preud'homme) -- fix relocation of Thumb branch to ARM function (Thomas Preud'homme) -- fix char wrong compatibility with [un]signed char (Thomas Preud'homme) -- choose the code to compile based on target in libtcc1 (Thomas Preud'homme) -- fix various clang warnings (Thomas Preud'homme) -- don't hardcode tcc in Makefile for tests (Thomas Preud'homme) -- fix relocation of __bound_init bound checking code (Thomas Preud'homme) -- accept only one basic type for a given variable (Thomas Preud'homme) -- fix error when using va_* with tcc using libgcc (Thomas Preud'homme) -- support GOT32 and PLT32 reloc on the same symbol (Thomas Preud'homme) -- fix memory leak due to symbol attributes (mingodad) -- partially fix bound checking of argv and arge (Thomas Preud'homme) -- fix possible dereference when getting name of symbol (grischka) -- fix va_list type definition on x86-64 (Daniel Glöckner) -- reduce number of scan-build false positive (mingodad) - -version 0.9.26: - -User interface: -- -MD/-MF (automatically generate dependencies for make) -- -pthread option (same as -D_REENTRANT -lpthread) (Henry Kroll III) -- -m32/-m64 to re-exec cross compiler (Henry Kroll III) -- -Wl, Mimic all GNU -option forms supported by ld (Kirill Smelkov) -- new LIBTCCAPI tcc_set_options() (grischka) - -Platforms: -- Many improvements for x86-64 target (Shinichiro Hamaji, Michael Matz, grischka) -- x86-64 assembler (Frederic Feret) -- Many improvements for ARM target (Daniel Glöckner, Thomas Preud'homme) -- Support WinCE PE ARM (Timo VJ Lahde) -- Support ARM hardfloat calling convention (Thomas Preud'homme) -- Support SELinux (Security-Enhanced Linux) (Henry Kroll III) -- Support Debian GNU/kFreeBSD kernels (Pierre Chifflier) -- Support GNU/Hurd kernels (Thomas Preud'homme) -- Support OSX (tcc -run only) (Milutin Jovanovic) -- Support multiarch configuration (Thomas Preud'homme) -- Support out-of-tree build (Akim Demaille) - -Features: -- C99 variable length arrays (Thomas Preud'homme & Joe Soroka) -- Asm labels for variables and functions (Thomas Preud'homme) -- STT_GNU_IFUNC (Indirect functions as externals) (Thomas Preud'homme) -- More tests (tests2) (Milutin Jovanovic) - -version 0.9.25: - -- first support for x86-64 target (Shinichiro Hamaji) -- support µClibc -- split tcc.c into tcc.h libtcc.c tccpp.c tccgen.c tcc.c -- improved preprocess output with linenumbers and spaces preserved -- tcc_relocate now copies code into user buffer -- fix bitfields with non-int types and in unions -- improve ARM cross-compiling (Daniel Glöckner) -- link stabstr sections from multiple objects -- better (still limited) support for multiple TCCStates - -version 0.9.24: - -- added verbosity levels -v, -vv, -vvv -- Accept standard input as an inputstream (Hanzac Chen) -- Support c89 compilers other than gcc (Hanzac Chen) -- -soname linker option (Marc Andre Tanner) -- Just warn about unknown directives, ignore quotes in #error/#warning -- Define __STDC_VERSION__=199901L (477) -- Switch to newer tccpe.c (includes support for resources) -- Handle backslashes within #include/#error/#warning -- Import changesets (part 4) 428,457,460,467: defines for openbsd etc. -- Use _WIN32 for a windows hosted tcc and define it for the PE target, - otherwise define __unix / __linux (Detlef Riekenberg) -- Import changesets (part 3) 409,410: ARM EABI by Daniel Glöckner -- Some in-between fixes: - TCC -E no longer hangs with macro calls involving newlines. - (next_nomacro1 now advances the read-pointer with TOK_LINEFEED) - Global cast (int g_i = 1LL;) no longer crashes tcc. - (nocode_wanted is initially 1, and only 0 for gen_function) - On win32 now tcc.exe finds 'include' & 'lib' even if itself is in 'bin'. - (new function w32_tcc_lib_path removes 'bin' if detected) - Added quick build batch file for mingw (win32/build-tcc.bat) - Last added case label optimization (455) produced wrong code. Reverted. - -- Import more changesets from Rob Landley's fork (part 2): - 487: Handle long long constants in gen_opic() (Rob Landley) - 484: Handle parentheses within __attribute__((...)) (Rob Landley) - 480: Remove a goto in decl_initializer_alloc (Rob Landley) - 475: Fix dereferences in inline assembly output (Joshua Phillips) - 474: Cast ptrs to ints of different sizes correctly (Joshua Phillips) - 473: Fix size of structs with empty array member (Joshua Phillips) - 470: No warning for && and || with mixed pointers/integers (Rob Landley) - 469: Fix symbol visibility problems in the linker (Vincent Pit) - 468: Allow && and || involving pointer arguments (Rob Landley) - 455: Optimize case labels with no code in between (Zdenek Pavlas) - 450: Implement alloca for x86 (grischka) - 415: Parse unicode escape sequences (Axel Liljencrantz) - 407: Add a simple va_copy() in stdarg.h (Hasso Tepper) - 400: Allow typedef names as symbols (Dave Dodge) - -- Import some changesets from Rob Landley's fork (part 1): - 462: Use LGPL with bcheck.c and il-gen.c - 458: Fix global compound literals (in unary: case '&':) (Andrew Johnson) - 456: Use return code from tcc_output_file in main() (Michael Somos) - 442: Fix indirections with function pointers (***fn)() (grischka) - 441: Fix LL left shift in libtcc1.c:__shldi3 (grischka) - 440: Pass structures and function ptrs through ?: (grischka) - 439: Keep rvalue in bit assignment (bit2 = bit1 = x) (grischka) - 438: Degrade nonportable pointer assignment to warning (grischka) - 437: Call 'saveregs()' before jumping with logical and/or/not (grischka) - 435: Put local static variables into global memory (grischka) - 432/434: Cast double and ptr to bool (grischka) - 420: Zero pad x87 tenbyte long doubles (Felix Nawothnig) - 417: Make 'sizeof' unsigned (Rob Landley) - 397: Fix save_reg for longlongs (Daniel Glöckner) - 396: Fix "invalid relocation entry" problem on ubuntu - (Bernhard Fischer) - -- ignore AS_NEEDED ld command -- mark executable sections as executable when running in memory -- added support for win32 wchar_t (Filip Navara) -- segment override prefix support (Filip Navara) -- normalized slashes in paths (Filip Navara) -- windows style fastcall (Filip Navara) -- support for empty input register section in asm (Filip Navara) -- anonymous union/struct support (Filip Navara) -- fixed parsing of function parameters -- workaround for function pointers in conditional expressions (Dave Dodge) -- initial '-E' option support to use the C preprocessor alone -- discard type qualifiers when comparing function parameters (Dave Dodge) -- Bug fix: A long long value used as a test expression ignores the - upper 32 bits at runtime (Dave Dodge) -- fixed multiple concatenation of PPNUM tokens (initial patch by Dave Dodge) -- fixed multiple typedef specifiers handling -- fixed sign extension in some type conversions (Dave Dodge) - -version 0.9.23: - -- initial PE executable format for windows version (grischka) -- '#pragma pack' support (grischka) -- '#include_next' support (Bernhard Fischer) -- ignore '-pipe' option -- added -f[no-]leading-underscore -- preprocessor function macro parsing fix (grischka) - -version 0.9.22: - -- simple memory optimisations: kernel compilation is 30% faster -- linker symbol definitions fixes -- gcc 3.4 fixes -- fixed value stack full error -- 'packed' attribute support for variables and structure fields -- ignore 'const' and 'volatile' in function prototypes -- allow '_Bool' in bit fields - -version 0.9.21: - -- ARM target support (Daniel Glöckner) -- added '-funsigned-char, '-fsigned-char' and - '-Wimplicit-function-declaration' -- fixed assignment of const struct in struct -- line comment fix (reported by Bertram Felgenhauer) -- initial TMS320C67xx target support (TK) -- win32 configure -- regparm() attribute -- many built-in assembler fixes -- added '.org', '.fill' and '.previous' assembler directives -- '-fno-common' option -- '-Ttext' linker option -- section alignment fixes -- bit fields fixes -- do not generate code for unused inline functions -- '-oformat' linker option. -- added 'binary' output format. - -version 0.9.20: - -- added '-w' option -- added '.gnu.linkonce' ELF sections support -- fixed libc linking when running in memory (avoid 'stat' function - errors). -- extended '-run' option to be able to give several arguments to a C - script. - -version 0.9.19: - -- "alacarte" linking (Dave Long) -- simpler function call -- more strict type checks -- added 'const' and 'volatile' support and associated warnings -- added -Werror, -Wunsupported, -Wwrite-strings, -Wall. -- added __builtin_types_compatible_p() and __builtin_constant_p() -- chars support in assembler (Dave Long) -- .string, .globl, .section, .text, .data and .bss asm directive - support (Dave Long) -- man page generated from tcc-doc.texi -- fixed macro argument substitution -- fixed zero argument macro parsing -- changed license to LGPL -- added -rdynamic option support - -version 0.9.18: - -- header fix (time.h) -- fixed inline asm without operand case -- fixed 'default:' or 'case x:' with '}' after (incorrect C construct accepted - by gcc) -- added 'A' inline asm constraint. - -version 0.9.17: - -- PLT generation fix -- tcc doc fixes (Peter Lund) -- struct parse fix (signaled by Pedro A. Aranda Gutierrez) -- better _Bool lvalue support (signaled by Alex Measday) -- function parameters must be converted to pointers (signaled by Neil Brown) -- sanitized string and character constant parsing -- fixed comment parse (signaled by Damian M Gryski) -- fixed macro function bug (signaled by Philippe Ribet) -- added configure (initial patch by Mitchell N Charity) -- added '-run' and '-v' options (initial patch by vlindos) -- added real date report in __DATE__ and __TIME__ macros - -version 0.9.16: - -- added assembler language support -- added GCC inline asm() support -- fixed multiple variable definitions : uninitialized variables are - created as COMMON symbols. -- optimized macro processing -- added GCC statement expressions support -- added GCC local labels support -- fixed array declaration in old style function parameters -- support casts in static structure initializations -- added various __xxx[__] keywords for GCC compatibility -- ignore __extension__ GCC in an expression or in a type (still not perfect) -- added '? :' GCC extension support - -version 0.9.15: - -- compilation fixes for glibc 2.2, gcc 2.95.3 and gcc 3.2. -- FreeBSD compile fixes. Makefile patches still missing (Carl Drougge). -- fixed file type guessing if '.' is in the path. -- fixed tcc_compile_string() -- add a dummy page in ELF files to fix RX/RW accesses (pageexec at - freemail dot hu). - -version 0.9.14: - -- added #warning. error message if invalid preprocessing directive. -- added CType structure to ease typing (faster parse). -- suppressed secondary hash tables (faster parse). -- rewrote parser by optimizing common cases (faster parse). -- fixed signed long long comparisons. -- fixed 'int a(), b();' declaration case. -- fixed structure init without '{}'. -- correct alignment support in structures. -- empty structures support. -- gcc testsuite now supported. -- output only warning if implicit integer/pointer conversions. -- added static bitfield init. - -version 0.9.13: - -- correct preprocessing token pasting (## operator) in all cases (added - preprocessing number token). -- fixed long long register spill. -- fixed signed long long '>>'. -- removed memory leaks. -- better error handling : processing can continue on link errors. A - custom callback can be added to display error messages. Most - errors do not call exit() now. -- ignore -O, -W, -m and -f options -- added old style function declarations -- added GCC __alignof__ support. -- added GCC typeof support. -- added GCC computed gotos support. -- added stack backtrace in runtime error message. Improved runtime - error position display. - -version 0.9.12: - -- more fixes for || and && handling. -- improved '? :' type handling. -- fixed bound checking generation with structures -- force '#endif' to be in same file as matching '#if' -- #include file optimization with '#ifndef #endif' construct detection -- macro handling optimization -- added tcc_relocate() and tcc_get_symbol() in libtcc. - -version 0.9.11: - -- stdarg.h fix for double type (thanks to Philippe Ribet). -- correct white space characters and added MSDOS newline support. -- fixed invalid implicit function call type declaration. -- special macros such as __LINE__ are defined if tested with defined(). -- fixed '!' operator with relocated address. -- added symbol + offset relocation (fixes some static variable initializers) -- '-l' option can be specified anywhere. '-c' option yields default - output name. added '-r' option for relocatable output. -- fixed '\nnn' octal parsing. -- fixed local extern variables declarations. - -version 0.9.10: - -- fixed lvalue type when saved in local stack. -- fixed '#include' syntax when using macros. -- fixed '#line' bug. -- removed size limit on strings. Unified string constants handling - with variable declarations. -- added correct support for '\xX' in wchar_t strings. -- added support for bound checking in generated executables -- fixed -I include order. -- fixed incorrect function displayed in runtime error. - -version 0.9.9: - -- fixed preprocessor expression parsing for #if/#elif. -- relocated debug info (.stab section). -- relocated bounds info (.bounds section). -- fixed cast to char of char constants ('\377' is -1 instead of 255) -- fixed implicit cast for unary plus. -- strings and '__func__' have now 'char[]' type instead of 'char *' - (fixes sizeof() return value). -- added __start_xxx and __stop_xxx symbols in linker. -- better DLL creation support (option -shared begins to work). -- ELF sections and hash tables are resized dynamically. -- executables and DLLs are stripped by default. - -version 0.9.8: - -- First version of full ELF linking support (generate objects, static - executable, dynamic executable, dynamic libraries). Dynamic library - support is not finished (need PIC support in compiler and some - patches in symbol exporting). -- First version of ELF loader for object (.o) and archive (.a) files. -- Support of simple GNU ld scripts (GROUP and FILE commands) -- Separated runtime library and bound check code from TCC (smaller - compiler core). -- fixed register reload in float compare. -- fixed implicit char/short to int casting. -- allow array type for address of ('&') operator. -- fixed unused || or && result. -- added GCC style variadic macro support. -- optimized bound checking code for array access. -- tcc includes are now in $(prefix)/lib/tcc/include. -- more command line options - more consistent handling of multiple - input files. -- added tcc man page (thanks to Cyril Bouthors). -- uClibc Makefile update -- converted documentation to texinfo format. -- added developper's guide in documentation. - -version 0.9.7: - -- added library API for easy dynamic compilation (see libtcc.h - first - draft). -- fixed long long register spill bug. -- fixed '? :' register spill bug. - -version 0.9.6: - -- added floating point constant propagation (fixes negative floating - point constants bug). - -version 0.9.5: - - - uClibc patches (submitted by Alfonso Martone). - - error reporting fix - - added CONFIG_TCC_BCHECK to get smaller code if needed. - -version 0.9.4: - - - windows port (currently cannot use -g, -b and dll functions). - - faster and simpler I/O handling. - - '-D' option works in all cases. - - preprocessor fixes (#elif and empty macro args) - - floating point fixes - - first code for CIL generation (does not work yet) - -version 0.9.3: - - - better and smaller code generator. - - full ISOC99 64 bit 'long long' support. - - full 32 bit 'float', 64 bit 'double' and 96 bit 'long double' support. - - added '-U' option. - - added assembly sections support. - - even faster startup time by mmaping sections instead of mallocing them. - - added GNUC __attribute__ keyword support (currently supports - 'section' and 'aligned' attributes). - - added ELF file output (only usable for debugging now) - - added debug symbol generation (STAB format). - - added integrated runtime error analysis ('-g' option: print clear - run time error messages instead of "Segmentation fault"). - - added first version of tiny memory and bound checker ('-b' option). - -version 0.9.2: - - - even faster parsing. - - various syntax parsing fixes. - - fixed external relocation handling for variables or functions pointers. - - better function pointers type handling. - - can compile multiple files (-i option). - - ANSI C bit fields are supported. - - beginning of float/double/long double support. - - beginning of long long support. - -version 0.9.1: - - - full ISOC99 initializers handling. - - compound literals. - - structures handle in assignments and as function param or return value. - - wide chars and strings. - - macro bug fix - -version 0.9: - - initial version. diff --git a/external/TCC/README b/external/TCC/README deleted file mode 100644 index 0b789b2d..00000000 --- a/external/TCC/README +++ /dev/null @@ -1,104 +0,0 @@ -Tiny C Compiler - C Scripting Everywhere - The Smallest ANSI C compiler ------------------------------------------------------------------------ - -Features: --------- - -- SMALL! You can compile and execute C code everywhere, for example on - rescue disks. - -- FAST! tcc generates optimized x86 code. No byte code - overhead. Compile, assemble and link about 7 times faster than 'gcc - -O0'. - -- UNLIMITED! Any C dynamic library can be used directly. TCC is - heading torward full ISOC99 compliance. TCC can of course compile - itself. - -- SAFE! tcc includes an optional memory and bound checker. Bound - checked code can be mixed freely with standard code. - -- Compile and execute C source directly. No linking or assembly - necessary. Full C preprocessor included. - -- C script supported : just add '#!/usr/local/bin/tcc -run' at the first - line of your C source, and execute it directly from the command - line. - -Documentation: -------------- - -1) Installation on a i386/x86_64/arm Linux/OSX/FreeBSD host (for Windows read tcc-win32.txt) - -Note: For OSX and FreeBSD, gmake should be used instead of make. - - ./configure - make - make test - make install - -Alternatively, out-of-tree builds are supported: you may use different -directories to hold build objects, kept separate from your source tree: - - mkdir _build - cd _build - ../configure - make - make test - make install - -Texi2html must be installed to compile the doc. -By default, tcc is installed in /usr/local/bin. -./configure --help shows configuration options. - - -2) Introduction - -We assume here that you know ANSI C. Look at the example ex1.c to know -what the programs look like. - -The include file can be used if you want a small basic libc -include support (especially useful for floppy disks). Of course, you -can also use standard headers, although they are slower to compile. - -You can begin your C script with '#!/usr/local/bin/tcc -run' on the first -line and set its execute bits (chmod a+x your_script). Then, you can -launch the C code as a shell or perl script :-) The command line -arguments are put in 'argc' and 'argv' of the main functions, as in -ANSI C. - -3) Examples - -ex1.c: simplest example (hello world). Can also be launched directly -as a script: './ex1.c'. - -ex2.c: more complicated example: find a number with the four -operations given a list of numbers (benchmark). - -ex3.c: compute fibonacci numbers (benchmark). - -ex4.c: more complicated: X11 program. Very complicated test in fact -because standard headers are being used ! As for ex1.c, can also be launched -directly as a script: './ex4.c'. - -ex5.c: 'hello world' with standard glibc headers. - -tcc.c: TCC can of course compile itself. Used to check the code -generator. - -tcctest.c: auto test for TCC which tests many subtle possible bugs. Used -when doing 'make test'. - -4) Full Documentation - -Please read tcc-doc.html to have all the features of TCC. - -Additional information is available for the Windows port in tcc-win32.txt. - -License: -------- - -TCC is distributed under the GNU Lesser General Public License (see -COPYING file). - -Fabrice Bellard. diff --git a/external/TCC/RELICENSING b/external/TCC/RELICENSING deleted file mode 100644 index a067c042..00000000 --- a/external/TCC/RELICENSING +++ /dev/null @@ -1,59 +0,0 @@ - - Relicensing TinyCC - ------------------ - - The authors listed below hereby confirm their agreement to relicense TinyCC - including their past contributions under the following terms: - - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - - - Author (name) I agree (YES/NO) Files/Features (optional) - ------------------------------------------------------------------------------ - Adam Sampson YES makefiles - Daniel Glöckner NO arm-gen.c - Daniel Glöckner YES not arm-gen.c - Edmund Grimley Evans YES arm64 - Fabrice Bellard YES original author - Frédéric Féret YES x86 64/16 bit asm - grischka YES tccpe.c - Henry Kroll YES - Joe Soroka YES - Kirill Smelkov YES - mingodad YES - Pip Cet YES - Shinichiro Hamaji YES x86_64-gen.c - Vincent Lefèvre YES - Thomas Preud'homme YES arm-gen.c - Timo VJ Lähde (Timppa) ? tiny_libmaker.c - TK ? tcccoff.c c67-gen.c - Urs Janssen YES - waddlesplash YES - - - ------------------------------------------------------------------------------ - - Please add yourself to the list above (rsp. replace the question mark) - and (after fetching the latest version) commit to the "mob" branch with - commit message: - - Relicensing TinyCC - - Thanks. diff --git a/external/TCC/TODO b/external/TCC/TODO deleted file mode 100644 index e6e5b070..00000000 --- a/external/TCC/TODO +++ /dev/null @@ -1,110 +0,0 @@ -TODO list: - -Bugs: - -- fix macro substitution with nested definitions (ShangHongzhang) -- FPU st(0) is left unclean (kwisatz haderach). Incompatible with - optimized gcc/msc code - -- constructors -- cast bug (Peter Wang) -- define incomplete type if defined several times (Peter Wang). -- test binutils/gcc compile -- tci patch + argument. -- see -lxxx bug (Michael Charity). -- see transparent union pb in /urs/include/sys/socket.h -- precise behaviour of typeof with arrays ? (__put_user macro) - but should suffice for most cases) -- handle '? x, y : z' in unsized variable initialization (',' is - considered incorrectly as separator in preparser) -- transform functions to function pointers in function parameters - (net/ipv4/ip_output.c) -- fix function pointer type display -- check lcc test suite -> fix bitfield binary operations -- check section alignment in C -- fix invalid cast in comparison 'if (v == (int8_t)v)' -- finish varargs.h support (gcc 3.2 testsuite issue) -- fix static functions declared inside block -- fix multiple unions init -- sizeof, alignof, typeof can still generate code in some cases. -- Fix the remaining libtcc memory leaks. -- make libtcc fully reentrant (except for the compilation stage itself). -- struct/union/enum definitions in nested scopes (see also Debian bug #770657) -- __STDC_IEC_559__: float f(void) { static float x = 0.0 / 0.0; return x; } - -Portability: - -- it is assumed that int is 32-bit and sizeof(int) == 4 -- int is used when host or target size_t would make more sense -- TCC handles target floating-point (fp) values using the host's fp - arithmetic, which is simple and fast but may lead to exceptions - and inaccuracy and wrong representations when cross-compiling - -Linking: - -- static linking does not work -- with "-run" and libtcc, no PLT is used, so branches may be out of - range and relocations may fail; as a result libtest fails on arm64; see: - https://lists.gnu.org/archive/html/tinycc-devel/2015-03/msg00111.html - -Bound checking: - -- '-b' bug. -- fix bound exit on RedHat 7.3 -- setjmp is not supported properly in bound checking. -- fix bound check code with '&' on local variables (currently done - only for local arrays). -- bound checking and float/long long/struct copy code. bound - checking and symbol + offset optimization - -Missing features: - -- disable-asm and disable-bcheck options -- __builtin_expect() -- improve '-E' option. -- atexit (Nigel Horne) -- packed attribute -- C99: add complex types (gcc 3.2 testsuite issue) -- postfix compound literals (see 20010124-1.c) - -Optimizations: - -- suppress specific anonymous symbol handling -- more parse optimizations (=even faster compilation) -- memory alloc optimizations (=even faster compilation) -- optimize VT_LOCAL + const -- better local variables handling (needed for other targets) - -Not critical: - -- C99: fix multiple compound literals inits in blocks (ISOC99 - normative example - only relevant when using gotos! -> must add - boolean variable to tell if compound literal was already - initialized). -- add PowerPC or ARM code generator and improve codegen for RISC (need - to suppress VT_LOCAL and use a base register instead). -- interactive mode / integrated debugger -- fix preprocessor symbol redefinition -- add portable byte code generator and interpreter for other - unsupported architectures. -- C++: variable declaration in for, minimal 'class' support. -- win32: __intxx. use resolve for bchecked malloc et al. - check exception code (exception filter func). -- handle void (__attribute__() *ptr)() -- VLAs are implemented in a way that is not compatible with signals: - http://lists.gnu.org/archive/html/tinycc-devel/2015-11/msg00018.html - -Fixed (probably): - -- bug with defines: - #define spin_lock(lock) do { } while (0) - #define wq_spin_lock spin_lock - #define TEST() wq_spin_lock(a) -- typedefs can be structure fields -- see bugfixes.diff + improvement.diff from Daniel Glockner -- long long constant evaluation -- add alloca() -- gcc '-E' option. -- #include_next support for /usr/include/limits ? -- function pointers/lvalues in ? : (linux kernel net/core/dev.c) -- win32: add __stdcall, check GetModuleHandle for dlls. diff --git a/external/TCC/VERSION b/external/TCC/VERSION deleted file mode 100644 index 46e7a712..00000000 --- a/external/TCC/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.9.26 diff --git a/external/TCC/c67-gen.c b/external/TCC/c67-gen.c deleted file mode 100644 index 5ea96665..00000000 --- a/external/TCC/c67-gen.c +++ /dev/null @@ -1,2549 +0,0 @@ -/* - * TMS320C67xx code generator for TCC - * - * Copyright (c) 2001, 2002 Fabrice Bellard - * - * 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef TARGET_DEFS_ONLY - -/* #define ASSEMBLY_LISTING_C67 */ - -/* number of available registers */ -#define NB_REGS 24 - -/* a register can belong to several classes. The classes must be - sorted from more general to more precise (see gv2() code which does - assumptions on it). */ -#define RC_INT 0x0001 /* generic integer register */ -#define RC_FLOAT 0x0002 /* generic float register */ -#define RC_EAX 0x0004 -#define RC_ST0 0x0008 -#define RC_ECX 0x0010 -#define RC_EDX 0x0020 -#define RC_INT_BSIDE 0x00000040 /* generic integer register on b side */ -#define RC_C67_A4 0x00000100 -#define RC_C67_A5 0x00000200 -#define RC_C67_B4 0x00000400 -#define RC_C67_B5 0x00000800 -#define RC_C67_A6 0x00001000 -#define RC_C67_A7 0x00002000 -#define RC_C67_B6 0x00004000 -#define RC_C67_B7 0x00008000 -#define RC_C67_A8 0x00010000 -#define RC_C67_A9 0x00020000 -#define RC_C67_B8 0x00040000 -#define RC_C67_B9 0x00080000 -#define RC_C67_A10 0x00100000 -#define RC_C67_A11 0x00200000 -#define RC_C67_B10 0x00400000 -#define RC_C67_B11 0x00800000 -#define RC_C67_A12 0x01000000 -#define RC_C67_A13 0x02000000 -#define RC_C67_B12 0x04000000 -#define RC_C67_B13 0x08000000 -#define RC_IRET RC_C67_A4 /* function return: integer register */ -#define RC_LRET RC_C67_A5 /* function return: second integer register */ -#define RC_FRET RC_C67_A4 /* function return: float register */ - -/* pretty names for the registers */ -enum { - TREG_EAX = 0, // really A2 - TREG_ECX, // really A3 - TREG_EDX, // really B0 - TREG_ST0, // really B1 - TREG_C67_A4, - TREG_C67_A5, - TREG_C67_B4, - TREG_C67_B5, - TREG_C67_A6, - TREG_C67_A7, - TREG_C67_B6, - TREG_C67_B7, - TREG_C67_A8, - TREG_C67_A9, - TREG_C67_B8, - TREG_C67_B9, - TREG_C67_A10, - TREG_C67_A11, - TREG_C67_B10, - TREG_C67_B11, - TREG_C67_A12, - TREG_C67_A13, - TREG_C67_B12, - TREG_C67_B13, -}; - -/* return registers for function */ -#define REG_IRET TREG_C67_A4 /* single word int return register */ -#define REG_LRET TREG_C67_A5 /* second word return register (for long long) */ -#define REG_FRET TREG_C67_A4 /* float return register */ - -/* defined if function parameters must be evaluated in reverse order */ -/* #define INVERT_FUNC_PARAMS */ - -/* defined if structures are passed as pointers. Otherwise structures - are directly pushed on stack. */ -/* #define FUNC_STRUCT_PARAM_AS_PTR */ - -/* pointer size, in bytes */ -#define PTR_SIZE 4 - -/* long double size and alignment, in bytes */ -#define LDOUBLE_SIZE 12 -#define LDOUBLE_ALIGN 4 -/* maximum alignment (for aligned attribute support) */ -#define MAX_ALIGN 8 - -/******************************************************/ -/* ELF defines */ - -#define EM_TCC_TARGET EM_C60 - -/* relocation type for 32 bit data relocation */ -#define R_DATA_32 R_C60_32 -#define R_DATA_PTR R_C60_32 -#define R_JMP_SLOT R_C60_JMP_SLOT -#define R_COPY R_C60_COPY - -#define ELF_START_ADDR 0x00000400 -#define ELF_PAGE_SIZE 0x1000 - -/******************************************************/ -#else /* ! TARGET_DEFS_ONLY */ -/******************************************************/ -#include "tcc.h" - -ST_DATA const int reg_classes[NB_REGS] = { - /* eax */ RC_INT | RC_FLOAT | RC_EAX, - // only allow even regs for floats (allow for doubles) - /* ecx */ RC_INT | RC_ECX, - /* edx */ RC_INT | RC_INT_BSIDE | RC_FLOAT | RC_EDX, - // only allow even regs for floats (allow for doubles) - /* st0 */ RC_INT | RC_INT_BSIDE | RC_ST0, - /* A4 */ RC_C67_A4, - /* A5 */ RC_C67_A5, - /* B4 */ RC_C67_B4, - /* B5 */ RC_C67_B5, - /* A6 */ RC_C67_A6, - /* A7 */ RC_C67_A7, - /* B6 */ RC_C67_B6, - /* B7 */ RC_C67_B7, - /* A8 */ RC_C67_A8, - /* A9 */ RC_C67_A9, - /* B8 */ RC_C67_B8, - /* B9 */ RC_C67_B9, - /* A10 */ RC_C67_A10, - /* A11 */ RC_C67_A11, - /* B10 */ RC_C67_B10, - /* B11 */ RC_C67_B11, - /* A12 */ RC_C67_A10, - /* A13 */ RC_C67_A11, - /* B12 */ RC_C67_B10, - /* B13 */ RC_C67_B11 -}; - -// although tcc thinks it is passing parameters on the stack, -// the C67 really passes up to the first 10 params in special -// regs or regs pairs (for 64 bit params). So keep track of -// the stack offsets so we can translate to the appropriate -// reg (pair) - -#define NoCallArgsPassedOnStack 10 -int NoOfCurFuncArgs; -int TranslateStackToReg[NoCallArgsPassedOnStack]; -int ParamLocOnStack[NoCallArgsPassedOnStack]; -int TotalBytesPushedOnStack; - -#ifndef FALSE -# define FALSE 0 -# define TRUE 1 -#endif - -#undef BOOL -#define BOOL int - -#define ALWAYS_ASSERT(x) \ -do {\ - if (!(x))\ - tcc_error("internal compiler error file at %s:%d", __FILE__, __LINE__);\ -} while (0) - -/******************************************************/ -static unsigned long func_sub_sp_offset; -static int func_ret_sub; - -static BOOL C67_invert_test; -static int C67_compare_reg; - -#ifdef ASSEMBLY_LISTING_C67 -FILE *f = NULL; -#endif - -void C67_g(int c) -{ - int ind1; - -#ifdef ASSEMBLY_LISTING_C67 - fprintf(f, " %08X", c); -#endif - ind1 = ind + 4; - if (ind1 > (int) cur_text_section->data_allocated) - section_realloc(cur_text_section, ind1); - cur_text_section->data[ind] = c & 0xff; - cur_text_section->data[ind + 1] = (c >> 8) & 0xff; - cur_text_section->data[ind + 2] = (c >> 16) & 0xff; - cur_text_section->data[ind + 3] = (c >> 24) & 0xff; - ind = ind1; -} - - -/* output a symbol and patch all calls to it */ -void gsym_addr(int t, int a) -{ - int n, *ptr; - while (t) { - ptr = (int *) (cur_text_section->data + t); - { - Sym *sym; - - // extract 32 bit address from MVKH/MVKL - n = ((*ptr >> 7) & 0xffff); - n |= ((*(ptr + 1) >> 7) & 0xffff) << 16; - - // define a label that will be relocated - - sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0); - greloc(cur_text_section, sym, t, R_C60LO16); - greloc(cur_text_section, sym, t + 4, R_C60HI16); - - // clear out where the pointer was - - *ptr &= ~(0xffff << 7); - *(ptr + 1) &= ~(0xffff << 7); - } - t = n; - } -} - -void gsym(int t) -{ - gsym_addr(t, ind); -} - -// these are regs that tcc doesn't really know about, -// but assign them unique values so the mapping routines -// can distinguish them - -#define C67_A0 105 -#define C67_SP 106 -#define C67_B3 107 -#define C67_FP 108 -#define C67_B2 109 -#define C67_CREG_ZERO -1 /* Special code for no condition reg test */ - - -int ConvertRegToRegClass(int r) -{ - // only works for A4-B13 - - return RC_C67_A4 << (r - TREG_C67_A4); -} - - -// map TCC reg to C67 reg number - -int C67_map_regn(int r) -{ - if (r == 0) // normal tcc regs - return 0x2; // A2 - else if (r == 1) // normal tcc regs - return 3; // A3 - else if (r == 2) // normal tcc regs - return 0; // B0 - else if (r == 3) // normal tcc regs - return 1; // B1 - else if (r >= TREG_C67_A4 && r <= TREG_C67_B13) // these form a pattern of alt pairs - return (((r & 0xfffffffc) >> 1) | (r & 1)) + 2; - else if (r == C67_A0) - return 0; // set to A0 (offset reg) - else if (r == C67_B2) - return 2; // set to B2 (offset reg) - else if (r == C67_B3) - return 3; // set to B3 (return address reg) - else if (r == C67_SP) - return 15; // set to SP (B15) (offset reg) - else if (r == C67_FP) - return 15; // set to FP (A15) (offset reg) - else if (r == C67_CREG_ZERO) - return 0; // Special code for no condition reg test - else - ALWAYS_ASSERT(FALSE); - - return 0; -} - -// mapping from tcc reg number to -// C67 register to condition code field -// -// valid condition code regs are: -// -// tcc reg 2 ->B0 -> 1 -// tcc reg 3 ->B1 -> 2 -// tcc reg 0 -> A2 -> 5 -// tcc reg 1 -> A3 -> X -// tcc reg B2 -> 3 - -int C67_map_regc(int r) -{ - if (r == 0) // normal tcc regs - return 0x5; - else if (r == 2) // normal tcc regs - return 0x1; - else if (r == 3) // normal tcc regs - return 0x2; - else if (r == C67_B2) // normal tcc regs - return 0x3; - else if (r == C67_CREG_ZERO) - return 0; // Special code for no condition reg test - else - ALWAYS_ASSERT(FALSE); - - return 0; -} - - -// map TCC reg to C67 reg side A or B - -int C67_map_regs(int r) -{ - if (r == 0) // normal tcc regs - return 0x0; - else if (r == 1) // normal tcc regs - return 0x0; - else if (r == 2) // normal tcc regs - return 0x1; - else if (r == 3) // normal tcc regs - return 0x1; - else if (r >= TREG_C67_A4 && r <= TREG_C67_B13) // these form a pattern of alt pairs - return (r & 2) >> 1; - else if (r == C67_A0) - return 0; // set to A side - else if (r == C67_B2) - return 1; // set to B side - else if (r == C67_B3) - return 1; // set to B side - else if (r == C67_SP) - return 0x1; // set to SP (B15) B side - else if (r == C67_FP) - return 0x0; // set to FP (A15) A side - else - ALWAYS_ASSERT(FALSE); - - return 0; -} - -int C67_map_S12(char *s) -{ - if (strstr(s, ".S1") != NULL) - return 0; - else if (strcmp(s, ".S2")) - return 1; - else - ALWAYS_ASSERT(FALSE); - - return 0; -} - -int C67_map_D12(char *s) -{ - if (strstr(s, ".D1") != NULL) - return 0; - else if (strcmp(s, ".D2")) - return 1; - else - ALWAYS_ASSERT(FALSE); - - return 0; -} - - - -void C67_asm(char *s, int a, int b, int c) -{ - BOOL xpath; - -#ifdef ASSEMBLY_LISTING_C67 - if (!f) { - f = fopen("TCC67_out.txt", "wt"); - } - fprintf(f, "%04X ", ind); -#endif - - if (strstr(s, "MVKL") == s) { - C67_g((C67_map_regn(b) << 23) | - ((a & 0xffff) << 7) | (0x0a << 2) | (C67_map_regs(b) << 1)); - } else if (strstr(s, "MVKH") == s) { - C67_g((C67_map_regn(b) << 23) | - (((a >> 16) & 0xffff) << 7) | - (0x1a << 2) | (C67_map_regs(b) << 1)); - } else if (strstr(s, "STW.D SP POST DEC") == s) { - C67_g((C67_map_regn(a) << 23) | //src - (15 << 18) | //SP B15 - (2 << 13) | //ucst5 (must keep 8 byte boundary !!) - (0xa << 9) | //mode a = post dec ucst - (0 << 8) | //r (LDDW bit 0) - (1 << 7) | //y D1/D2 use B side - (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(a) << 1) | //side of src - (0 << 0)); //parallel - } else if (strstr(s, "STB.D *+SP[A0]") == s) { - C67_g((C67_map_regn(a) << 23) | //src - (15 << 18) | //base reg A15 - (0 << 13) | //offset reg A0 - (5 << 9) | //mode 5 = pos offset, base reg + off reg - (0 << 8) | //r (LDDW bit 0) - (0 << 7) | //y D1/D2 A side - (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(a) << 1) | //side of src - (0 << 0)); //parallel - } else if (strstr(s, "STH.D *+SP[A0]") == s) { - C67_g((C67_map_regn(a) << 23) | //src - (15 << 18) | //base reg A15 - (0 << 13) | //offset reg A0 - (5 << 9) | //mode 5 = pos offset, base reg + off reg - (0 << 8) | //r (LDDW bit 0) - (0 << 7) | //y D1/D2 A side - (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(a) << 1) | //side of src - (0 << 0)); //parallel - } else if (strstr(s, "STB.D *+SP[A0]") == s) { - C67_g((C67_map_regn(a) << 23) | //src - (15 << 18) | //base reg A15 - (0 << 13) | //offset reg A0 - (5 << 9) | //mode 5 = pos offset, base reg + off reg - (0 << 8) | //r (LDDW bit 0) - (0 << 7) | //y D1/D2 A side - (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(a) << 1) | //side of src - (0 << 0)); //parallel - } else if (strstr(s, "STH.D *+SP[A0]") == s) { - C67_g((C67_map_regn(a) << 23) | //src - (15 << 18) | //base reg A15 - (0 << 13) | //offset reg A0 - (5 << 9) | //mode 5 = pos offset, base reg + off reg - (0 << 8) | //r (LDDW bit 0) - (0 << 7) | //y D1/D2 A side - (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(a) << 1) | //side of src - (0 << 0)); //parallel - } else if (strstr(s, "STW.D *+SP[A0]") == s) { - C67_g((C67_map_regn(a) << 23) | //src - (15 << 18) | //base reg A15 - (0 << 13) | //offset reg A0 - (5 << 9) | //mode 5 = pos offset, base reg + off reg - (0 << 8) | //r (LDDW bit 0) - (0 << 7) | //y D1/D2 A side - (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(a) << 1) | //side of src - (0 << 0)); //parallel - } else if (strstr(s, "STW.D *") == s) { - C67_g((C67_map_regn(a) << 23) | //src - (C67_map_regn(b) << 18) | //base reg A0 - (0 << 13) | //cst5 - (1 << 9) | //mode 1 = pos cst offset - (0 << 8) | //r (LDDW bit 0) - (C67_map_regs(b) << 7) | //y D1/D2 base reg side - (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(a) << 1) | //side of src - (0 << 0)); //parallel - } else if (strstr(s, "STH.D *") == s) { - C67_g((C67_map_regn(a) << 23) | //src - (C67_map_regn(b) << 18) | //base reg A0 - (0 << 13) | //cst5 - (1 << 9) | //mode 1 = pos cst offset - (0 << 8) | //r (LDDW bit 0) - (C67_map_regs(b) << 7) | //y D1/D2 base reg side - (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(a) << 1) | //side of src - (0 << 0)); //parallel - } else if (strstr(s, "STB.D *") == s) { - C67_g((C67_map_regn(a) << 23) | //src - (C67_map_regn(b) << 18) | //base reg A0 - (0 << 13) | //cst5 - (1 << 9) | //mode 1 = pos cst offset - (0 << 8) | //r (LDDW bit 0) - (C67_map_regs(b) << 7) | //y D1/D2 base reg side - (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(a) << 1) | //side of src - (0 << 0)); //parallel - } else if (strstr(s, "STW.D +*") == s) { - ALWAYS_ASSERT(c < 32); - C67_g((C67_map_regn(a) << 23) | //src - (C67_map_regn(b) << 18) | //base reg A0 - (c << 13) | //cst5 - (1 << 9) | //mode 1 = pos cst offset - (0 << 8) | //r (LDDW bit 0) - (C67_map_regs(b) << 7) | //y D1/D2 base reg side - (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(a) << 1) | //side of src - (0 << 0)); //parallel - } else if (strstr(s, "LDW.D SP PRE INC") == s) { - C67_g((C67_map_regn(a) << 23) | //dst - (15 << 18) | //base reg B15 - (2 << 13) | //ucst5 (must keep 8 byte boundary) - (9 << 9) | //mode 9 = pre inc ucst5 - (0 << 8) | //r (LDDW bit 0) - (1 << 7) | //y D1/D2 B side - (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(a) << 1) | //side of dst - (0 << 0)); //parallel - } else if (strstr(s, "LDDW.D SP PRE INC") == s) { - C67_g((C67_map_regn(a) << 23) | //dst - (15 << 18) | //base reg B15 - (1 << 13) | //ucst5 (must keep 8 byte boundary) - (9 << 9) | //mode 9 = pre inc ucst5 - (1 << 8) | //r (LDDW bit 1) - (1 << 7) | //y D1/D2 B side - (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(a) << 1) | //side of dst - (0 << 0)); //parallel - } else if (strstr(s, "LDW.D *+SP[A0]") == s) { - C67_g((C67_map_regn(a) << 23) | //dst - (15 << 18) | //base reg A15 - (0 << 13) | //offset reg A0 - (5 << 9) | //mode 5 = pos offset, base reg + off reg - (0 << 8) | //r (LDDW bit 0) - (0 << 7) | //y D1/D2 A side - (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(a) << 1) | //side of dst - (0 << 0)); //parallel - } else if (strstr(s, "LDDW.D *+SP[A0]") == s) { - C67_g((C67_map_regn(a) << 23) | //dst - (15 << 18) | //base reg A15 - (0 << 13) | //offset reg A0 - (5 << 9) | //mode 5 = pos offset, base reg + off reg - (1 << 8) | //r (LDDW bit 1) - (0 << 7) | //y D1/D2 A side - (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(a) << 1) | //side of dst - (0 << 0)); //parallel - } else if (strstr(s, "LDH.D *+SP[A0]") == s) { - C67_g((C67_map_regn(a) << 23) | //dst - (15 << 18) | //base reg A15 - (0 << 13) | //offset reg A0 - (5 << 9) | //mode 5 = pos offset, base reg + off reg - (0 << 8) | //r (LDDW bit 0) - (0 << 7) | //y D1/D2 A side - (4 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(a) << 1) | //side of dst - (0 << 0)); //parallel - } else if (strstr(s, "LDB.D *+SP[A0]") == s) { - C67_g((C67_map_regn(a) << 23) | //dst - (15 << 18) | //base reg A15 - (0 << 13) | //offset reg A0 - (5 << 9) | //mode 5 = pos offset, base reg + off reg - (0 << 8) | //r (LDDW bit 0) - (0 << 7) | //y D1/D2 A side - (2 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(a) << 1) | //side of dst - (0 << 0)); //parallel - } else if (strstr(s, "LDHU.D *+SP[A0]") == s) { - C67_g((C67_map_regn(a) << 23) | //dst - (15 << 18) | //base reg A15 - (0 << 13) | //offset reg A0 - (5 << 9) | //mode 5 = pos offset, base reg + off reg - (0 << 8) | //r (LDDW bit 0) - (0 << 7) | //y D1/D2 A side - (0 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(a) << 1) | //side of dst - (0 << 0)); //parallel - } else if (strstr(s, "LDBU.D *+SP[A0]") == s) { - C67_g((C67_map_regn(a) << 23) | //dst - (15 << 18) | //base reg A15 - (0 << 13) | //offset reg A0 - (5 << 9) | //mode 5 = pos offset, base reg + off reg - (0 << 8) | //r (LDDW bit 0) - (0 << 7) | //y D1/D2 A side - (1 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(a) << 1) | //side of dst - (0 << 0)); //parallel - } else if (strstr(s, "LDW.D *") == s) { - C67_g((C67_map_regn(b) << 23) | //dst - (C67_map_regn(a) << 18) | //base reg A15 - (0 << 13) | //cst5 - (1 << 9) | //mode 1 = pos cst offset - (0 << 8) | //r (LDDW bit 0) - (C67_map_regs(a) << 7) | //y D1/D2 src side - (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(b) << 1) | //side of dst - (0 << 0)); //parallel - } else if (strstr(s, "LDDW.D *") == s) { - C67_g((C67_map_regn(b) << 23) | //dst - (C67_map_regn(a) << 18) | //base reg A15 - (0 << 13) | //cst5 - (1 << 9) | //mode 1 = pos cst offset - (1 << 8) | //r (LDDW bit 1) - (C67_map_regs(a) << 7) | //y D1/D2 src side - (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(b) << 1) | //side of dst - (0 << 0)); //parallel - } else if (strstr(s, "LDH.D *") == s) { - C67_g((C67_map_regn(b) << 23) | //dst - (C67_map_regn(a) << 18) | //base reg A15 - (0 << 13) | //cst5 - (1 << 9) | //mode 1 = pos cst offset - (0 << 8) | //r (LDDW bit 0) - (C67_map_regs(a) << 7) | //y D1/D2 src side - (4 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(b) << 1) | //side of dst - (0 << 0)); //parallel - } else if (strstr(s, "LDB.D *") == s) { - C67_g((C67_map_regn(b) << 23) | //dst - (C67_map_regn(a) << 18) | //base reg A15 - (0 << 13) | //cst5 - (1 << 9) | //mode 1 = pos cst offset - (0 << 8) | //r (LDDW bit 0) - (C67_map_regs(a) << 7) | //y D1/D2 src side - (2 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(b) << 1) | //side of dst - (0 << 0)); //parallel - } else if (strstr(s, "LDHU.D *") == s) { - C67_g((C67_map_regn(b) << 23) | //dst - (C67_map_regn(a) << 18) | //base reg A15 - (0 << 13) | //cst5 - (1 << 9) | //mode 1 = pos cst offset - (0 << 8) | //r (LDDW bit 0) - (C67_map_regs(a) << 7) | //y D1/D2 src side - (0 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(b) << 1) | //side of dst - (0 << 0)); //parallel - } else if (strstr(s, "LDBU.D *") == s) { - C67_g((C67_map_regn(b) << 23) | //dst - (C67_map_regn(a) << 18) | //base reg A15 - (0 << 13) | //cst5 - (1 << 9) | //mode 1 = pos cst offset - (0 << 8) | //r (LDDW bit 0) - (C67_map_regs(a) << 7) | //y D1/D2 src side - (1 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(b) << 1) | //side of dst - (0 << 0)); //parallel - } else if (strstr(s, "LDW.D +*") == s) { - C67_g((C67_map_regn(b) << 23) | //dst - (C67_map_regn(a) << 18) | //base reg A15 - (1 << 13) | //cst5 - (1 << 9) | //mode 1 = pos cst offset - (0 << 8) | //r (LDDW bit 0) - (C67_map_regs(a) << 7) | //y D1/D2 src side - (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU - (1 << 2) | //opcode - (C67_map_regs(b) << 1) | //side of dst - (0 << 0)); //parallel - } else if (strstr(s, "CMPLTSP") == s) { - xpath = C67_map_regs(a) ^ C67_map_regs(b); - ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); - - C67_g((C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x use cross path for src2 - (0x3a << 6) | //opcode - (0x8 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side for reg c - (0 << 0)); //parallel - } else if (strstr(s, "CMPGTSP") == s) { - xpath = C67_map_regs(a) ^ C67_map_regs(b); - ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); - - C67_g((C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x use cross path for src2 - (0x39 << 6) | //opcode - (0x8 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side for reg c - (0 << 0)); //parallel - } else if (strstr(s, "CMPEQSP") == s) { - xpath = C67_map_regs(a) ^ C67_map_regs(b); - ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); - - C67_g((C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x use cross path for src2 - (0x38 << 6) | //opcode - (0x8 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side for reg c - (0 << 0)); //parallel - } - - else if (strstr(s, "CMPLTDP") == s) { - xpath = C67_map_regs(a) ^ C67_map_regs(b); - ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); - - C67_g((C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x use cross path for src2 - (0x2a << 6) | //opcode - (0x8 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side for reg c - (0 << 0)); //parallel - } else if (strstr(s, "CMPGTDP") == s) { - xpath = C67_map_regs(a) ^ C67_map_regs(b); - ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); - - C67_g((C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x use cross path for src2 - (0x29 << 6) | //opcode - (0x8 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side for reg c - (0 << 0)); //parallel - } else if (strstr(s, "CMPEQDP") == s) { - xpath = C67_map_regs(a) ^ C67_map_regs(b); - ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); - - C67_g((C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x use cross path for src2 - (0x28 << 6) | //opcode - (0x8 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side for reg c - (0 << 0)); //parallel - } else if (strstr(s, "CMPLT") == s) { - xpath = C67_map_regs(a) ^ C67_map_regs(b); - ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); - - C67_g((C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x use cross path for src2 - (0x57 << 5) | //opcode - (0x6 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side for reg c - (0 << 0)); //parallel - } else if (strstr(s, "CMPGT") == s) { - xpath = C67_map_regs(a) ^ C67_map_regs(b); - ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); - - C67_g((C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x use cross path for src2 - (0x47 << 5) | //opcode - (0x6 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side for reg c - (0 << 0)); //parallel - } else if (strstr(s, "CMPEQ") == s) { - xpath = C67_map_regs(a) ^ C67_map_regs(b); - ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); - - C67_g((C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x use cross path for src2 - (0x53 << 5) | //opcode - (0x6 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side for reg c - (0 << 0)); //parallel - } else if (strstr(s, "CMPLTU") == s) { - xpath = C67_map_regs(a) ^ C67_map_regs(b); - ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); - - C67_g((C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x use cross path for src2 - (0x5f << 5) | //opcode - (0x6 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side for reg c - (0 << 0)); //parallel - } else if (strstr(s, "CMPGTU") == s) { - xpath = C67_map_regs(a) ^ C67_map_regs(b); - ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); - - C67_g((C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x use cross path for src2 - (0x4f << 5) | //opcode - (0x6 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side for reg c - (0 << 0)); //parallel - } else if (strstr(s, "B DISP") == s) { - C67_g((0 << 29) | //creg - (0 << 28) | //z - (a << 7) | //cnst - (0x4 << 2) | //opcode fixed - (0 << 1) | //S0/S1 - (0 << 0)); //parallel - } else if (strstr(s, "B.") == s) { - xpath = C67_map_regs(c) ^ 1; - - C67_g((C67_map_regc(b) << 29) | //creg - (a << 28) | //inv - (0 << 23) | //dst - (C67_map_regn(c) << 18) | //src2 - (0 << 13) | // - (xpath << 12) | //x cross path if !B side - (0xd << 6) | //opcode - (0x8 << 2) | //opcode fixed - (1 << 1) | //must be S2 - (0 << 0)); //parallel - } else if (strstr(s, "MV.L") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 - (0 << 13) | //src1 (cst5) - (xpath << 12) | //x cross path if opposite sides - (0x2 << 5) | //opcode - (0x6 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "SPTRUNC.L") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 - (0 << 13) | //src1 NA - (xpath << 12) | //x cross path if opposite sides - (0xb << 5) | //opcode - (0x6 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "DPTRUNC.L") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - ((C67_map_regn(b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason - (0 << 13) | //src1 NA - (xpath << 12) | //x cross path if opposite sides - (0x1 << 5) | //opcode - (0x6 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "INTSP.L") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 - (0 << 13) | //src1 NA - (xpath << 12) | //x cross path if opposite sides - (0x4a << 5) | //opcode - (0x6 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "INTSPU.L") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 - (0 << 13) | //src1 NA - (xpath << 12) | //x cross path if opposite sides - (0x49 << 5) | //opcode - (0x6 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "INTDP.L") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 - (0 << 13) | //src1 NA - (xpath << 12) | //x cross path if opposite sides - (0x39 << 5) | //opcode - (0x6 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "INTDPU.L") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - ((C67_map_regn(b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason - (0 << 13) | //src1 NA - (xpath << 12) | //x cross path if opposite sides - (0x3b << 5) | //opcode - (0x6 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "SPDP.L") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 - (0 << 13) | //src1 NA - (xpath << 12) | //x cross path if opposite sides - (0x2 << 6) | //opcode - (0x8 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "DPSP.L") == s) { - ALWAYS_ASSERT(C67_map_regs(b) == C67_map_regs(c)); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - ((C67_map_regn(b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason - (0 << 13) | //src1 NA - (0 << 12) | //x cross path if opposite sides - (0x9 << 5) | //opcode - (0x6 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "ADD.L") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 (possible x path) - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x cross path if opposite sides - (0x3 << 5) | //opcode - (0x6 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "SUB.L") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 (possible x path) - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x cross path if opposite sides - (0x7 << 5) | //opcode - (0x6 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "OR.L") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 (possible x path) - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x cross path if opposite sides - (0x7f << 5) | //opcode - (0x6 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "AND.L") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 (possible x path) - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x cross path if opposite sides - (0x7b << 5) | //opcode - (0x6 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "XOR.L") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 (possible x path) - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x cross path if opposite sides - (0x6f << 5) | //opcode - (0x6 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "ADDSP.L") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 (possible x path) - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x cross path if opposite sides - (0x10 << 5) | //opcode - (0x6 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "ADDDP.L") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 (possible x path) - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x cross path if opposite sides - (0x18 << 5) | //opcode - (0x6 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "SUBSP.L") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 (possible x path) - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x cross path if opposite sides - (0x11 << 5) | //opcode - (0x6 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "SUBDP.L") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 (possible x path) - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x cross path if opposite sides - (0x19 << 5) | //opcode - (0x6 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "MPYSP.M") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 (possible x path) - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x cross path if opposite sides - (0x1c << 7) | //opcode - (0x0 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "MPYDP.M") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 (possible x path) - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x cross path if opposite sides - (0x0e << 7) | //opcode - (0x0 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "MPYI.M") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 - (C67_map_regn(a) << 13) | //src1 (cst5) - (xpath << 12) | //x cross path if opposite sides - (0x4 << 7) | //opcode - (0x0 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "SHR.S") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x cross path if opposite sides - (0x37 << 6) | //opcode - (0x8 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "SHRU.S") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x cross path if opposite sides - (0x27 << 6) | //opcode - (0x8 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "SHL.S") == s) { - xpath = C67_map_regs(b) ^ C67_map_regs(c); - - ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(c) << 23) | //dst - (C67_map_regn(b) << 18) | //src2 - (C67_map_regn(a) << 13) | //src1 - (xpath << 12) | //x cross path if opposite sides - (0x33 << 6) | //opcode - (0x8 << 2) | //opcode fixed - (C67_map_regs(c) << 1) | //side of dest - (0 << 0)); //parallel - } else if (strstr(s, "||ADDK") == s) { - xpath = 0; // no xpath required just use the side of the src/dst - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(b) << 23) | //dst - (a << 07) | //scst16 - (0x14 << 2) | //opcode fixed - (C67_map_regs(b) << 1) | //side of dst - (1 << 0)); //parallel - } else if (strstr(s, "ADDK") == s) { - xpath = 0; // no xpath required just use the side of the src/dst - - C67_g((0 << 29) | //creg - (0 << 28) | //inv - (C67_map_regn(b) << 23) | //dst - (a << 07) | //scst16 - (0x14 << 2) | //opcode fixed - (C67_map_regs(b) << 1) | //side of dst - (0 << 0)); //parallel - } else if (strstr(s, "NOP") == s) { - C67_g(((a - 1) << 13) | //no of cycles - (0 << 0)); //parallel - } else - ALWAYS_ASSERT(FALSE); - -#ifdef ASSEMBLY_LISTING_C67 - fprintf(f, " %s %d %d %d\n", s, a, b, c); -#endif - -} - -//r=reg to load, fr=from reg, symbol for relocation, constant - -void C67_MVKL(int r, int fc) -{ - C67_asm("MVKL.", fc, r, 0); -} - -void C67_MVKH(int r, int fc) -{ - C67_asm("MVKH.", fc, r, 0); -} - -void C67_STB_SP_A0(int r) -{ - C67_asm("STB.D *+SP[A0]", r, 0, 0); // STB r,*+SP[A0] -} - -void C67_STH_SP_A0(int r) -{ - C67_asm("STH.D *+SP[A0]", r, 0, 0); // STH r,*+SP[A0] -} - -void C67_STW_SP_A0(int r) -{ - C67_asm("STW.D *+SP[A0]", r, 0, 0); // STW r,*+SP[A0] -} - -void C67_STB_PTR(int r, int r2) -{ - C67_asm("STB.D *", r, r2, 0); // STB r, *r2 -} - -void C67_STH_PTR(int r, int r2) -{ - C67_asm("STH.D *", r, r2, 0); // STH r, *r2 -} - -void C67_STW_PTR(int r, int r2) -{ - C67_asm("STW.D *", r, r2, 0); // STW r, *r2 -} - -void C67_STW_PTR_PRE_INC(int r, int r2, int n) -{ - C67_asm("STW.D +*", r, r2, n); // STW r, *+r2 -} - -void C67_PUSH(int r) -{ - C67_asm("STW.D SP POST DEC", r, 0, 0); // STW r,*SP-- -} - -void C67_LDW_SP_A0(int r) -{ - C67_asm("LDW.D *+SP[A0]", r, 0, 0); // LDW *+SP[A0],r -} - -void C67_LDDW_SP_A0(int r) -{ - C67_asm("LDDW.D *+SP[A0]", r, 0, 0); // LDDW *+SP[A0],r -} - -void C67_LDH_SP_A0(int r) -{ - C67_asm("LDH.D *+SP[A0]", r, 0, 0); // LDH *+SP[A0],r -} - -void C67_LDB_SP_A0(int r) -{ - C67_asm("LDB.D *+SP[A0]", r, 0, 0); // LDB *+SP[A0],r -} - -void C67_LDHU_SP_A0(int r) -{ - C67_asm("LDHU.D *+SP[A0]", r, 0, 0); // LDHU *+SP[A0],r -} - -void C67_LDBU_SP_A0(int r) -{ - C67_asm("LDBU.D *+SP[A0]", r, 0, 0); // LDBU *+SP[A0],r -} - -void C67_LDW_PTR(int r, int r2) -{ - C67_asm("LDW.D *", r, r2, 0); // LDW *r,r2 -} - -void C67_LDDW_PTR(int r, int r2) -{ - C67_asm("LDDW.D *", r, r2, 0); // LDDW *r,r2 -} - -void C67_LDH_PTR(int r, int r2) -{ - C67_asm("LDH.D *", r, r2, 0); // LDH *r,r2 -} - -void C67_LDB_PTR(int r, int r2) -{ - C67_asm("LDB.D *", r, r2, 0); // LDB *r,r2 -} - -void C67_LDHU_PTR(int r, int r2) -{ - C67_asm("LDHU.D *", r, r2, 0); // LDHU *r,r2 -} - -void C67_LDBU_PTR(int r, int r2) -{ - C67_asm("LDBU.D *", r, r2, 0); // LDBU *r,r2 -} - -void C67_LDW_PTR_PRE_INC(int r, int r2) -{ - C67_asm("LDW.D +*", r, r2, 0); // LDW *+r,r2 -} - -void C67_POP(int r) -{ - C67_asm("LDW.D SP PRE INC", r, 0, 0); // LDW *++SP,r -} - -void C67_POP_DW(int r) -{ - C67_asm("LDDW.D SP PRE INC", r, 0, 0); // LDDW *++SP,r -} - -void C67_CMPLT(int s1, int s2, int dst) -{ - C67_asm("CMPLT.L1", s1, s2, dst); -} - -void C67_CMPGT(int s1, int s2, int dst) -{ - C67_asm("CMPGT.L1", s1, s2, dst); -} - -void C67_CMPEQ(int s1, int s2, int dst) -{ - C67_asm("CMPEQ.L1", s1, s2, dst); -} - -void C67_CMPLTU(int s1, int s2, int dst) -{ - C67_asm("CMPLTU.L1", s1, s2, dst); -} - -void C67_CMPGTU(int s1, int s2, int dst) -{ - C67_asm("CMPGTU.L1", s1, s2, dst); -} - - -void C67_CMPLTSP(int s1, int s2, int dst) -{ - C67_asm("CMPLTSP.S1", s1, s2, dst); -} - -void C67_CMPGTSP(int s1, int s2, int dst) -{ - C67_asm("CMPGTSP.S1", s1, s2, dst); -} - -void C67_CMPEQSP(int s1, int s2, int dst) -{ - C67_asm("CMPEQSP.S1", s1, s2, dst); -} - -void C67_CMPLTDP(int s1, int s2, int dst) -{ - C67_asm("CMPLTDP.S1", s1, s2, dst); -} - -void C67_CMPGTDP(int s1, int s2, int dst) -{ - C67_asm("CMPGTDP.S1", s1, s2, dst); -} - -void C67_CMPEQDP(int s1, int s2, int dst) -{ - C67_asm("CMPEQDP.S1", s1, s2, dst); -} - - -void C67_IREG_B_REG(int inv, int r1, int r2) // [!R] B r2 -{ - C67_asm("B.S2", inv, r1, r2); -} - - -// call with how many 32 bit words to skip -// (0 would branch to the branch instruction) - -void C67_B_DISP(int disp) // B +2 Branch with constant displacement -{ - // Branch point is relative to the 8 word fetch packet - // - // we will assume the text section always starts on an 8 word (32 byte boundary) - // - // so add in how many words into the fetch packet the branch is - - - C67_asm("B DISP", disp + ((ind & 31) >> 2), 0, 0); -} - -void C67_NOP(int n) -{ - C67_asm("NOP", n, 0, 0); -} - -void C67_ADDK(int n, int r) -{ - ALWAYS_ASSERT(abs(n) < 32767); - - C67_asm("ADDK", n, r, 0); -} - -void C67_ADDK_PARALLEL(int n, int r) -{ - ALWAYS_ASSERT(abs(n) < 32767); - - C67_asm("||ADDK", n, r, 0); -} - -void C67_Adjust_ADDK(int *inst, int n) -{ - ALWAYS_ASSERT(abs(n) < 32767); - - *inst = (*inst & (~(0xffff << 7))) | ((n & 0xffff) << 7); -} - -void C67_MV(int r, int v) -{ - C67_asm("MV.L", 0, r, v); -} - - -void C67_DPTRUNC(int r, int v) -{ - C67_asm("DPTRUNC.L", 0, r, v); -} - -void C67_SPTRUNC(int r, int v) -{ - C67_asm("SPTRUNC.L", 0, r, v); -} - -void C67_INTSP(int r, int v) -{ - C67_asm("INTSP.L", 0, r, v); -} - -void C67_INTDP(int r, int v) -{ - C67_asm("INTDP.L", 0, r, v); -} - -void C67_INTSPU(int r, int v) -{ - C67_asm("INTSPU.L", 0, r, v); -} - -void C67_INTDPU(int r, int v) -{ - C67_asm("INTDPU.L", 0, r, v); -} - -void C67_SPDP(int r, int v) -{ - C67_asm("SPDP.L", 0, r, v); -} - -void C67_DPSP(int r, int v) // note regs must be on the same side -{ - C67_asm("DPSP.L", 0, r, v); -} - -void C67_ADD(int r, int v) -{ - C67_asm("ADD.L", v, r, v); -} - -void C67_SUB(int r, int v) -{ - C67_asm("SUB.L", v, r, v); -} - -void C67_AND(int r, int v) -{ - C67_asm("AND.L", v, r, v); -} - -void C67_OR(int r, int v) -{ - C67_asm("OR.L", v, r, v); -} - -void C67_XOR(int r, int v) -{ - C67_asm("XOR.L", v, r, v); -} - -void C67_ADDSP(int r, int v) -{ - C67_asm("ADDSP.L", v, r, v); -} - -void C67_SUBSP(int r, int v) -{ - C67_asm("SUBSP.L", v, r, v); -} - -void C67_MPYSP(int r, int v) -{ - C67_asm("MPYSP.M", v, r, v); -} - -void C67_ADDDP(int r, int v) -{ - C67_asm("ADDDP.L", v, r, v); -} - -void C67_SUBDP(int r, int v) -{ - C67_asm("SUBDP.L", v, r, v); -} - -void C67_MPYDP(int r, int v) -{ - C67_asm("MPYDP.M", v, r, v); -} - -void C67_MPYI(int r, int v) -{ - C67_asm("MPYI.M", v, r, v); -} - -void C67_SHL(int r, int v) -{ - C67_asm("SHL.S", r, v, v); -} - -void C67_SHRU(int r, int v) -{ - C67_asm("SHRU.S", r, v, v); -} - -void C67_SHR(int r, int v) -{ - C67_asm("SHR.S", r, v, v); -} - - - -/* load 'r' from value 'sv' */ -void load(int r, SValue * sv) -{ - int v, t, ft, fc, fr, size = 0, element; - BOOL Unsigned = FALSE; - SValue v1; - - fr = sv->r; - ft = sv->type.t; - fc = sv->c.i; - - v = fr & VT_VALMASK; - if (fr & VT_LVAL) { - if (v == VT_LLOCAL) { - v1.type.t = VT_INT; - v1.r = VT_LOCAL | VT_LVAL; - v1.c.i = fc; - load(r, &v1); - fr = r; - } else if ((ft & VT_BTYPE) == VT_LDOUBLE) { - tcc_error("long double not supported"); - } else if ((ft & VT_TYPE) == VT_BYTE) { - size = 1; - } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) { - size = 1; - Unsigned = TRUE; - } else if ((ft & VT_TYPE) == VT_SHORT) { - size = 2; - } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) { - size = 2; - Unsigned = TRUE; - } else if ((ft & VT_BTYPE) == VT_DOUBLE) { - size = 8; - } else { - size = 4; - } - - // check if fc is a positive reference on the stack, - // if it is tcc is referencing what it thinks is a parameter - // on the stack, so check if it is really in a register. - - - if (v == VT_LOCAL && fc > 0) { - int stack_pos = 8; - - for (t = 0; t < NoCallArgsPassedOnStack; t++) { - if (fc == stack_pos) - break; - - stack_pos += TranslateStackToReg[t]; - } - - // param has been pushed on stack, get it like a local var - - fc = ParamLocOnStack[t] - 8; - } - - if ((fr & VT_VALMASK) < VT_CONST) // check for pure indirect - { - if (size == 1) { - if (Unsigned) - C67_LDBU_PTR(v, r); // LDBU *v,r - else - C67_LDB_PTR(v, r); // LDB *v,r - } else if (size == 2) { - if (Unsigned) - C67_LDHU_PTR(v, r); // LDHU *v,r - else - C67_LDH_PTR(v, r); // LDH *v,r - } else if (size == 4) { - C67_LDW_PTR(v, r); // LDW *v,r - } else if (size == 8) { - C67_LDDW_PTR(v, r); // LDDW *v,r - } - - C67_NOP(4); // NOP 4 - return; - } else if (fr & VT_SYM) { - greloc(cur_text_section, sv->sym, ind, R_C60LO16); // rem the inst need to be patched - greloc(cur_text_section, sv->sym, ind + 4, R_C60HI16); - - - C67_MVKL(C67_A0, fc); //r=reg to load, constant - C67_MVKH(C67_A0, fc); //r=reg to load, constant - - - if (size == 1) { - if (Unsigned) - C67_LDBU_PTR(C67_A0, r); // LDBU *A0,r - else - C67_LDB_PTR(C67_A0, r); // LDB *A0,r - } else if (size == 2) { - if (Unsigned) - C67_LDHU_PTR(C67_A0, r); // LDHU *A0,r - else - C67_LDH_PTR(C67_A0, r); // LDH *A0,r - } else if (size == 4) { - C67_LDW_PTR(C67_A0, r); // LDW *A0,r - } else if (size == 8) { - C67_LDDW_PTR(C67_A0, r); // LDDW *A0,r - } - - C67_NOP(4); // NOP 4 - return; - } else { - element = size; - - // divide offset in bytes to create element index - C67_MVKL(C67_A0, (fc / element) + 8 / element); //r=reg to load, constant - C67_MVKH(C67_A0, (fc / element) + 8 / element); //r=reg to load, constant - - if (size == 1) { - if (Unsigned) - C67_LDBU_SP_A0(r); // LDBU r, SP[A0] - else - C67_LDB_SP_A0(r); // LDB r, SP[A0] - } else if (size == 2) { - if (Unsigned) - C67_LDHU_SP_A0(r); // LDHU r, SP[A0] - else - C67_LDH_SP_A0(r); // LDH r, SP[A0] - } else if (size == 4) { - C67_LDW_SP_A0(r); // LDW r, SP[A0] - } else if (size == 8) { - C67_LDDW_SP_A0(r); // LDDW r, SP[A0] - } - - - C67_NOP(4); // NOP 4 - return; - } - } else { - if (v == VT_CONST) { - if (fr & VT_SYM) { - greloc(cur_text_section, sv->sym, ind, R_C60LO16); // rem the inst need to be patched - greloc(cur_text_section, sv->sym, ind + 4, R_C60HI16); - } - C67_MVKL(r, fc); //r=reg to load, constant - C67_MVKH(r, fc); //r=reg to load, constant - } else if (v == VT_LOCAL) { - C67_MVKL(r, fc + 8); //r=reg to load, constant C67 stack points to next free - C67_MVKH(r, fc + 8); //r=reg to load, constant - C67_ADD(C67_FP, r); // MV v,r v -> r - } else if (v == VT_CMP) { - C67_MV(C67_compare_reg, r); // MV v,r v -> r - } else if (v == VT_JMP || v == VT_JMPI) { - t = v & 1; - C67_B_DISP(4); // Branch with constant displacement, skip over this branch, load, nop, load - C67_MVKL(r, t); // r=reg to load, 0 or 1 (do this while branching) - C67_NOP(4); // NOP 4 - gsym(fc); // modifies other branches to branch here - C67_MVKL(r, t ^ 1); // r=reg to load, 0 or 1 - } else if (v != r) { - C67_MV(v, r); // MV v,r v -> r - - if ((ft & VT_BTYPE) == VT_DOUBLE) - C67_MV(v + 1, r + 1); // MV v,r v -> r - } - } -} - - -/* store register 'r' in lvalue 'v' */ -void store(int r, SValue * v) -{ - int fr, bt, ft, fc, size, t, element; - - ft = v->type.t; - fc = v->c.i; - fr = v->r & VT_VALMASK; - bt = ft & VT_BTYPE; - /* XXX: incorrect if float reg to reg */ - - if (bt == VT_LDOUBLE) { - tcc_error("long double not supported"); - } else { - if (bt == VT_SHORT) - size = 2; - else if (bt == VT_BYTE) - size = 1; - else if (bt == VT_DOUBLE) - size = 8; - else - size = 4; - - if ((v->r & VT_VALMASK) == VT_CONST) { - /* constant memory reference */ - - if (v->r & VT_SYM) { - greloc(cur_text_section, v->sym, ind, R_C60LO16); // rem the inst need to be patched - greloc(cur_text_section, v->sym, ind + 4, R_C60HI16); - } - C67_MVKL(C67_A0, fc); //r=reg to load, constant - C67_MVKH(C67_A0, fc); //r=reg to load, constant - - if (size == 1) - C67_STB_PTR(r, C67_A0); // STB r, *A0 - else if (size == 2) - C67_STH_PTR(r, C67_A0); // STH r, *A0 - else if (size == 4 || size == 8) - C67_STW_PTR(r, C67_A0); // STW r, *A0 - - if (size == 8) - C67_STW_PTR_PRE_INC(r + 1, C67_A0, 1); // STW r, *+A0[1] - } else if ((v->r & VT_VALMASK) == VT_LOCAL) { - // check case of storing to passed argument that - // tcc thinks is on the stack but for C67 is - // passed as a reg. However it may have been - // saved to the stack, if that reg was required - // for a call to a child function - - if (fc > 0) // argument ?? - { - // walk through sizes and figure which param - - int stack_pos = 8; - - for (t = 0; t < NoCallArgsPassedOnStack; t++) { - if (fc == stack_pos) - break; - - stack_pos += TranslateStackToReg[t]; - } - - // param has been pushed on stack, get it like a local var - fc = ParamLocOnStack[t] - 8; - } - - if (size == 8) - element = 4; - else - element = size; - - // divide offset in bytes to create word index - C67_MVKL(C67_A0, (fc / element) + 8 / element); //r=reg to load, constant - C67_MVKH(C67_A0, (fc / element) + 8 / element); //r=reg to load, constant - - - - if (size == 1) - C67_STB_SP_A0(r); // STB r, SP[A0] - else if (size == 2) - C67_STH_SP_A0(r); // STH r, SP[A0] - else if (size == 4 || size == 8) - C67_STW_SP_A0(r); // STW r, SP[A0] - - if (size == 8) { - C67_ADDK(1, C67_A0); // ADDK 1,A0 - C67_STW_SP_A0(r + 1); // STW r, SP[A0] - } - } else { - if (size == 1) - C67_STB_PTR(r, fr); // STB r, *fr - else if (size == 2) - C67_STH_PTR(r, fr); // STH r, *fr - else if (size == 4 || size == 8) - C67_STW_PTR(r, fr); // STW r, *fr - - if (size == 8) { - C67_STW_PTR_PRE_INC(r + 1, fr, 1); // STW r, *+fr[1] - } - } - } -} - -/* 'is_jmp' is '1' if it is a jump */ -static void gcall_or_jmp(int is_jmp) -{ - int r; - Sym *sym; - - if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { - /* constant case */ - if (vtop->r & VT_SYM) { - /* relocation case */ - - // get add into A0, then start the jump B3 - - greloc(cur_text_section, vtop->sym, ind, R_C60LO16); // rem the inst need to be patched - greloc(cur_text_section, vtop->sym, ind + 4, R_C60HI16); - - C67_MVKL(C67_A0, 0); //r=reg to load, constant - C67_MVKH(C67_A0, 0); //r=reg to load, constant - C67_IREG_B_REG(0, C67_CREG_ZERO, C67_A0); // B.S2x A0 - - if (is_jmp) { - C67_NOP(5); // simple jump, just put NOP - } else { - // Call, must load return address into B3 during delay slots - - sym = get_sym_ref(&char_pointer_type, cur_text_section, ind + 12, 0); // symbol for return address - greloc(cur_text_section, sym, ind, R_C60LO16); // rem the inst need to be patched - greloc(cur_text_section, sym, ind + 4, R_C60HI16); - C67_MVKL(C67_B3, 0); //r=reg to load, constant - C67_MVKH(C67_B3, 0); //r=reg to load, constant - C67_NOP(3); // put remaining NOPs - } - } else { - /* put an empty PC32 relocation */ - ALWAYS_ASSERT(FALSE); - } - } else { - /* otherwise, indirect call */ - r = gv(RC_INT); - C67_IREG_B_REG(0, C67_CREG_ZERO, r); // B.S2x r - - if (is_jmp) { - C67_NOP(5); // simple jump, just put NOP - } else { - // Call, must load return address into B3 during delay slots - - sym = get_sym_ref(&char_pointer_type, cur_text_section, ind + 12, 0); // symbol for return address - greloc(cur_text_section, sym, ind, R_C60LO16); // rem the inst need to be patched - greloc(cur_text_section, sym, ind + 4, R_C60HI16); - C67_MVKL(C67_B3, 0); //r=reg to load, constant - C67_MVKH(C67_B3, 0); //r=reg to load, constant - C67_NOP(3); // put remaining NOPs - } - } -} - -/* Return the number of registers needed to return the struct, or 0 if - returning via struct pointer. */ -ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize) { - *ret_align = 1; // Never have to re-align return values for x86-64 - return 0; -} - -/* generate function call with address in (vtop->t, vtop->c) and free function - context. Stack entry is popped */ -void gfunc_call(int nb_args) -{ - int i, r, size = 0; - int args_sizes[NoCallArgsPassedOnStack]; - - if (nb_args > NoCallArgsPassedOnStack) { - tcc_error("more than 10 function params not currently supported"); - // handle more than 10, put some on the stack - } - - for (i = 0; i < nb_args; i++) { - if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { - ALWAYS_ASSERT(FALSE); - } else { - /* simple type (currently always same size) */ - /* XXX: implicit cast ? */ - - - if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { - tcc_error("long long not supported"); - } else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { - tcc_error("long double not supported"); - } else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) { - size = 8; - } else { - size = 4; - } - - // put the parameter into the corresponding reg (pair) - - r = gv(RC_C67_A4 << (2 * i)); - - // must put on stack because with 1 pass compiler , no way to tell - // if an up coming nested call might overwrite these regs - - C67_PUSH(r); - - if (size == 8) { - C67_STW_PTR_PRE_INC(r + 1, C67_SP, 3); // STW r, *+SP[3] (go back and put the other) - } - args_sizes[i] = size; - } - vtop--; - } - // POP all the params on the stack into registers for the - // immediate call (in reverse order) - - for (i = nb_args - 1; i >= 0; i--) { - - if (args_sizes[i] == 8) - C67_POP_DW(TREG_C67_A4 + i * 2); - else - C67_POP(TREG_C67_A4 + i * 2); - } - gcall_or_jmp(0); - vtop--; -} - - -// to be compatible with Code Composer for the C67 -// the first 10 parameters must be passed in registers -// (pairs for 64 bits) starting wit; A4:A5, then B4:B5 and -// ending with B12:B13. -// -// When a call is made, if the caller has its parameters -// in regs A4-B13 these must be saved before/as the call -// parameters are loaded and restored upon return (or if/when needed). - -/* generate function prolog of type 't' */ -void gfunc_prolog(CType * func_type) -{ - int addr, align, size, func_call, i; - Sym *sym; - CType *type; - - sym = func_type->ref; - func_call = sym->r; - addr = 8; - /* if the function returns a structure, then add an - implicit pointer parameter */ - func_vt = sym->type; - func_var = (sym->c == FUNC_ELLIPSIS); - if ((func_vt.t & VT_BTYPE) == VT_STRUCT) { - func_vc = addr; - addr += 4; - } - - NoOfCurFuncArgs = 0; - - /* define parameters */ - while ((sym = sym->next) != NULL) { - type = &sym->type; - sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | lvalue_type(type->t), addr); - size = type_size(type, &align); - size = (size + 3) & ~3; - - // keep track of size of arguments so - // we can translate where tcc thinks they - // are on the stack into the appropriate reg - - TranslateStackToReg[NoOfCurFuncArgs] = size; - NoOfCurFuncArgs++; - -#ifdef FUNC_STRUCT_PARAM_AS_PTR - /* structs are passed as pointer */ - if ((type->t & VT_BTYPE) == VT_STRUCT) { - size = 4; - } -#endif - addr += size; - } - func_ret_sub = 0; - /* pascal type call ? */ - if (func_call == FUNC_STDCALL) - func_ret_sub = addr - 8; - - C67_MV(C67_FP, C67_A0); // move FP -> A0 - C67_MV(C67_SP, C67_FP); // move SP -> FP - - // place all the args passed in regs onto the stack - - loc = 0; - for (i = 0; i < NoOfCurFuncArgs; i++) { - - ParamLocOnStack[i] = loc; // remember where the param is - loc += -8; - - C67_PUSH(TREG_C67_A4 + i * 2); - - if (TranslateStackToReg[i] == 8) { - C67_STW_PTR_PRE_INC(TREG_C67_A4 + i * 2 + 1, C67_SP, 3); // STW r, *+SP[1] (go back and put the other) - } - } - - TotalBytesPushedOnStack = -loc; - - func_sub_sp_offset = ind; // remember where we put the stack instruction - C67_ADDK(0, C67_SP); // ADDK.L2 loc,SP (just put zero temporarily) - - C67_PUSH(C67_A0); - C67_PUSH(C67_B3); -} - -/* generate function epilog */ -void gfunc_epilog(void) -{ - { - int local = (-loc + 7) & -8; // stack must stay aligned to 8 bytes for LDDW instr - C67_POP(C67_B3); - C67_NOP(4); // NOP wait for load - C67_IREG_B_REG(0, C67_CREG_ZERO, C67_B3); // B.S2 B3 - C67_POP(C67_FP); - C67_ADDK(local, C67_SP); // ADDK.L2 loc,SP - C67_Adjust_ADDK((int *) (cur_text_section->data + - func_sub_sp_offset), - -local + TotalBytesPushedOnStack); - C67_NOP(3); // NOP - } -} - -/* generate a jump to a label */ -int gjmp(int t) -{ - int ind1 = ind; - - C67_MVKL(C67_A0, t); //r=reg to load, constant - C67_MVKH(C67_A0, t); //r=reg to load, constant - C67_IREG_B_REG(0, C67_CREG_ZERO, C67_A0); // [!R] B.S2x A0 - C67_NOP(5); - return ind1; -} - -/* generate a jump to a fixed address */ -void gjmp_addr(int a) -{ - Sym *sym; - // I guess this routine is used for relative short - // local jumps, for now just handle it as the general - // case - - // define a label that will be relocated - - sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0); - greloc(cur_text_section, sym, ind, R_C60LO16); - greloc(cur_text_section, sym, ind + 4, R_C60HI16); - - gjmp(0); // place a zero there later the symbol will be added to it -} - -/* generate a test. set 'inv' to invert test. Stack entry is popped */ -int gtst(int inv, int t) -{ - int ind1, n; - int v, *p; - - v = vtop->r & VT_VALMASK; - if (v == VT_CMP) { - /* fast case : can jump directly since flags are set */ - // C67 uses B2 sort of as flags register - ind1 = ind; - C67_MVKL(C67_A0, t); //r=reg to load, constant - C67_MVKH(C67_A0, t); //r=reg to load, constant - - if (C67_compare_reg != TREG_EAX && // check if not already in a conditional test reg - C67_compare_reg != TREG_EDX && - C67_compare_reg != TREG_ST0 && C67_compare_reg != C67_B2) { - C67_MV(C67_compare_reg, C67_B2); - C67_compare_reg = C67_B2; - } - - C67_IREG_B_REG(C67_invert_test ^ inv, C67_compare_reg, C67_A0); // [!R] B.S2x A0 - C67_NOP(5); - t = ind1; //return where we need to patch - - } else if (v == VT_JMP || v == VT_JMPI) { - /* && or || optimization */ - if ((v & 1) == inv) { - /* insert vtop->c jump list in t */ - - // I guess the idea is to traverse to the - // null at the end of the list and store t - // there - - n = vtop->c.i; - while (n != 0) { - p = (int *) (cur_text_section->data + n); - - // extract 32 bit address from MVKH/MVKL - n = ((*p >> 7) & 0xffff); - n |= ((*(p + 1) >> 7) & 0xffff) << 16; - } - *p |= (t & 0xffff) << 7; - *(p + 1) |= ((t >> 16) & 0xffff) << 7; - t = vtop->c.i; - - } else { - t = gjmp(t); - gsym(vtop->c.i); - } - } - vtop--; - return t; -} - -/* generate an integer binary operation */ -void gen_opi(int op) -{ - int r, fr, opc, t; - - switch (op) { - case '+': - case TOK_ADDC1: /* add with carry generation */ - opc = 0; - gen_op8: - - -// C67 can't do const compares, must load into a reg -// so just go to gv2 directly - tktk - - - - if (op >= TOK_ULT && op <= TOK_GT) - gv2(RC_INT_BSIDE, RC_INT); // make sure r (src1) is on the B Side of CPU - else - gv2(RC_INT, RC_INT); - - r = vtop[-1].r; - fr = vtop[0].r; - - C67_compare_reg = C67_B2; - - - if (op == TOK_LT) { - C67_CMPLT(r, fr, C67_B2); - C67_invert_test = FALSE; - } else if (op == TOK_GE) { - C67_CMPLT(r, fr, C67_B2); - C67_invert_test = TRUE; - } else if (op == TOK_GT) { - C67_CMPGT(r, fr, C67_B2); - C67_invert_test = FALSE; - } else if (op == TOK_LE) { - C67_CMPGT(r, fr, C67_B2); - C67_invert_test = TRUE; - } else if (op == TOK_EQ) { - C67_CMPEQ(r, fr, C67_B2); - C67_invert_test = FALSE; - } else if (op == TOK_NE) { - C67_CMPEQ(r, fr, C67_B2); - C67_invert_test = TRUE; - } else if (op == TOK_ULT) { - C67_CMPLTU(r, fr, C67_B2); - C67_invert_test = FALSE; - } else if (op == TOK_UGE) { - C67_CMPLTU(r, fr, C67_B2); - C67_invert_test = TRUE; - } else if (op == TOK_UGT) { - C67_CMPGTU(r, fr, C67_B2); - C67_invert_test = FALSE; - } else if (op == TOK_ULE) { - C67_CMPGTU(r, fr, C67_B2); - C67_invert_test = TRUE; - } else if (op == '+') - C67_ADD(fr, r); // ADD r,fr,r - else if (op == '-') - C67_SUB(fr, r); // SUB r,fr,r - else if (op == '&') - C67_AND(fr, r); // AND r,fr,r - else if (op == '|') - C67_OR(fr, r); // OR r,fr,r - else if (op == '^') - C67_XOR(fr, r); // XOR r,fr,r - else - ALWAYS_ASSERT(FALSE); - - vtop--; - if (op >= TOK_ULT && op <= TOK_GT) { - vtop->r = VT_CMP; - vtop->c.i = op; - } - break; - case '-': - case TOK_SUBC1: /* sub with carry generation */ - opc = 5; - goto gen_op8; - case TOK_ADDC2: /* add with carry use */ - opc = 2; - goto gen_op8; - case TOK_SUBC2: /* sub with carry use */ - opc = 3; - goto gen_op8; - case '&': - opc = 4; - goto gen_op8; - case '^': - opc = 6; - goto gen_op8; - case '|': - opc = 1; - goto gen_op8; - case '*': - case TOK_UMULL: - gv2(RC_INT, RC_INT); - r = vtop[-1].r; - fr = vtop[0].r; - vtop--; - C67_MPYI(fr, r); // 32 bit bultiply fr,r,fr - C67_NOP(8); // NOP 8 for worst case - break; - case TOK_SHL: - gv2(RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst - r = vtop[-1].r; - fr = vtop[0].r; - vtop--; - C67_SHL(fr, r); // arithmetic/logical shift - break; - - case TOK_SHR: - gv2(RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst - r = vtop[-1].r; - fr = vtop[0].r; - vtop--; - C67_SHRU(fr, r); // logical shift - break; - - case TOK_SAR: - gv2(RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst - r = vtop[-1].r; - fr = vtop[0].r; - vtop--; - C67_SHR(fr, r); // arithmetic shift - break; - - case '/': - t = TOK__divi; - call_func: - vswap(); - /* call generic idiv function */ - vpush_global_sym(&func_old_type, t); - vrott(3); - gfunc_call(2); - vpushi(0); - vtop->r = REG_IRET; - vtop->r2 = VT_CONST; - break; - case TOK_UDIV: - case TOK_PDIV: - t = TOK__divu; - goto call_func; - case '%': - t = TOK__remi; - goto call_func; - case TOK_UMOD: - t = TOK__remu; - goto call_func; - - default: - opc = 7; - goto gen_op8; - } -} - -/* generate a floating point operation 'v = t1 op t2' instruction. The - two operands are guaranted to have the same floating point type */ -/* XXX: need to use ST1 too */ -void gen_opf(int op) -{ - int ft, fc, fr, r; - - if (op >= TOK_ULT && op <= TOK_GT) - gv2(RC_EDX, RC_EAX); // make sure src2 is on b side - else - gv2(RC_FLOAT, RC_FLOAT); // make sure src2 is on b side - - ft = vtop->type.t; - fc = vtop->c.i; - r = vtop->r; - fr = vtop[-1].r; - - - if ((ft & VT_BTYPE) == VT_LDOUBLE) - tcc_error("long doubles not supported"); - - if (op >= TOK_ULT && op <= TOK_GT) { - - r = vtop[-1].r; - fr = vtop[0].r; - - C67_compare_reg = C67_B2; - - if (op == TOK_LT) { - if ((ft & VT_BTYPE) == VT_DOUBLE) - C67_CMPLTDP(r, fr, C67_B2); - else - C67_CMPLTSP(r, fr, C67_B2); - - C67_invert_test = FALSE; - } else if (op == TOK_GE) { - if ((ft & VT_BTYPE) == VT_DOUBLE) - C67_CMPLTDP(r, fr, C67_B2); - else - C67_CMPLTSP(r, fr, C67_B2); - - C67_invert_test = TRUE; - } else if (op == TOK_GT) { - if ((ft & VT_BTYPE) == VT_DOUBLE) - C67_CMPGTDP(r, fr, C67_B2); - else - C67_CMPGTSP(r, fr, C67_B2); - - C67_invert_test = FALSE; - } else if (op == TOK_LE) { - if ((ft & VT_BTYPE) == VT_DOUBLE) - C67_CMPGTDP(r, fr, C67_B2); - else - C67_CMPGTSP(r, fr, C67_B2); - - C67_invert_test = TRUE; - } else if (op == TOK_EQ) { - if ((ft & VT_BTYPE) == VT_DOUBLE) - C67_CMPEQDP(r, fr, C67_B2); - else - C67_CMPEQSP(r, fr, C67_B2); - - C67_invert_test = FALSE; - } else if (op == TOK_NE) { - if ((ft & VT_BTYPE) == VT_DOUBLE) - C67_CMPEQDP(r, fr, C67_B2); - else - C67_CMPEQSP(r, fr, C67_B2); - - C67_invert_test = TRUE; - } else { - ALWAYS_ASSERT(FALSE); - } - vtop->r = VT_CMP; // tell TCC that result is in "flags" actually B2 - } else { - if (op == '+') { - if ((ft & VT_BTYPE) == VT_DOUBLE) { - C67_ADDDP(r, fr); // ADD fr,r,fr - C67_NOP(6); - } else { - C67_ADDSP(r, fr); // ADD fr,r,fr - C67_NOP(3); - } - vtop--; - } else if (op == '-') { - if ((ft & VT_BTYPE) == VT_DOUBLE) { - C67_SUBDP(r, fr); // SUB fr,r,fr - C67_NOP(6); - } else { - C67_SUBSP(r, fr); // SUB fr,r,fr - C67_NOP(3); - } - vtop--; - } else if (op == '*') { - if ((ft & VT_BTYPE) == VT_DOUBLE) { - C67_MPYDP(r, fr); // MPY fr,r,fr - C67_NOP(9); - } else { - C67_MPYSP(r, fr); // MPY fr,r,fr - C67_NOP(3); - } - vtop--; - } else if (op == '/') { - if ((ft & VT_BTYPE) == VT_DOUBLE) { - // must call intrinsic DP floating point divide - vswap(); - /* call generic idiv function */ - vpush_global_sym(&func_old_type, TOK__divd); - vrott(3); - gfunc_call(2); - vpushi(0); - vtop->r = REG_FRET; - vtop->r2 = REG_LRET; - - } else { - // must call intrinsic SP floating point divide - vswap(); - /* call generic idiv function */ - vpush_global_sym(&func_old_type, TOK__divf); - vrott(3); - gfunc_call(2); - vpushi(0); - vtop->r = REG_FRET; - vtop->r2 = VT_CONST; - } - } else - ALWAYS_ASSERT(FALSE); - - - } -} - - -/* convert integers to fp 't' type. Must handle 'int', 'unsigned int' - and 'long long' cases. */ -void gen_cvt_itof(int t) -{ - int r; - - gv(RC_INT); - r = vtop->r; - - if ((t & VT_BTYPE) == VT_DOUBLE) { - if (t & VT_UNSIGNED) - C67_INTDPU(r, r); - else - C67_INTDP(r, r); - - C67_NOP(4); - vtop->type.t = VT_DOUBLE; - } else { - if (t & VT_UNSIGNED) - C67_INTSPU(r, r); - else - C67_INTSP(r, r); - C67_NOP(3); - vtop->type.t = VT_FLOAT; - } - -} - -/* convert fp to int 't' type */ -/* XXX: handle long long case */ -void gen_cvt_ftoi(int t) -{ - int r; - - gv(RC_FLOAT); - r = vtop->r; - - if (t != VT_INT) - tcc_error("long long not supported"); - else { - if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) { - C67_DPTRUNC(r, r); - C67_NOP(3); - } else { - C67_SPTRUNC(r, r); - C67_NOP(3); - } - - vtop->type.t = VT_INT; - - } -} - -/* convert from one floating point type to another */ -void gen_cvt_ftof(int t) -{ - int r, r2; - - if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE && - (t & VT_BTYPE) == VT_FLOAT) { - // convert double to float - - gv(RC_FLOAT); // get it in a register pair - - r = vtop->r; - - C67_DPSP(r, r); // convert it to SP same register - C67_NOP(3); - - vtop->type.t = VT_FLOAT; - vtop->r2 = VT_CONST; // set this as unused - } else if ((vtop->type.t & VT_BTYPE) == VT_FLOAT && - (t & VT_BTYPE) == VT_DOUBLE) { - // convert float to double - - gv(RC_FLOAT); // get it in a register - - r = vtop->r; - - if (r == TREG_EAX) { // make sure the paired reg is avail - r2 = get_reg(RC_ECX); - } else if (r == TREG_EDX) { - r2 = get_reg(RC_ST0); - } else { - ALWAYS_ASSERT(FALSE); - r2 = 0; /* avoid warning */ - } - - C67_SPDP(r, r); // convert it to DP same register - C67_NOP(1); - - vtop->type.t = VT_DOUBLE; - vtop->r2 = r2; // set this as unused - } else { - ALWAYS_ASSERT(FALSE); - } -} - -/* computed goto support */ -void ggoto(void) -{ - gcall_or_jmp(1); - vtop--; -} - -/* Save the stack pointer onto the stack and return the location of its address */ -ST_FUNC void gen_vla_sp_save(int addr) { - tcc_error("variable length arrays unsupported for this target"); -} - -/* Restore the SP from a location on the stack */ -ST_FUNC void gen_vla_sp_restore(int addr) { - tcc_error("variable length arrays unsupported for this target"); -} - -/* Subtract from the stack pointer, and push the resulting value onto the stack */ -ST_FUNC void gen_vla_alloc(CType *type, int align) { - tcc_error("variable length arrays unsupported for this target"); -} - -/* end of C67 code generator */ -/*************************************************************/ -#endif -/*************************************************************/ diff --git a/external/TCC/coff.h b/external/TCC/coff.h deleted file mode 100644 index ea871a7b..00000000 --- a/external/TCC/coff.h +++ /dev/null @@ -1,446 +0,0 @@ -/**************************************************************************/ -/* COFF.H */ -/* COFF data structures and related definitions used by the linker */ -/**************************************************************************/ - -/*------------------------------------------------------------------------*/ -/* COFF FILE HEADER */ -/*------------------------------------------------------------------------*/ -struct filehdr { - unsigned short f_magic; /* magic number */ - unsigned short f_nscns; /* number of sections */ - long f_timdat; /* time & date stamp */ - long f_symptr; /* file pointer to symtab */ - long f_nsyms; /* number of symtab entries */ - unsigned short f_opthdr; /* sizeof(optional hdr) */ - unsigned short f_flags; /* flags */ - unsigned short f_TargetID; /* for C6x = 0x0099 */ - }; - -/*------------------------------------------------------------------------*/ -/* File header flags */ -/*------------------------------------------------------------------------*/ -#define F_RELFLG 0x01 /* relocation info stripped from file */ -#define F_EXEC 0x02 /* file is executable (no unresolved refs) */ -#define F_LNNO 0x04 /* line nunbers stripped from file */ -#define F_LSYMS 0x08 /* local symbols stripped from file */ -#define F_GSP10 0x10 /* 34010 version */ -#define F_GSP20 0x20 /* 34020 version */ -#define F_SWABD 0x40 /* bytes swabbed (in names) */ -#define F_AR16WR 0x80 /* byte ordering of an AR16WR (PDP-11) */ -#define F_LITTLE 0x100 /* byte ordering of an AR32WR (vax) */ -#define F_BIG 0x200 /* byte ordering of an AR32W (3B, maxi) */ -#define F_PATCH 0x400 /* contains "patch" list in optional header */ -#define F_NODF 0x400 - -#define F_VERSION (F_GSP10 | F_GSP20) -#define F_BYTE_ORDER (F_LITTLE | F_BIG) -#define FILHDR struct filehdr - -/* #define FILHSZ sizeof(FILHDR) */ -#define FILHSZ 22 /* above rounds to align on 4 bytes which causes problems */ - -#define COFF_C67_MAGIC 0x00c2 - -/*------------------------------------------------------------------------*/ -/* Macros to recognize magic numbers */ -/*------------------------------------------------------------------------*/ -#define ISMAGIC(x) (((unsigned short)(x))==(unsigned short)magic) -#define ISARCHIVE(x) ((((unsigned short)(x))==(unsigned short)ARTYPE)) -#define BADMAGIC(x) (((unsigned short)(x) & 0x8080) && !ISMAGIC(x)) - - -/*------------------------------------------------------------------------*/ -/* OPTIONAL FILE HEADER */ -/*------------------------------------------------------------------------*/ -typedef struct aouthdr { - short magic; /* see magic.h */ - short vstamp; /* version stamp */ - long tsize; /* text size in bytes, padded to FW bdry*/ - long dsize; /* initialized data " " */ - long bsize; /* uninitialized data " " */ - long entrypt; /* entry pt. */ - long text_start; /* base of text used for this file */ - long data_start; /* base of data used for this file */ -} AOUTHDR; - -#define AOUTSZ sizeof(AOUTHDR) - -/*----------------------------------------------------------------------*/ -/* When a UNIX aout header is to be built in the optional header, */ -/* the following magic numbers can appear in that header: */ -/* */ -/* AOUT1MAGIC : default : readonly sharable text segment */ -/* AOUT2MAGIC: : writable text segment */ -/* PAGEMAGIC : : configured for paging */ -/*----------------------------------------------------------------------*/ -#define AOUT1MAGIC 0410 -#define AOUT2MAGIC 0407 -#define PAGEMAGIC 0413 - - -/*------------------------------------------------------------------------*/ -/* COMMON ARCHIVE FILE STRUCTURES */ -/* */ -/* ARCHIVE File Organization: */ -/* _______________________________________________ */ -/* |__________ARCHIVE_MAGIC_STRING_______________| */ -/* |__________ARCHIVE_FILE_MEMBER_1______________| */ -/* | | */ -/* | Archive File Header "ar_hdr" | */ -/* |.............................................| */ -/* | Member Contents | */ -/* | 1. External symbol directory | */ -/* | 2. Text file | */ -/* |_____________________________________________| */ -/* |________ARCHIVE_FILE_MEMBER_2________________| */ -/* | "ar_hdr" | */ -/* |.............................................| */ -/* | Member Contents (.o or text file) | */ -/* |_____________________________________________| */ -/* | . . . | */ -/* | . . . | */ -/* | . . . | */ -/* |_____________________________________________| */ -/* |________ARCHIVE_FILE_MEMBER_n________________| */ -/* | "ar_hdr" | */ -/* |.............................................| */ -/* | Member Contents | */ -/* |_____________________________________________| */ -/* */ -/*------------------------------------------------------------------------*/ - -#define COFF_ARMAG "!\n" -#define SARMAG 8 -#define ARFMAG "`\n" - -struct ar_hdr /* archive file member header - printable ascii */ -{ - char ar_name[16]; /* file member name - `/' terminated */ - char ar_date[12]; /* file member date - decimal */ - char ar_uid[6]; /* file member user id - decimal */ - char ar_gid[6]; /* file member group id - decimal */ - char ar_mode[8]; /* file member mode - octal */ - char ar_size[10]; /* file member size - decimal */ - char ar_fmag[2]; /* ARFMAG - string to end header */ -}; - - -/*------------------------------------------------------------------------*/ -/* SECTION HEADER */ -/*------------------------------------------------------------------------*/ -struct scnhdr { - char s_name[8]; /* section name */ - long s_paddr; /* physical address */ - long s_vaddr; /* virtual address */ - long s_size; /* section size */ - long s_scnptr; /* file ptr to raw data for section */ - long s_relptr; /* file ptr to relocation */ - long s_lnnoptr; /* file ptr to line numbers */ - unsigned int s_nreloc; /* number of relocation entries */ - unsigned int s_nlnno; /* number of line number entries */ - unsigned int s_flags; /* flags */ - unsigned short s_reserved; /* reserved byte */ - unsigned short s_page; /* memory page id */ - }; - -#define SCNHDR struct scnhdr -#define SCNHSZ sizeof(SCNHDR) - -/*------------------------------------------------------------------------*/ -/* Define constants for names of "special" sections */ -/*------------------------------------------------------------------------*/ -/* #define _TEXT ".text" */ -#define _DATA ".data" -#define _BSS ".bss" -#define _CINIT ".cinit" -#define _TV ".tv" - -/*------------------------------------------------------------------------*/ -/* The low 4 bits of s_flags is used as a section "type" */ -/*------------------------------------------------------------------------*/ -#define STYP_REG 0x00 /* "regular" : allocated, relocated, loaded */ -#define STYP_DSECT 0x01 /* "dummy" : not allocated, relocated, not loaded */ -#define STYP_NOLOAD 0x02 /* "noload" : allocated, relocated, not loaded */ -#define STYP_GROUP 0x04 /* "grouped" : formed of input sections */ -#define STYP_PAD 0x08 /* "padding" : not allocated, not relocated, loaded */ -#define STYP_COPY 0x10 /* "copy" : used for C init tables - - not allocated, relocated, - loaded; reloc & lineno - entries processed normally */ -#define STYP_TEXT 0x20 /* section contains text only */ -#define STYP_DATA 0x40 /* section contains data only */ -#define STYP_BSS 0x80 /* section contains bss only */ - -#define STYP_ALIGN 0x100 /* align flag passed by old version assemblers */ -#define ALIGN_MASK 0x0F00 /* part of s_flags that is used for align vals */ -#define ALIGNSIZE(x) (1 << ((x & ALIGN_MASK) >> 8)) - - -/*------------------------------------------------------------------------*/ -/* RELOCATION ENTRIES */ -/*------------------------------------------------------------------------*/ -struct reloc -{ - long r_vaddr; /* (virtual) address of reference */ - short r_symndx; /* index into symbol table */ - unsigned short r_disp; /* additional bits for address calculation */ - unsigned short r_type; /* relocation type */ -}; - -#define RELOC struct reloc -#define RELSZ 10 /* sizeof(RELOC) */ - -/*--------------------------------------------------------------------------*/ -/* define all relocation types */ -/*--------------------------------------------------------------------------*/ - -#define R_ABS 0 /* absolute address - no relocation */ -#define R_DIR16 01 /* UNUSED */ -#define R_REL16 02 /* UNUSED */ -#define R_DIR24 04 /* UNUSED */ -#define R_REL24 05 /* 24 bits, direct */ -#define R_DIR32 06 /* UNUSED */ -#define R_RELBYTE 017 /* 8 bits, direct */ -#define R_RELWORD 020 /* 16 bits, direct */ -#define R_RELLONG 021 /* 32 bits, direct */ -#define R_PCRBYTE 022 /* 8 bits, PC-relative */ -#define R_PCRWORD 023 /* 16 bits, PC-relative */ -#define R_PCRLONG 024 /* 32 bits, PC-relative */ -#define R_OCRLONG 030 /* GSP: 32 bits, one's complement direct */ -#define R_GSPPCR16 031 /* GSP: 16 bits, PC relative (in words) */ -#define R_GSPOPR32 032 /* GSP: 32 bits, direct big-endian */ -#define R_PARTLS16 040 /* Brahma: 16 bit offset of 24 bit address*/ -#define R_PARTMS8 041 /* Brahma: 8 bit page of 24 bit address */ -#define R_PARTLS7 050 /* DSP: 7 bit offset of 16 bit address */ -#define R_PARTMS9 051 /* DSP: 9 bit page of 16 bit address */ -#define R_REL13 052 /* DSP: 13 bits, direct */ - - -/*------------------------------------------------------------------------*/ -/* LINE NUMBER ENTRIES */ -/*------------------------------------------------------------------------*/ -struct lineno -{ - union - { - long l_symndx ; /* sym. table index of function name - iff l_lnno == 0 */ - long l_paddr ; /* (physical) address of line number */ - } l_addr ; - unsigned short l_lnno ; /* line number */ -}; - -#define LINENO struct lineno -#define LINESZ 6 /* sizeof(LINENO) */ - - -/*------------------------------------------------------------------------*/ -/* STORAGE CLASSES */ -/*------------------------------------------------------------------------*/ -#define C_EFCN -1 /* physical end of function */ -#define C_NULL 0 -#define C_AUTO 1 /* automatic variable */ -#define C_EXT 2 /* external symbol */ -#define C_STAT 3 /* static */ -#define C_REG 4 /* register variable */ -#define C_EXTDEF 5 /* external definition */ -#define C_LABEL 6 /* label */ -#define C_ULABEL 7 /* undefined label */ -#define C_MOS 8 /* member of structure */ -#define C_ARG 9 /* function argument */ -#define C_STRTAG 10 /* structure tag */ -#define C_MOU 11 /* member of union */ -#define C_UNTAG 12 /* union tag */ -#define C_TPDEF 13 /* type definition */ -#define C_USTATIC 14 /* undefined static */ -#define C_ENTAG 15 /* enumeration tag */ -#define C_MOE 16 /* member of enumeration */ -#define C_REGPARM 17 /* register parameter */ -#define C_FIELD 18 /* bit field */ - -#define C_BLOCK 100 /* ".bb" or ".eb" */ -#define C_FCN 101 /* ".bf" or ".ef" */ -#define C_EOS 102 /* end of structure */ -#define C_FILE 103 /* file name */ -#define C_LINE 104 /* dummy sclass for line number entry */ -#define C_ALIAS 105 /* duplicate tag */ -#define C_HIDDEN 106 /* special storage class for external */ - /* symbols in dmert public libraries */ - -/*------------------------------------------------------------------------*/ -/* SYMBOL TABLE ENTRIES */ -/*------------------------------------------------------------------------*/ - -#define SYMNMLEN 8 /* Number of characters in a symbol name */ -#define FILNMLEN 14 /* Number of characters in a file name */ -#define DIMNUM 4 /* Number of array dimensions in auxiliary entry */ - - -struct syment -{ - union - { - char _n_name[SYMNMLEN]; /* old COFF version */ - struct - { - long _n_zeroes; /* new == 0 */ - long _n_offset; /* offset into string table */ - } _n_n; - char *_n_nptr[2]; /* allows for overlaying */ - } _n; - long n_value; /* value of symbol */ - short n_scnum; /* section number */ - unsigned short n_type; /* type and derived type */ - char n_sclass; /* storage class */ - char n_numaux; /* number of aux. entries */ -}; - -#define n_name _n._n_name -#define n_nptr _n._n_nptr[1] -#define n_zeroes _n._n_n._n_zeroes -#define n_offset _n._n_n._n_offset - -/*------------------------------------------------------------------------*/ -/* Relocatable symbols have a section number of the */ -/* section in which they are defined. Otherwise, section */ -/* numbers have the following meanings: */ -/*------------------------------------------------------------------------*/ -#define N_UNDEF 0 /* undefined symbol */ -#define N_ABS -1 /* value of symbol is absolute */ -#define N_DEBUG -2 /* special debugging symbol */ -#define N_TV (unsigned short)-3 /* needs transfer vector (preload) */ -#define P_TV (unsigned short)-4 /* needs transfer vector (postload) */ - - -/*------------------------------------------------------------------------*/ -/* The fundamental type of a symbol packed into the low */ -/* 4 bits of the word. */ -/*------------------------------------------------------------------------*/ -#define _EF ".ef" - -#define T_NULL 0 /* no type info */ -#define T_ARG 1 /* function argument (only used by compiler) */ -#define T_CHAR 2 /* character */ -#define T_SHORT 3 /* short integer */ -#define T_INT 4 /* integer */ -#define T_LONG 5 /* long integer */ -#define T_FLOAT 6 /* floating point */ -#define T_DOUBLE 7 /* double word */ -#define T_STRUCT 8 /* structure */ -#define T_UNION 9 /* union */ -#define T_ENUM 10 /* enumeration */ -#define T_MOE 11 /* member of enumeration */ -#define T_UCHAR 12 /* unsigned character */ -#define T_USHORT 13 /* unsigned short */ -#define T_UINT 14 /* unsigned integer */ -#define T_ULONG 15 /* unsigned long */ - -/*------------------------------------------------------------------------*/ -/* derived types are: */ -/*------------------------------------------------------------------------*/ -#define DT_NON 0 /* no derived type */ -#define DT_PTR 1 /* pointer */ -#define DT_FCN 2 /* function */ -#define DT_ARY 3 /* array */ - -#define MKTYPE(basic, d1,d2,d3,d4,d5,d6) \ - ((basic) | ((d1) << 4) | ((d2) << 6) | ((d3) << 8) |\ - ((d4) << 10) | ((d5) << 12) | ((d6) << 14)) - -/*------------------------------------------------------------------------*/ -/* type packing constants and macros */ -/*------------------------------------------------------------------------*/ -#define N_BTMASK_COFF 017 -#define N_TMASK_COFF 060 -#define N_TMASK1_COFF 0300 -#define N_TMASK2_COFF 0360 -#define N_BTSHFT_COFF 4 -#define N_TSHIFT_COFF 2 - -#define BTYPE_COFF(x) ((x) & N_BTMASK_COFF) -#define ISINT(x) (((x) >= T_CHAR && (x) <= T_LONG) || \ - ((x) >= T_UCHAR && (x) <= T_ULONG) || (x) == T_ENUM) -#define ISFLT_COFF(x) ((x) == T_DOUBLE || (x) == T_FLOAT) -#define ISPTR_COFF(x) (((x) & N_TMASK_COFF) == (DT_PTR << N_BTSHFT_COFF)) -#define ISFCN_COFF(x) (((x) & N_TMASK_COFF) == (DT_FCN << N_BTSHFT_COFF)) -#define ISARY_COFF(x) (((x) & N_TMASK_COFF) == (DT_ARY << N_BTSHFT_COFF)) -#define ISTAG_COFF(x) ((x)==C_STRTAG || (x)==C_UNTAG || (x)==C_ENTAG) - -#define INCREF_COFF(x) ((((x)&~N_BTMASK_COFF)<>N_TSHIFT_COFF)&~N_BTMASK_COFF)|((x)&N_BTMASK_COFF)) - - -/*------------------------------------------------------------------------*/ -/* AUXILIARY SYMBOL ENTRY */ -/*------------------------------------------------------------------------*/ -union auxent -{ - struct - { - long x_tagndx; /* str, un, or enum tag indx */ - union - { - struct - { - unsigned short x_lnno; /* declaration line number */ - unsigned short x_size; /* str, union, array size */ - } x_lnsz; - long x_fsize; /* size of function */ - } x_misc; - union - { - struct /* if ISFCN, tag, or .bb */ - { - long x_lnnoptr; /* ptr to fcn line # */ - long x_endndx; /* entry ndx past block end */ - } x_fcn; - struct /* if ISARY, up to 4 dimen. */ - { - unsigned short x_dimen[DIMNUM]; - } x_ary; - } x_fcnary; - unsigned short x_regcount; /* number of registers used by func */ - } x_sym; - struct - { - char x_fname[FILNMLEN]; - } x_file; - struct - { - long x_scnlen; /* section length */ - unsigned short x_nreloc; /* number of relocation entries */ - unsigned short x_nlinno; /* number of line numbers */ - } x_scn; -}; - -#define SYMENT struct syment -#define SYMESZ 18 /* sizeof(SYMENT) */ - -#define AUXENT union auxent -#define AUXESZ 18 /* sizeof(AUXENT) */ - -/*------------------------------------------------------------------------*/ -/* NAMES OF "SPECIAL" SYMBOLS */ -/*------------------------------------------------------------------------*/ -#define _STEXT ".text" -#define _ETEXT "etext" -#define _SDATA ".data" -#define _EDATA "edata" -#define _SBSS ".bss" -#define _END "end" -#define _CINITPTR "cinit" - -/*--------------------------------------------------------------------------*/ -/* ENTRY POINT SYMBOLS */ -/*--------------------------------------------------------------------------*/ -#define _START "_start" -#define _MAIN "_main" - /* _CSTART "_c_int00" (defined in params.h) */ - - -#define _TVORIG "_tvorig" -#define _TORIGIN "_torigin" -#define _DORIGIN "_dorigin" - -#define _SORIGIN "_sorigin" diff --git a/external/TCC/config.h b/external/TCC/config.h deleted file mode 100644 index 958399e6..00000000 --- a/external/TCC/config.h +++ /dev/null @@ -1,7 +0,0 @@ -#define CONFIG_TCCDIR "C:/Program Files (x86)/tcc" -#define TCC_VERSION "0.9.26" - -/* #undef CONFIG_WIN32 */ -/* #undef CONFIG_WIN64 */ -/* #undef CONFIG_TCC_BCHECK */ -/* #undef CONFIG_TCC_ASSERT */ diff --git a/external/TCC/elf.h b/external/TCC/elf.h deleted file mode 100644 index 52ccf3fd..00000000 --- a/external/TCC/elf.h +++ /dev/null @@ -1,3233 +0,0 @@ -/* This file defines standard ELF types, structures, and macros. - Copyright (C) 1995-2012 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C 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. - - The GNU C 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 the GNU C Library; if not, see - . */ - -#ifndef _ELF_H -#define _ELF_H 1 - -#ifndef _WIN32 -#include -#else -#ifndef __int8_t_defined -#define __int8_t_defined -typedef signed char int8_t; -typedef short int int16_t; -typedef int int32_t; -typedef long long int int64_t; -#endif - -typedef unsigned char uint8_t; -typedef unsigned short int uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long long int uint64_t; -#endif - -/* Standard ELF types. */ - -/* Type for a 16-bit quantity. */ -typedef uint16_t Elf32_Half; -typedef uint16_t Elf64_Half; - -/* Types for signed and unsigned 32-bit quantities. */ -typedef uint32_t Elf32_Word; -typedef int32_t Elf32_Sword; -typedef uint32_t Elf64_Word; -typedef int32_t Elf64_Sword; - -/* Types for signed and unsigned 64-bit quantities. */ -typedef uint64_t Elf32_Xword; -typedef int64_t Elf32_Sxword; -typedef uint64_t Elf64_Xword; -typedef int64_t Elf64_Sxword; - -/* Type of addresses. */ -typedef uint32_t Elf32_Addr; -typedef uint64_t Elf64_Addr; - -/* Type of file offsets. */ -typedef uint32_t Elf32_Off; -typedef uint64_t Elf64_Off; - -/* Type for section indices, which are 16-bit quantities. */ -typedef uint16_t Elf32_Section; -typedef uint16_t Elf64_Section; - -/* Type for version symbol information. */ -typedef Elf32_Half Elf32_Versym; -typedef Elf64_Half Elf64_Versym; - - -/* The ELF file header. This appears at the start of every ELF file. */ - -#define EI_NIDENT (16) - -typedef struct -{ - unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ - Elf32_Half e_type; /* Object file type */ - Elf32_Half e_machine; /* Architecture */ - Elf32_Word e_version; /* Object file version */ - Elf32_Addr e_entry; /* Entry point virtual address */ - Elf32_Off e_phoff; /* Program header table file offset */ - Elf32_Off e_shoff; /* Section header table file offset */ - Elf32_Word e_flags; /* Processor-specific flags */ - Elf32_Half e_ehsize; /* ELF header size in bytes */ - Elf32_Half e_phentsize; /* Program header table entry size */ - Elf32_Half e_phnum; /* Program header table entry count */ - Elf32_Half e_shentsize; /* Section header table entry size */ - Elf32_Half e_shnum; /* Section header table entry count */ - Elf32_Half e_shstrndx; /* Section header string table index */ -} Elf32_Ehdr; - -typedef struct -{ - unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ - Elf64_Half e_type; /* Object file type */ - Elf64_Half e_machine; /* Architecture */ - Elf64_Word e_version; /* Object file version */ - Elf64_Addr e_entry; /* Entry point virtual address */ - Elf64_Off e_phoff; /* Program header table file offset */ - Elf64_Off e_shoff; /* Section header table file offset */ - Elf64_Word e_flags; /* Processor-specific flags */ - Elf64_Half e_ehsize; /* ELF header size in bytes */ - Elf64_Half e_phentsize; /* Program header table entry size */ - Elf64_Half e_phnum; /* Program header table entry count */ - Elf64_Half e_shentsize; /* Section header table entry size */ - Elf64_Half e_shnum; /* Section header table entry count */ - Elf64_Half e_shstrndx; /* Section header string table index */ -} Elf64_Ehdr; - -/* Fields in the e_ident array. The EI_* macros are indices into the - array. The macros under each EI_* macro are the values the byte - may have. */ - -#define EI_MAG0 0 /* File identification byte 0 index */ -#define ELFMAG0 0x7f /* Magic number byte 0 */ - -#define EI_MAG1 1 /* File identification byte 1 index */ -#define ELFMAG1 'E' /* Magic number byte 1 */ - -#define EI_MAG2 2 /* File identification byte 2 index */ -#define ELFMAG2 'L' /* Magic number byte 2 */ - -#define EI_MAG3 3 /* File identification byte 3 index */ -#define ELFMAG3 'F' /* Magic number byte 3 */ - -/* Conglomeration of the identification bytes, for easy testing as a word. */ -#define ELFMAG "\177ELF" -#define SELFMAG 4 - -#define EI_CLASS 4 /* File class byte index */ -#define ELFCLASSNONE 0 /* Invalid class */ -#define ELFCLASS32 1 /* 32-bit objects */ -#define ELFCLASS64 2 /* 64-bit objects */ -#define ELFCLASSNUM 3 - -#define EI_DATA 5 /* Data encoding byte index */ -#define ELFDATANONE 0 /* Invalid data encoding */ -#define ELFDATA2LSB 1 /* 2's complement, little endian */ -#define ELFDATA2MSB 2 /* 2's complement, big endian */ -#define ELFDATANUM 3 - -#define EI_VERSION 6 /* File version byte index */ - /* Value must be EV_CURRENT */ - -#define EI_OSABI 7 /* OS ABI identification */ -#define ELFOSABI_NONE 0 /* UNIX System V ABI */ -#define ELFOSABI_SYSV 0 /* Alias. */ -#define ELFOSABI_HPUX 1 /* HP-UX */ -#define ELFOSABI_NETBSD 2 /* NetBSD. */ -#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */ -#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */ -#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */ -#define ELFOSABI_AIX 7 /* IBM AIX. */ -#define ELFOSABI_IRIX 8 /* SGI Irix. */ -#define ELFOSABI_FREEBSD 9 /* FreeBSD. */ -#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */ -#define ELFOSABI_MODESTO 11 /* Novell Modesto. */ -#define ELFOSABI_OPENBSD 12 /* OpenBSD. */ -#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */ -#define ELFOSABI_ARM 97 /* ARM */ -#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ - -#define EI_ABIVERSION 8 /* ABI version */ - -#define EI_PAD 9 /* Byte index of padding bytes */ - -/* Legal values for e_type (object file type). */ - -#define ET_NONE 0 /* No file type */ -#define ET_REL 1 /* Relocatable file */ -#define ET_EXEC 2 /* Executable file */ -#define ET_DYN 3 /* Shared object file */ -#define ET_CORE 4 /* Core file */ -#define ET_NUM 5 /* Number of defined types */ -#define ET_LOOS 0xfe00 /* OS-specific range start */ -#define ET_HIOS 0xfeff /* OS-specific range end */ -#define ET_LOPROC 0xff00 /* Processor-specific range start */ -#define ET_HIPROC 0xffff /* Processor-specific range end */ - -/* Legal values for e_machine (architecture). */ - -#define EM_NONE 0 /* No machine */ -#define EM_M32 1 /* AT&T WE 32100 */ -#define EM_SPARC 2 /* SUN SPARC */ -#define EM_386 3 /* Intel 80386 */ -#define EM_68K 4 /* Motorola m68k family */ -#define EM_88K 5 /* Motorola m88k family */ -#define EM_860 7 /* Intel 80860 */ -#define EM_MIPS 8 /* MIPS R3000 big-endian */ -#define EM_S370 9 /* IBM System/370 */ -#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ - -#define EM_PARISC 15 /* HPPA */ -#define EM_VPP500 17 /* Fujitsu VPP500 */ -#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ -#define EM_960 19 /* Intel 80960 */ -#define EM_PPC 20 /* PowerPC */ -#define EM_PPC64 21 /* PowerPC 64-bit */ -#define EM_S390 22 /* IBM S390 */ - -#define EM_V800 36 /* NEC V800 series */ -#define EM_FR20 37 /* Fujitsu FR20 */ -#define EM_RH32 38 /* TRW RH-32 */ -#define EM_RCE 39 /* Motorola RCE */ -#define EM_ARM 40 /* ARM */ -#define EM_FAKE_ALPHA 41 /* Digital Alpha */ -#define EM_SH 42 /* Hitachi SH */ -#define EM_SPARCV9 43 /* SPARC v9 64-bit */ -#define EM_TRICORE 44 /* Siemens Tricore */ -#define EM_ARC 45 /* Argonaut RISC Core */ -#define EM_H8_300 46 /* Hitachi H8/300 */ -#define EM_H8_300H 47 /* Hitachi H8/300H */ -#define EM_H8S 48 /* Hitachi H8S */ -#define EM_H8_500 49 /* Hitachi H8/500 */ -#define EM_IA_64 50 /* Intel Merced */ -#define EM_MIPS_X 51 /* Stanford MIPS-X */ -#define EM_COLDFIRE 52 /* Motorola Coldfire */ -#define EM_68HC12 53 /* Motorola M68HC12 */ -#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ -#define EM_PCP 55 /* Siemens PCP */ -#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ -#define EM_NDR1 57 /* Denso NDR1 microprocessor */ -#define EM_STARCORE 58 /* Motorola Start*Core processor */ -#define EM_ME16 59 /* Toyota ME16 processor */ -#define EM_ST100 60 /* STMicroelectronic ST100 processor */ -#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ -#define EM_X86_64 62 /* AMD x86-64 architecture */ -#define EM_PDSP 63 /* Sony DSP Processor */ - -#define EM_FX66 66 /* Siemens FX66 microcontroller */ -#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ -#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ -#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ -#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ -#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ -#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ -#define EM_SVX 73 /* Silicon Graphics SVx */ -#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ -#define EM_VAX 75 /* Digital VAX */ -#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ -#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */ -#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ -#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ -#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */ -#define EM_HUANY 81 /* Harvard University machine-independent object files */ -#define EM_PRISM 82 /* SiTera Prism */ -#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ -#define EM_FR30 84 /* Fujitsu FR30 */ -#define EM_D10V 85 /* Mitsubishi D10V */ -#define EM_D30V 86 /* Mitsubishi D30V */ -#define EM_V850 87 /* NEC v850 */ -#define EM_M32R 88 /* Mitsubishi M32R */ -#define EM_MN10300 89 /* Matsushita MN10300 */ -#define EM_MN10200 90 /* Matsushita MN10200 */ -#define EM_PJ 91 /* picoJava */ -#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ -#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ -#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ -#define EM_AARCH64 183 /* ARM AARCH64 */ -#define EM_TILEPRO 188 /* Tilera TILEPro */ -#define EM_TILEGX 191 /* Tilera TILE-Gx */ -#define EM_NUM 192 - -/* If it is necessary to assign new unofficial EM_* values, please - pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the - chances of collision with official or non-GNU unofficial values. */ - -#define EM_ALPHA 0x9026 -#define EM_C60 0x9c60 - -/* Legal values for e_version (version). */ - -#define EV_NONE 0 /* Invalid ELF version */ -#define EV_CURRENT 1 /* Current version */ -#define EV_NUM 2 - -/* Section header. */ - -typedef struct -{ - Elf32_Word sh_name; /* Section name (string tbl index) */ - Elf32_Word sh_type; /* Section type */ - Elf32_Word sh_flags; /* Section flags */ - Elf32_Addr sh_addr; /* Section virtual addr at execution */ - Elf32_Off sh_offset; /* Section file offset */ - Elf32_Word sh_size; /* Section size in bytes */ - Elf32_Word sh_link; /* Link to another section */ - Elf32_Word sh_info; /* Additional section information */ - Elf32_Word sh_addralign; /* Section alignment */ - Elf32_Word sh_entsize; /* Entry size if section holds table */ -} Elf32_Shdr; - -typedef struct -{ - Elf64_Word sh_name; /* Section name (string tbl index) */ - Elf64_Word sh_type; /* Section type */ - Elf64_Xword sh_flags; /* Section flags */ - Elf64_Addr sh_addr; /* Section virtual addr at execution */ - Elf64_Off sh_offset; /* Section file offset */ - Elf64_Xword sh_size; /* Section size in bytes */ - Elf64_Word sh_link; /* Link to another section */ - Elf64_Word sh_info; /* Additional section information */ - Elf64_Xword sh_addralign; /* Section alignment */ - Elf64_Xword sh_entsize; /* Entry size if section holds table */ -} Elf64_Shdr; - -/* Special section indices. */ - -#define SHN_UNDEF 0 /* Undefined section */ -#define SHN_LORESERVE 0xff00 /* Start of reserved indices */ -#define SHN_LOPROC 0xff00 /* Start of processor-specific */ -#define SHN_BEFORE 0xff00 /* Order section before all others - (Solaris). */ -#define SHN_AFTER 0xff01 /* Order section after all others - (Solaris). */ -#define SHN_HIPROC 0xff1f /* End of processor-specific */ -#define SHN_LOOS 0xff20 /* Start of OS-specific */ -#define SHN_HIOS 0xff3f /* End of OS-specific */ -#define SHN_ABS 0xfff1 /* Associated symbol is absolute */ -#define SHN_COMMON 0xfff2 /* Associated symbol is common */ -#define SHN_XINDEX 0xffff /* Index is in extra table. */ -#define SHN_HIRESERVE 0xffff /* End of reserved indices */ - -/* Legal values for sh_type (section type). */ - -#define SHT_NULL 0 /* Section header table entry unused */ -#define SHT_PROGBITS 1 /* Program data */ -#define SHT_SYMTAB 2 /* Symbol table */ -#define SHT_STRTAB 3 /* String table */ -#define SHT_RELA 4 /* Relocation entries with addends */ -#define SHT_HASH 5 /* Symbol hash table */ -#define SHT_DYNAMIC 6 /* Dynamic linking information */ -#define SHT_NOTE 7 /* Notes */ -#define SHT_NOBITS 8 /* Program space with no data (bss) */ -#define SHT_REL 9 /* Relocation entries, no addends */ -#define SHT_SHLIB 10 /* Reserved */ -#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ -#define SHT_INIT_ARRAY 14 /* Array of constructors */ -#define SHT_FINI_ARRAY 15 /* Array of destructors */ -#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ -#define SHT_GROUP 17 /* Section group */ -#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ -#define SHT_NUM 19 /* Number of defined types. */ -#define SHT_LOOS 0x60000000 /* Start OS-specific. */ -#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */ -#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */ -#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */ -#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */ -#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */ -#define SHT_SUNW_move 0x6ffffffa -#define SHT_SUNW_COMDAT 0x6ffffffb -#define SHT_SUNW_syminfo 0x6ffffffc -#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ -#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ -#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ -#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ -#define SHT_HIOS 0x6fffffff /* End OS-specific type */ -#define SHT_LOPROC 0x70000000 /* Start of processor-specific */ -#define SHT_HIPROC 0x7fffffff /* End of processor-specific */ -#define SHT_LOUSER 0x80000000 /* Start of application-specific */ -#define SHT_HIUSER 0x8fffffff /* End of application-specific */ - -/* Legal values for sh_flags (section flags). */ - -#define SHF_WRITE (1 << 0) /* Writable */ -#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ -#define SHF_EXECINSTR (1 << 2) /* Executable */ -#define SHF_MERGE (1 << 4) /* Might be merged */ -#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */ -#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */ -#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */ -#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling - required */ -#define SHF_GROUP (1 << 9) /* Section is member of a group. */ -#define SHF_TLS (1 << 10) /* Section hold thread-local data. */ -#define SHF_MASKOS 0x0ff00000 /* OS-specific. */ -#define SHF_MASKPROC 0xf0000000 /* Processor-specific */ -#define SHF_ORDERED (1 << 30) /* Special ordering requirement - (Solaris). */ -#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless - referenced or allocated (Solaris).*/ - -/* Section group handling. */ -#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */ - -/* Symbol table entry. */ - -typedef struct -{ - Elf32_Word st_name; /* Symbol name (string tbl index) */ - Elf32_Addr st_value; /* Symbol value */ - Elf32_Word st_size; /* Symbol size */ - unsigned char st_info; /* Symbol type and binding */ - unsigned char st_other; /* Symbol visibility */ - Elf32_Section st_shndx; /* Section index */ -} Elf32_Sym; - -typedef struct -{ - Elf64_Word st_name; /* Symbol name (string tbl index) */ - unsigned char st_info; /* Symbol type and binding */ - unsigned char st_other; /* Symbol visibility */ - Elf64_Section st_shndx; /* Section index */ - Elf64_Addr st_value; /* Symbol value */ - Elf64_Xword st_size; /* Symbol size */ -} Elf64_Sym; - -/* The syminfo section if available contains additional information about - every dynamic symbol. */ - -typedef struct -{ - Elf32_Half si_boundto; /* Direct bindings, symbol bound to */ - Elf32_Half si_flags; /* Per symbol flags */ -} Elf32_Syminfo; - -typedef struct -{ - Elf64_Half si_boundto; /* Direct bindings, symbol bound to */ - Elf64_Half si_flags; /* Per symbol flags */ -} Elf64_Syminfo; - -/* Possible values for si_boundto. */ -#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */ -#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */ -#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */ - -/* Possible bitmasks for si_flags. */ -#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */ -#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */ -#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */ -#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy - loaded */ -/* Syminfo version values. */ -#define SYMINFO_NONE 0 -#define SYMINFO_CURRENT 1 -#define SYMINFO_NUM 2 - - -/* How to extract and insert information held in the st_info field. */ - -#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) -#define ELF32_ST_TYPE(val) ((val) & 0xf) -#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) - -/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */ -#define ELF64_ST_BIND(val) ELF32_ST_BIND (val) -#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) -#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) - -/* Legal values for ST_BIND subfield of st_info (symbol binding). */ - -#define STB_LOCAL 0 /* Local symbol */ -#define STB_GLOBAL 1 /* Global symbol */ -#define STB_WEAK 2 /* Weak symbol */ -#define STB_NUM 3 /* Number of defined types. */ -#define STB_LOOS 10 /* Start of OS-specific */ -#define STB_GNU_UNIQUE 10 /* Unique symbol. */ -#define STB_HIOS 12 /* End of OS-specific */ -#define STB_LOPROC 13 /* Start of processor-specific */ -#define STB_HIPROC 15 /* End of processor-specific */ - -/* Legal values for ST_TYPE subfield of st_info (symbol type). */ - -#define STT_NOTYPE 0 /* Symbol type is unspecified */ -#define STT_OBJECT 1 /* Symbol is a data object */ -#define STT_FUNC 2 /* Symbol is a code object */ -#define STT_SECTION 3 /* Symbol associated with a section */ -#define STT_FILE 4 /* Symbol's name is file name */ -#define STT_COMMON 5 /* Symbol is a common data object */ -#define STT_TLS 6 /* Symbol is thread-local data object*/ -#define STT_NUM 7 /* Number of defined types. */ -#define STT_LOOS 10 /* Start of OS-specific */ -#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */ -#define STT_HIOS 12 /* End of OS-specific */ -#define STT_LOPROC 13 /* Start of processor-specific */ -#define STT_HIPROC 15 /* End of processor-specific */ - - -/* Symbol table indices are found in the hash buckets and chain table - of a symbol hash table section. This special index value indicates - the end of a chain, meaning no further symbols are found in that bucket. */ - -#define STN_UNDEF 0 /* End of a chain. */ - - -/* How to extract and insert information held in the st_other field. */ - -#define ELF32_ST_VISIBILITY(o) ((o) & 0x03) - -/* For ELF64 the definitions are the same. */ -#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o) - -/* Symbol visibility specification encoded in the st_other field. */ -#define STV_DEFAULT 0 /* Default symbol visibility rules */ -#define STV_INTERNAL 1 /* Processor specific hidden class */ -#define STV_HIDDEN 2 /* Sym unavailable in other modules */ -#define STV_PROTECTED 3 /* Not preemptible, not exported */ - - -/* Relocation table entry without addend (in section of type SHT_REL). */ - -typedef struct -{ - Elf32_Addr r_offset; /* Address */ - Elf32_Word r_info; /* Relocation type and symbol index */ -} Elf32_Rel; - -/* I have seen two different definitions of the Elf64_Rel and - Elf64_Rela structures, so we'll leave them out until Novell (or - whoever) gets their act together. */ -/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */ - -typedef struct -{ - Elf64_Addr r_offset; /* Address */ - Elf64_Xword r_info; /* Relocation type and symbol index */ -} Elf64_Rel; - -/* Relocation table entry with addend (in section of type SHT_RELA). */ - -typedef struct -{ - Elf32_Addr r_offset; /* Address */ - Elf32_Word r_info; /* Relocation type and symbol index */ - Elf32_Sword r_addend; /* Addend */ -} Elf32_Rela; - -typedef struct -{ - Elf64_Addr r_offset; /* Address */ - Elf64_Xword r_info; /* Relocation type and symbol index */ - Elf64_Sxword r_addend; /* Addend */ -} Elf64_Rela; - -/* How to extract and insert information held in the r_info field. */ - -#define ELF32_R_SYM(val) ((val) >> 8) -#define ELF32_R_TYPE(val) ((val) & 0xff) -#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) - -#define ELF64_R_SYM(i) ((i) >> 32) -#define ELF64_R_TYPE(i) ((i) & 0xffffffff) -#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type)) - -/* Program segment header. */ - -typedef struct -{ - Elf32_Word p_type; /* Segment type */ - Elf32_Off p_offset; /* Segment file offset */ - Elf32_Addr p_vaddr; /* Segment virtual address */ - Elf32_Addr p_paddr; /* Segment physical address */ - Elf32_Word p_filesz; /* Segment size in file */ - Elf32_Word p_memsz; /* Segment size in memory */ - Elf32_Word p_flags; /* Segment flags */ - Elf32_Word p_align; /* Segment alignment */ -} Elf32_Phdr; - -typedef struct -{ - Elf64_Word p_type; /* Segment type */ - Elf64_Word p_flags; /* Segment flags */ - Elf64_Off p_offset; /* Segment file offset */ - Elf64_Addr p_vaddr; /* Segment virtual address */ - Elf64_Addr p_paddr; /* Segment physical address */ - Elf64_Xword p_filesz; /* Segment size in file */ - Elf64_Xword p_memsz; /* Segment size in memory */ - Elf64_Xword p_align; /* Segment alignment */ -} Elf64_Phdr; - -/* Special value for e_phnum. This indicates that the real number of - program headers is too large to fit into e_phnum. Instead the real - value is in the field sh_info of section 0. */ - -#define PN_XNUM 0xffff - -/* Legal values for p_type (segment type). */ - -#define PT_NULL 0 /* Program header table entry unused */ -#define PT_LOAD 1 /* Loadable program segment */ -#define PT_DYNAMIC 2 /* Dynamic linking information */ -#define PT_INTERP 3 /* Program interpreter */ -#define PT_NOTE 4 /* Auxiliary information */ -#define PT_SHLIB 5 /* Reserved */ -#define PT_PHDR 6 /* Entry for header table itself */ -#define PT_TLS 7 /* Thread-local storage segment */ -#define PT_NUM 8 /* Number of defined types */ -#define PT_LOOS 0x60000000 /* Start of OS-specific */ -#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ -#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */ -#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ -#define PT_LOSUNW 0x6ffffffa -#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ -#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ -#define PT_HISUNW 0x6fffffff -#define PT_HIOS 0x6fffffff /* End of OS-specific */ -#define PT_LOPROC 0x70000000 /* Start of processor-specific */ -#define PT_HIPROC 0x7fffffff /* End of processor-specific */ - -/* Legal values for p_flags (segment flags). */ - -#define PF_X (1 << 0) /* Segment is executable */ -#define PF_W (1 << 1) /* Segment is writable */ -#define PF_R (1 << 2) /* Segment is readable */ -#define PF_MASKOS 0x0ff00000 /* OS-specific */ -#define PF_MASKPROC 0xf0000000 /* Processor-specific */ - -/* Legal values for note segment descriptor types for core files. */ - -#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */ -#define NT_FPREGSET 2 /* Contains copy of fpregset struct */ -#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ -#define NT_PRXREG 4 /* Contains copy of prxregset struct */ -#define NT_TASKSTRUCT 4 /* Contains copy of task structure */ -#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */ -#define NT_AUXV 6 /* Contains copy of auxv array */ -#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */ -#define NT_ASRS 8 /* Contains copy of asrset struct */ -#define NT_PSTATUS 10 /* Contains copy of pstatus struct */ -#define NT_PSINFO 13 /* Contains copy of psinfo struct */ -#define NT_PRCRED 14 /* Contains copy of prcred struct */ -#define NT_UTSNAME 15 /* Contains copy of utsname struct */ -#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */ -#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */ -#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */ -#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct */ -#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ -#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ -#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ -#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ -#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ -#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */ -#define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */ -#define NT_S390_TIMER 0x301 /* s390 timer register */ -#define NT_S390_TODCMP 0x302 /* s390 TOD clock comparator register */ -#define NT_S390_TODPREG 0x303 /* s390 TOD programmable register */ -#define NT_S390_CTRS 0x304 /* s390 control registers */ -#define NT_S390_PREFIX 0x305 /* s390 prefix register */ -#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */ -#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */ -#define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */ -#define NT_ARM_TLS 0x401 /* ARM TLS register */ -#define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */ -#define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */ - -/* Legal values for the note segment descriptor types for object files. */ - -#define NT_VERSION 1 /* Contains a version string. */ - - -/* Dynamic section entry. */ - -typedef struct -{ - Elf32_Sword d_tag; /* Dynamic entry type */ - union - { - Elf32_Word d_val; /* Integer value */ - Elf32_Addr d_ptr; /* Address value */ - } d_un; -} Elf32_Dyn; - -typedef struct -{ - Elf64_Sxword d_tag; /* Dynamic entry type */ - union - { - Elf64_Xword d_val; /* Integer value */ - Elf64_Addr d_ptr; /* Address value */ - } d_un; -} Elf64_Dyn; - -/* Legal values for d_tag (dynamic entry type). */ - -#define DT_NULL 0 /* Marks end of dynamic section */ -#define DT_NEEDED 1 /* Name of needed library */ -#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ -#define DT_PLTGOT 3 /* Processor defined value */ -#define DT_HASH 4 /* Address of symbol hash table */ -#define DT_STRTAB 5 /* Address of string table */ -#define DT_SYMTAB 6 /* Address of symbol table */ -#define DT_RELA 7 /* Address of Rela relocs */ -#define DT_RELASZ 8 /* Total size of Rela relocs */ -#define DT_RELAENT 9 /* Size of one Rela reloc */ -#define DT_STRSZ 10 /* Size of string table */ -#define DT_SYMENT 11 /* Size of one symbol table entry */ -#define DT_INIT 12 /* Address of init function */ -#define DT_FINI 13 /* Address of termination function */ -#define DT_SONAME 14 /* Name of shared object */ -#define DT_RPATH 15 /* Library search path (deprecated) */ -#define DT_SYMBOLIC 16 /* Start symbol search here */ -#define DT_REL 17 /* Address of Rel relocs */ -#define DT_RELSZ 18 /* Total size of Rel relocs */ -#define DT_RELENT 19 /* Size of one Rel reloc */ -#define DT_PLTREL 20 /* Type of reloc in PLT */ -#define DT_DEBUG 21 /* For debugging; unspecified */ -#define DT_TEXTREL 22 /* Reloc might modify .text */ -#define DT_JMPREL 23 /* Address of PLT relocs */ -#define DT_BIND_NOW 24 /* Process relocations of object */ -#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ -#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ -#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ -#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ -#define DT_RUNPATH 29 /* Library search path */ -#define DT_FLAGS 30 /* Flags for the object being loaded */ -#define DT_ENCODING 32 /* Start of encoded range */ -#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ -#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ -#define DT_NUM 34 /* Number used */ -#define DT_LOOS 0x6000000d /* Start of OS-specific */ -#define DT_HIOS 0x6ffff000 /* End of OS-specific */ -#define DT_LOPROC 0x70000000 /* Start of processor-specific */ -#define DT_HIPROC 0x7fffffff /* End of processor-specific */ -#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ - -/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the - Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's - approach. */ -#define DT_VALRNGLO 0x6ffffd00 -#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */ -#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */ -#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */ -#define DT_CHECKSUM 0x6ffffdf8 -#define DT_PLTPADSZ 0x6ffffdf9 -#define DT_MOVEENT 0x6ffffdfa -#define DT_MOVESZ 0x6ffffdfb -#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */ -#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting - the following DT_* entry. */ -#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */ -#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */ -#define DT_VALRNGHI 0x6ffffdff -#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */ -#define DT_VALNUM 12 - -/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the - Dyn.d_un.d_ptr field of the Elf*_Dyn structure. - - If any adjustment is made to the ELF object after it has been - built these entries will need to be adjusted. */ -#define DT_ADDRRNGLO 0x6ffffe00 -#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table. */ -#define DT_TLSDESC_PLT 0x6ffffef6 -#define DT_TLSDESC_GOT 0x6ffffef7 -#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */ -#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */ -#define DT_CONFIG 0x6ffffefa /* Configuration information. */ -#define DT_DEPAUDIT 0x6ffffefb /* Dependency auditing. */ -#define DT_AUDIT 0x6ffffefc /* Object auditing. */ -#define DT_PLTPAD 0x6ffffefd /* PLT padding. */ -#define DT_MOVETAB 0x6ffffefe /* Move table. */ -#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */ -#define DT_ADDRRNGHI 0x6ffffeff -#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */ -#define DT_ADDRNUM 11 - -/* The versioning entry types. The next are defined as part of the - GNU extension. */ -#define DT_VERSYM 0x6ffffff0 - -#define DT_RELACOUNT 0x6ffffff9 -#define DT_RELCOUNT 0x6ffffffa - -/* These were chosen by Sun. */ -#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */ -#define DT_VERDEF 0x6ffffffc /* Address of version definition - table */ -#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */ -#define DT_VERNEED 0x6ffffffe /* Address of table with needed - versions */ -#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */ -#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ -#define DT_VERSIONTAGNUM 16 - -/* Sun added these machine-independent extensions in the "processor-specific" - range. Be compatible. */ -#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */ -#define DT_FILTER 0x7fffffff /* Shared object to get values from */ -#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) -#define DT_EXTRANUM 3 - -/* Values of `d_un.d_val' in the DT_FLAGS entry. */ -#define DF_ORIGIN 0x00000001 /* Object may use DF_ORIGIN */ -#define DF_SYMBOLIC 0x00000002 /* Symbol resolutions starts here */ -#define DF_TEXTREL 0x00000004 /* Object contains text relocations */ -#define DF_BIND_NOW 0x00000008 /* No lazy binding for this object */ -#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */ - -/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 - entry in the dynamic section. */ -#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */ -#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */ -#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */ -#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/ -#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/ -#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/ -#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */ -#define DF_1_ORIGIN 0x00000080 /* $ORIGIN must be handled. */ -#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */ -#define DF_1_TRANS 0x00000200 -#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */ -#define DF_1_NODEFLIB 0x00000800 /* Ignore default lib search path. */ -#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */ -#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/ -#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */ -#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */ -#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */ -#define DF_1_NODIRECT 0x00020000 /* Object has no-direct binding. */ -#define DF_1_IGNMULDEF 0x00040000 -#define DF_1_NOKSYMS 0x00080000 -#define DF_1_NOHDR 0x00100000 -#define DF_1_EDITED 0x00200000 /* Object is modified after built. */ -#define DF_1_NORELOC 0x00400000 -#define DF_1_SYMINTPOSE 0x00800000 /* Object has individual interposers. */ -#define DF_1_GLOBAUDIT 0x01000000 /* Global auditin required. */ -#define DF_1_SINGLETON 0x02000000 /* Singleton symbols are used. */ - -/* Flags for the feature selection in DT_FEATURE_1. */ -#define DTF_1_PARINIT 0x00000001 -#define DTF_1_CONFEXP 0x00000002 - -/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */ -#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */ -#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not - generally available. */ - -/* Version definition sections. */ - -typedef struct -{ - Elf32_Half vd_version; /* Version revision */ - Elf32_Half vd_flags; /* Version information */ - Elf32_Half vd_ndx; /* Version Index */ - Elf32_Half vd_cnt; /* Number of associated aux entries */ - Elf32_Word vd_hash; /* Version name hash value */ - Elf32_Word vd_aux; /* Offset in bytes to verdaux array */ - Elf32_Word vd_next; /* Offset in bytes to next verdef - entry */ -} Elf32_Verdef; - -typedef struct -{ - Elf64_Half vd_version; /* Version revision */ - Elf64_Half vd_flags; /* Version information */ - Elf64_Half vd_ndx; /* Version Index */ - Elf64_Half vd_cnt; /* Number of associated aux entries */ - Elf64_Word vd_hash; /* Version name hash value */ - Elf64_Word vd_aux; /* Offset in bytes to verdaux array */ - Elf64_Word vd_next; /* Offset in bytes to next verdef - entry */ -} Elf64_Verdef; - - -/* Legal values for vd_version (version revision). */ -#define VER_DEF_NONE 0 /* No version */ -#define VER_DEF_CURRENT 1 /* Current version */ -#define VER_DEF_NUM 2 /* Given version number */ - -/* Legal values for vd_flags (version information flags). */ -#define VER_FLG_BASE 0x1 /* Version definition of file itself */ -#define VER_FLG_WEAK 0x2 /* Weak version identifier */ - -/* Versym symbol index values. */ -#define VER_NDX_LOCAL 0 /* Symbol is local. */ -#define VER_NDX_GLOBAL 1 /* Symbol is global. */ -#define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */ -#define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */ - -/* Auxialiary version information. */ - -typedef struct -{ - Elf32_Word vda_name; /* Version or dependency names */ - Elf32_Word vda_next; /* Offset in bytes to next verdaux - entry */ -} Elf32_Verdaux; - -typedef struct -{ - Elf64_Word vda_name; /* Version or dependency names */ - Elf64_Word vda_next; /* Offset in bytes to next verdaux - entry */ -} Elf64_Verdaux; - - -/* Version dependency section. */ - -typedef struct -{ - Elf32_Half vn_version; /* Version of structure */ - Elf32_Half vn_cnt; /* Number of associated aux entries */ - Elf32_Word vn_file; /* Offset of filename for this - dependency */ - Elf32_Word vn_aux; /* Offset in bytes to vernaux array */ - Elf32_Word vn_next; /* Offset in bytes to next verneed - entry */ -} Elf32_Verneed; - -typedef struct -{ - Elf64_Half vn_version; /* Version of structure */ - Elf64_Half vn_cnt; /* Number of associated aux entries */ - Elf64_Word vn_file; /* Offset of filename for this - dependency */ - Elf64_Word vn_aux; /* Offset in bytes to vernaux array */ - Elf64_Word vn_next; /* Offset in bytes to next verneed - entry */ -} Elf64_Verneed; - - -/* Legal values for vn_version (version revision). */ -#define VER_NEED_NONE 0 /* No version */ -#define VER_NEED_CURRENT 1 /* Current version */ -#define VER_NEED_NUM 2 /* Given version number */ - -/* Auxiliary needed version information. */ - -typedef struct -{ - Elf32_Word vna_hash; /* Hash value of dependency name */ - Elf32_Half vna_flags; /* Dependency specific information */ - Elf32_Half vna_other; /* Unused */ - Elf32_Word vna_name; /* Dependency name string offset */ - Elf32_Word vna_next; /* Offset in bytes to next vernaux - entry */ -} Elf32_Vernaux; - -typedef struct -{ - Elf64_Word vna_hash; /* Hash value of dependency name */ - Elf64_Half vna_flags; /* Dependency specific information */ - Elf64_Half vna_other; /* Unused */ - Elf64_Word vna_name; /* Dependency name string offset */ - Elf64_Word vna_next; /* Offset in bytes to next vernaux - entry */ -} Elf64_Vernaux; - - -/* Legal values for vna_flags. */ -#define VER_FLG_WEAK 0x2 /* Weak version identifier */ - - -/* Auxiliary vector. */ - -/* This vector is normally only used by the program interpreter. The - usual definition in an ABI supplement uses the name auxv_t. The - vector is not usually defined in a standard file, but it - can't hurt. We rename it to avoid conflicts. The sizes of these - types are an arrangement between the exec server and the program - interpreter, so we don't fully specify them here. */ - -typedef struct -{ - uint32_t a_type; /* Entry type */ - union - { - uint32_t a_val; /* Integer value */ - /* We use to have pointer elements added here. We cannot do that, - though, since it does not work when using 32-bit definitions - on 64-bit platforms and vice versa. */ - } a_un; -} Elf32_auxv_t; - -typedef struct -{ - uint64_t a_type; /* Entry type */ - union - { - uint64_t a_val; /* Integer value */ - /* We use to have pointer elements added here. We cannot do that, - though, since it does not work when using 32-bit definitions - on 64-bit platforms and vice versa. */ - } a_un; -} Elf64_auxv_t; - -/* Legal values for a_type (entry type). */ - -#define AT_NULL 0 /* End of vector */ -#define AT_IGNORE 1 /* Entry should be ignored */ -#define AT_EXECFD 2 /* File descriptor of program */ -#define AT_PHDR 3 /* Program headers for program */ -#define AT_PHENT 4 /* Size of program header entry */ -#define AT_PHNUM 5 /* Number of program headers */ -#define AT_PAGESZ 6 /* System page size */ -#define AT_BASE 7 /* Base address of interpreter */ -#define AT_FLAGS 8 /* Flags */ -#define AT_ENTRY 9 /* Entry point of program */ -#define AT_NOTELF 10 /* Program is not ELF */ -#define AT_UID 11 /* Real uid */ -#define AT_EUID 12 /* Effective uid */ -#define AT_GID 13 /* Real gid */ -#define AT_EGID 14 /* Effective gid */ -#define AT_CLKTCK 17 /* Frequency of times() */ - -/* Some more special a_type values describing the hardware. */ -#define AT_PLATFORM 15 /* String identifying platform. */ -#define AT_HWCAP 16 /* Machine dependent hints about - processor capabilities. */ - -/* This entry gives some information about the FPU initialization - performed by the kernel. */ -#define AT_FPUCW 18 /* Used FPU control word. */ - -/* Cache block sizes. */ -#define AT_DCACHEBSIZE 19 /* Data cache block size. */ -#define AT_ICACHEBSIZE 20 /* Instruction cache block size. */ -#define AT_UCACHEBSIZE 21 /* Unified cache block size. */ - -/* A special ignored value for PPC, used by the kernel to control the - interpretation of the AUXV. Must be > 16. */ -#define AT_IGNOREPPC 22 /* Entry should be ignored. */ - -#define AT_SECURE 23 /* Boolean, was exec setuid-like? */ - -#define AT_BASE_PLATFORM 24 /* String identifying real platforms.*/ - -#define AT_RANDOM 25 /* Address of 16 random bytes. */ - -#define AT_EXECFN 31 /* Filename of executable. */ - -/* Pointer to the global system page used for system calls and other - nice things. */ -#define AT_SYSINFO 32 -#define AT_SYSINFO_EHDR 33 - -/* Shapes of the caches. Bits 0-3 contains associativity; bits 4-7 contains - log2 of line size; mask those to get cache size. */ -#define AT_L1I_CACHESHAPE 34 -#define AT_L1D_CACHESHAPE 35 -#define AT_L2_CACHESHAPE 36 -#define AT_L3_CACHESHAPE 37 - -/* Note section contents. Each entry in the note section begins with - a header of a fixed form. */ - -typedef struct -{ - Elf32_Word n_namesz; /* Length of the note's name. */ - Elf32_Word n_descsz; /* Length of the note's descriptor. */ - Elf32_Word n_type; /* Type of the note. */ -} Elf32_Nhdr; - -typedef struct -{ - Elf64_Word n_namesz; /* Length of the note's name. */ - Elf64_Word n_descsz; /* Length of the note's descriptor. */ - Elf64_Word n_type; /* Type of the note. */ -} Elf64_Nhdr; - -/* Known names of notes. */ - -/* Solaris entries in the note section have this name. */ -#define ELF_NOTE_SOLARIS "SUNW Solaris" - -/* Note entries for GNU systems have this name. */ -#define ELF_NOTE_GNU "GNU" - - -/* Defined types of notes for Solaris. */ - -/* Value of descriptor (one word) is desired pagesize for the binary. */ -#define ELF_NOTE_PAGESIZE_HINT 1 - - -/* Defined note types for GNU systems. */ - -/* ABI information. The descriptor consists of words: - word 0: OS descriptor - word 1: major version of the ABI - word 2: minor version of the ABI - word 3: subminor version of the ABI -*/ -#define NT_GNU_ABI_TAG 1 -#define ELF_NOTE_ABI NT_GNU_ABI_TAG /* Old name. */ - -/* Known OSes. These values can appear in word 0 of an - NT_GNU_ABI_TAG note section entry. */ -#define ELF_NOTE_OS_LINUX 0 -#define ELF_NOTE_OS_GNU 1 -#define ELF_NOTE_OS_SOLARIS2 2 -#define ELF_NOTE_OS_FREEBSD 3 - -/* Synthetic hwcap information. The descriptor begins with two words: - word 0: number of entries - word 1: bitmask of enabled entries - Then follow variable-length entries, one byte followed by a - '\0'-terminated hwcap name string. The byte gives the bit - number to test if enabled, (1U << bit) & bitmask. */ -#define NT_GNU_HWCAP 2 - -/* Build ID bits as generated by ld --build-id. - The descriptor consists of any nonzero number of bytes. */ -#define NT_GNU_BUILD_ID 3 - -/* Version note generated by GNU gold containing a version string. */ -#define NT_GNU_GOLD_VERSION 4 - - -/* Move records. */ -typedef struct -{ - Elf32_Xword m_value; /* Symbol value. */ - Elf32_Word m_info; /* Size and index. */ - Elf32_Word m_poffset; /* Symbol offset. */ - Elf32_Half m_repeat; /* Repeat count. */ - Elf32_Half m_stride; /* Stride info. */ -} Elf32_Move; - -typedef struct -{ - Elf64_Xword m_value; /* Symbol value. */ - Elf64_Xword m_info; /* Size and index. */ - Elf64_Xword m_poffset; /* Symbol offset. */ - Elf64_Half m_repeat; /* Repeat count. */ - Elf64_Half m_stride; /* Stride info. */ -} Elf64_Move; - -/* Macro to construct move records. */ -#define ELF32_M_SYM(info) ((info) >> 8) -#define ELF32_M_SIZE(info) ((unsigned char) (info)) -#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size)) - -#define ELF64_M_SYM(info) ELF32_M_SYM (info) -#define ELF64_M_SIZE(info) ELF32_M_SIZE (info) -#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size) - - -/* Motorola 68k specific definitions. */ - -/* Values for Elf32_Ehdr.e_flags. */ -#define EF_CPU32 0x00810000 - -/* m68k relocs. */ - -#define R_68K_NONE 0 /* No reloc */ -#define R_68K_32 1 /* Direct 32 bit */ -#define R_68K_16 2 /* Direct 16 bit */ -#define R_68K_8 3 /* Direct 8 bit */ -#define R_68K_PC32 4 /* PC relative 32 bit */ -#define R_68K_PC16 5 /* PC relative 16 bit */ -#define R_68K_PC8 6 /* PC relative 8 bit */ -#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */ -#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */ -#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */ -#define R_68K_GOT32O 10 /* 32 bit GOT offset */ -#define R_68K_GOT16O 11 /* 16 bit GOT offset */ -#define R_68K_GOT8O 12 /* 8 bit GOT offset */ -#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */ -#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */ -#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */ -#define R_68K_PLT32O 16 /* 32 bit PLT offset */ -#define R_68K_PLT16O 17 /* 16 bit PLT offset */ -#define R_68K_PLT8O 18 /* 8 bit PLT offset */ -#define R_68K_COPY 19 /* Copy symbol at runtime */ -#define R_68K_GLOB_DAT 20 /* Create GOT entry */ -#define R_68K_JMP_SLOT 21 /* Create PLT entry */ -#define R_68K_RELATIVE 22 /* Adjust by program base */ -#define R_68K_TLS_GD32 25 /* 32 bit GOT offset for GD */ -#define R_68K_TLS_GD16 26 /* 16 bit GOT offset for GD */ -#define R_68K_TLS_GD8 27 /* 8 bit GOT offset for GD */ -#define R_68K_TLS_LDM32 28 /* 32 bit GOT offset for LDM */ -#define R_68K_TLS_LDM16 29 /* 16 bit GOT offset for LDM */ -#define R_68K_TLS_LDM8 30 /* 8 bit GOT offset for LDM */ -#define R_68K_TLS_LDO32 31 /* 32 bit module-relative offset */ -#define R_68K_TLS_LDO16 32 /* 16 bit module-relative offset */ -#define R_68K_TLS_LDO8 33 /* 8 bit module-relative offset */ -#define R_68K_TLS_IE32 34 /* 32 bit GOT offset for IE */ -#define R_68K_TLS_IE16 35 /* 16 bit GOT offset for IE */ -#define R_68K_TLS_IE8 36 /* 8 bit GOT offset for IE */ -#define R_68K_TLS_LE32 37 /* 32 bit offset relative to - static TLS block */ -#define R_68K_TLS_LE16 38 /* 16 bit offset relative to - static TLS block */ -#define R_68K_TLS_LE8 39 /* 8 bit offset relative to - static TLS block */ -#define R_68K_TLS_DTPMOD32 40 /* 32 bit module number */ -#define R_68K_TLS_DTPREL32 41 /* 32 bit module-relative offset */ -#define R_68K_TLS_TPREL32 42 /* 32 bit TP-relative offset */ -/* Keep this the last entry. */ -#define R_68K_NUM 43 - -/* Intel 80386 specific definitions. */ - -/* i386 relocs. */ - -#define R_386_NONE 0 /* No reloc */ -#define R_386_32 1 /* Direct 32 bit */ -#define R_386_PC32 2 /* PC relative 32 bit */ -#define R_386_GOT32 3 /* 32 bit GOT entry */ -#define R_386_PLT32 4 /* 32 bit PLT address */ -#define R_386_COPY 5 /* Copy symbol at runtime */ -#define R_386_GLOB_DAT 6 /* Create GOT entry */ -#define R_386_JMP_SLOT 7 /* Create PLT entry */ -#define R_386_RELATIVE 8 /* Adjust by program base */ -#define R_386_GOTOFF 9 /* 32 bit offset to GOT */ -#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */ -#define R_386_32PLT 11 -#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */ -#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS - block offset */ -#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block - offset */ -#define R_386_TLS_LE 17 /* Offset relative to static TLS - block */ -#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of - general dynamic thread local data */ -#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of - local dynamic thread local data - in LE code */ -#define R_386_16 20 -#define R_386_PC16 21 -#define R_386_8 22 -#define R_386_PC8 23 -#define R_386_TLS_GD_32 24 /* Direct 32 bit for general dynamic - thread local data */ -#define R_386_TLS_GD_PUSH 25 /* Tag for pushl in GD TLS code */ -#define R_386_TLS_GD_CALL 26 /* Relocation for call to - __tls_get_addr() */ -#define R_386_TLS_GD_POP 27 /* Tag for popl in GD TLS code */ -#define R_386_TLS_LDM_32 28 /* Direct 32 bit for local dynamic - thread local data in LE code */ -#define R_386_TLS_LDM_PUSH 29 /* Tag for pushl in LDM TLS code */ -#define R_386_TLS_LDM_CALL 30 /* Relocation for call to - __tls_get_addr() in LDM code */ -#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */ -#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */ -#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS - block offset */ -#define R_386_TLS_LE_32 34 /* Negated offset relative to static - TLS block */ -#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */ -#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */ -#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */ -/* 38? */ -#define R_386_TLS_GOTDESC 39 /* GOT offset for TLS descriptor. */ -#define R_386_TLS_DESC_CALL 40 /* Marker of call through TLS - descriptor for - relaxation. */ -#define R_386_TLS_DESC 41 /* TLS descriptor containing - pointer to code and to - argument, returning the TLS - offset for the symbol. */ -#define R_386_IRELATIVE 42 /* Adjust indirectly by program base */ -#define R_386_GOT32X 43 /* 32 bit GOT entry, relaxable */ -/* Keep this the last entry. */ -#define R_386_NUM 44 - -/* SUN SPARC specific definitions. */ - -/* Legal values for ST_TYPE subfield of st_info (symbol type). */ - -#define STT_SPARC_REGISTER 13 /* Global register reserved to app. */ - -/* Values for Elf64_Ehdr.e_flags. */ - -#define EF_SPARCV9_MM 3 -#define EF_SPARCV9_TSO 0 -#define EF_SPARCV9_PSO 1 -#define EF_SPARCV9_RMO 2 -#define EF_SPARC_LEDATA 0x800000 /* little endian data */ -#define EF_SPARC_EXT_MASK 0xFFFF00 -#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */ -#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */ -#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */ -#define EF_SPARC_SUN_US3 0x000800 /* Sun UltraSPARCIII extensions */ - -/* SPARC relocs. */ - -#define R_SPARC_NONE 0 /* No reloc */ -#define R_SPARC_8 1 /* Direct 8 bit */ -#define R_SPARC_16 2 /* Direct 16 bit */ -#define R_SPARC_32 3 /* Direct 32 bit */ -#define R_SPARC_DISP8 4 /* PC relative 8 bit */ -#define R_SPARC_DISP16 5 /* PC relative 16 bit */ -#define R_SPARC_DISP32 6 /* PC relative 32 bit */ -#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */ -#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */ -#define R_SPARC_HI22 9 /* High 22 bit */ -#define R_SPARC_22 10 /* Direct 22 bit */ -#define R_SPARC_13 11 /* Direct 13 bit */ -#define R_SPARC_LO10 12 /* Truncated 10 bit */ -#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */ -#define R_SPARC_GOT13 14 /* 13 bit GOT entry */ -#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */ -#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */ -#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */ -#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */ -#define R_SPARC_COPY 19 /* Copy symbol at runtime */ -#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */ -#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */ -#define R_SPARC_RELATIVE 22 /* Adjust by program base */ -#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */ - -/* Additional Sparc64 relocs. */ - -#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */ -#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */ -#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */ -#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */ -#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */ -#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */ -#define R_SPARC_10 30 /* Direct 10 bit */ -#define R_SPARC_11 31 /* Direct 11 bit */ -#define R_SPARC_64 32 /* Direct 64 bit */ -#define R_SPARC_OLO10 33 /* 10bit with secondary 13bit addend */ -#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */ -#define R_SPARC_HM10 35 /* High middle 10 bits of ... */ -#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */ -#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */ -#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */ -#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */ -#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */ -#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */ -#define R_SPARC_GLOB_JMP 42 /* was part of v9 ABI but was removed */ -#define R_SPARC_7 43 /* Direct 7 bit */ -#define R_SPARC_5 44 /* Direct 5 bit */ -#define R_SPARC_6 45 /* Direct 6 bit */ -#define R_SPARC_DISP64 46 /* PC relative 64 bit */ -#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */ -#define R_SPARC_HIX22 48 /* High 22 bit complemented */ -#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */ -#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */ -#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */ -#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */ -#define R_SPARC_REGISTER 53 /* Global register usage */ -#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */ -#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */ -#define R_SPARC_TLS_GD_HI22 56 -#define R_SPARC_TLS_GD_LO10 57 -#define R_SPARC_TLS_GD_ADD 58 -#define R_SPARC_TLS_GD_CALL 59 -#define R_SPARC_TLS_LDM_HI22 60 -#define R_SPARC_TLS_LDM_LO10 61 -#define R_SPARC_TLS_LDM_ADD 62 -#define R_SPARC_TLS_LDM_CALL 63 -#define R_SPARC_TLS_LDO_HIX22 64 -#define R_SPARC_TLS_LDO_LOX10 65 -#define R_SPARC_TLS_LDO_ADD 66 -#define R_SPARC_TLS_IE_HI22 67 -#define R_SPARC_TLS_IE_LO10 68 -#define R_SPARC_TLS_IE_LD 69 -#define R_SPARC_TLS_IE_LDX 70 -#define R_SPARC_TLS_IE_ADD 71 -#define R_SPARC_TLS_LE_HIX22 72 -#define R_SPARC_TLS_LE_LOX10 73 -#define R_SPARC_TLS_DTPMOD32 74 -#define R_SPARC_TLS_DTPMOD64 75 -#define R_SPARC_TLS_DTPOFF32 76 -#define R_SPARC_TLS_DTPOFF64 77 -#define R_SPARC_TLS_TPOFF32 78 -#define R_SPARC_TLS_TPOFF64 79 -#define R_SPARC_GOTDATA_HIX22 80 -#define R_SPARC_GOTDATA_LOX10 81 -#define R_SPARC_GOTDATA_OP_HIX22 82 -#define R_SPARC_GOTDATA_OP_LOX10 83 -#define R_SPARC_GOTDATA_OP 84 -#define R_SPARC_H34 85 -#define R_SPARC_SIZE32 86 -#define R_SPARC_SIZE64 87 -#define R_SPARC_WDISP10 88 -#define R_SPARC_JMP_IREL 248 -#define R_SPARC_IRELATIVE 249 -#define R_SPARC_GNU_VTINHERIT 250 -#define R_SPARC_GNU_VTENTRY 251 -#define R_SPARC_REV32 252 -/* Keep this the last entry. */ -#define R_SPARC_NUM 253 - -/* For Sparc64, legal values for d_tag of Elf64_Dyn. */ - -#define DT_SPARC_REGISTER 0x70000001 -#define DT_SPARC_NUM 2 - -/* MIPS R3000 specific definitions. */ - -/* Legal values for e_flags field of Elf32_Ehdr. */ - -#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used */ -#define EF_MIPS_PIC 2 /* Contains PIC code */ -#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence */ -#define EF_MIPS_XGOT 8 -#define EF_MIPS_64BIT_WHIRL 16 -#define EF_MIPS_ABI2 32 -#define EF_MIPS_ABI_ON32 64 -#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */ - -/* Legal values for MIPS architecture level. */ - -#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ -#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ -#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ -#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ -#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ -#define EF_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ -#define EF_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ - -/* The following are non-official names and should not be used. */ - -#define E_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ -#define E_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ -#define E_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ -#define E_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ -#define E_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ -#define E_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ -#define E_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ - -/* Special section indices. */ - -#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */ -#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */ -#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */ -#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */ -#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */ - -/* Legal values for sh_type field of Elf32_Shdr. */ - -#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link */ -#define SHT_MIPS_MSYM 0x70000001 -#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols */ -#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes */ -#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */ -#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information*/ -#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information */ -#define SHT_MIPS_PACKAGE 0x70000007 -#define SHT_MIPS_PACKSYM 0x70000008 -#define SHT_MIPS_RELD 0x70000009 -#define SHT_MIPS_IFACE 0x7000000b -#define SHT_MIPS_CONTENT 0x7000000c -#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */ -#define SHT_MIPS_SHDR 0x70000010 -#define SHT_MIPS_FDESC 0x70000011 -#define SHT_MIPS_EXTSYM 0x70000012 -#define SHT_MIPS_DENSE 0x70000013 -#define SHT_MIPS_PDESC 0x70000014 -#define SHT_MIPS_LOCSYM 0x70000015 -#define SHT_MIPS_AUXSYM 0x70000016 -#define SHT_MIPS_OPTSYM 0x70000017 -#define SHT_MIPS_LOCSTR 0x70000018 -#define SHT_MIPS_LINE 0x70000019 -#define SHT_MIPS_RFDESC 0x7000001a -#define SHT_MIPS_DELTASYM 0x7000001b -#define SHT_MIPS_DELTAINST 0x7000001c -#define SHT_MIPS_DELTACLASS 0x7000001d -#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */ -#define SHT_MIPS_DELTADECL 0x7000001f -#define SHT_MIPS_SYMBOL_LIB 0x70000020 -#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */ -#define SHT_MIPS_TRANSLATE 0x70000022 -#define SHT_MIPS_PIXIE 0x70000023 -#define SHT_MIPS_XLATE 0x70000024 -#define SHT_MIPS_XLATE_DEBUG 0x70000025 -#define SHT_MIPS_WHIRL 0x70000026 -#define SHT_MIPS_EH_REGION 0x70000027 -#define SHT_MIPS_XLATE_OLD 0x70000028 -#define SHT_MIPS_PDR_EXCEPTION 0x70000029 - -/* Legal values for sh_flags field of Elf32_Shdr. */ - -#define SHF_MIPS_GPREL 0x10000000 /* Must be part of global data area */ -#define SHF_MIPS_MERGE 0x20000000 -#define SHF_MIPS_ADDR 0x40000000 -#define SHF_MIPS_STRINGS 0x80000000 -#define SHF_MIPS_NOSTRIP 0x08000000 -#define SHF_MIPS_LOCAL 0x04000000 -#define SHF_MIPS_NAMES 0x02000000 -#define SHF_MIPS_NODUPE 0x01000000 - - -/* Symbol tables. */ - -/* MIPS specific values for `st_other'. */ -#define STO_MIPS_DEFAULT 0x0 -#define STO_MIPS_INTERNAL 0x1 -#define STO_MIPS_HIDDEN 0x2 -#define STO_MIPS_PROTECTED 0x3 -#define STO_MIPS_PLT 0x8 -#define STO_MIPS_SC_ALIGN_UNUSED 0xff - -/* MIPS specific values for `st_info'. */ -#define STB_MIPS_SPLIT_COMMON 13 - -/* Entries found in sections of type SHT_MIPS_GPTAB. */ - -typedef union -{ - struct - { - Elf32_Word gt_current_g_value; /* -G value used for compilation */ - Elf32_Word gt_unused; /* Not used */ - } gt_header; /* First entry in section */ - struct - { - Elf32_Word gt_g_value; /* If this value were used for -G */ - Elf32_Word gt_bytes; /* This many bytes would be used */ - } gt_entry; /* Subsequent entries in section */ -} Elf32_gptab; - -/* Entry found in sections of type SHT_MIPS_REGINFO. */ - -typedef struct -{ - Elf32_Word ri_gprmask; /* General registers used */ - Elf32_Word ri_cprmask[4]; /* Coprocessor registers used */ - Elf32_Sword ri_gp_value; /* $gp register value */ -} Elf32_RegInfo; - -/* Entries found in sections of type SHT_MIPS_OPTIONS. */ - -typedef struct -{ - unsigned char kind; /* Determines interpretation of the - variable part of descriptor. */ - unsigned char size; /* Size of descriptor, including header. */ - Elf32_Section section; /* Section header index of section affected, - 0 for global options. */ - Elf32_Word info; /* Kind-specific information. */ -} Elf_Options; - -/* Values for `kind' field in Elf_Options. */ - -#define ODK_NULL 0 /* Undefined. */ -#define ODK_REGINFO 1 /* Register usage information. */ -#define ODK_EXCEPTIONS 2 /* Exception processing options. */ -#define ODK_PAD 3 /* Section padding options. */ -#define ODK_HWPATCH 4 /* Hardware workarounds performed */ -#define ODK_FILL 5 /* record the fill value used by the linker. */ -#define ODK_TAGS 6 /* reserve space for desktop tools to write. */ -#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */ -#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */ - -/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */ - -#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */ -#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */ -#define OEX_PAGE0 0x10000 /* page zero must be mapped. */ -#define OEX_SMM 0x20000 /* Force sequential memory mode? */ -#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */ -#define OEX_PRECISEFP OEX_FPDBUG -#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */ - -#define OEX_FPU_INVAL 0x10 -#define OEX_FPU_DIV0 0x08 -#define OEX_FPU_OFLO 0x04 -#define OEX_FPU_UFLO 0x02 -#define OEX_FPU_INEX 0x01 - -/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */ - -#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */ -#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */ -#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */ -#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */ - -#define OPAD_PREFIX 0x1 -#define OPAD_POSTFIX 0x2 -#define OPAD_SYMBOL 0x4 - -/* Entry found in `.options' section. */ - -typedef struct -{ - Elf32_Word hwp_flags1; /* Extra flags. */ - Elf32_Word hwp_flags2; /* Extra flags. */ -} Elf_Options_Hw; - -/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */ - -#define OHWA0_R4KEOP_CHECKED 0x00000001 -#define OHWA1_R4KEOP_CLEAN 0x00000002 - -/* MIPS relocs. */ - -#define R_MIPS_NONE 0 /* No reloc */ -#define R_MIPS_16 1 /* Direct 16 bit */ -#define R_MIPS_32 2 /* Direct 32 bit */ -#define R_MIPS_REL32 3 /* PC relative 32 bit */ -#define R_MIPS_26 4 /* Direct 26 bit shifted */ -#define R_MIPS_HI16 5 /* High 16 bit */ -#define R_MIPS_LO16 6 /* Low 16 bit */ -#define R_MIPS_GPREL16 7 /* GP relative 16 bit */ -#define R_MIPS_LITERAL 8 /* 16 bit literal entry */ -#define R_MIPS_GOT16 9 /* 16 bit GOT entry */ -#define R_MIPS_PC16 10 /* PC relative 16 bit */ -#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ -#define R_MIPS_GPREL32 12 /* GP relative 32 bit */ - -#define R_MIPS_SHIFT5 16 -#define R_MIPS_SHIFT6 17 -#define R_MIPS_64 18 -#define R_MIPS_GOT_DISP 19 -#define R_MIPS_GOT_PAGE 20 -#define R_MIPS_GOT_OFST 21 -#define R_MIPS_GOT_HI16 22 -#define R_MIPS_GOT_LO16 23 -#define R_MIPS_SUB 24 -#define R_MIPS_INSERT_A 25 -#define R_MIPS_INSERT_B 26 -#define R_MIPS_DELETE 27 -#define R_MIPS_HIGHER 28 -#define R_MIPS_HIGHEST 29 -#define R_MIPS_CALL_HI16 30 -#define R_MIPS_CALL_LO16 31 -#define R_MIPS_SCN_DISP 32 -#define R_MIPS_REL16 33 -#define R_MIPS_ADD_IMMEDIATE 34 -#define R_MIPS_PJUMP 35 -#define R_MIPS_RELGOT 36 -#define R_MIPS_JALR 37 -#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */ -#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */ -#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */ -#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */ -#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */ -#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */ -#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */ -#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */ -#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */ -#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */ -#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */ -#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */ -#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */ -#define R_MIPS_GLOB_DAT 51 -#define R_MIPS_COPY 126 -#define R_MIPS_JUMP_SLOT 127 -/* Keep this the last entry. */ -#define R_MIPS_NUM 128 - -/* Legal values for p_type field of Elf32_Phdr. */ - -#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */ -#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ -#define PT_MIPS_OPTIONS 0x70000002 - -/* Special program header types. */ - -#define PF_MIPS_LOCAL 0x10000000 - -/* Legal values for d_tag field of Elf32_Dyn. */ - -#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */ -#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */ -#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */ -#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */ -#define DT_MIPS_FLAGS 0x70000005 /* Flags */ -#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */ -#define DT_MIPS_MSYM 0x70000007 -#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */ -#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */ -#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */ -#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */ -#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */ -#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */ -#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */ -#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */ -#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */ -#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */ -#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */ -#define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in - DT_MIPS_DELTA_CLASS. */ -#define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */ -#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in - DT_MIPS_DELTA_INSTANCE. */ -#define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */ -#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in - DT_MIPS_DELTA_RELOC. */ -#define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta - relocations refer to. */ -#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in - DT_MIPS_DELTA_SYM. */ -#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the - class declaration. */ -#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in - DT_MIPS_DELTA_CLASSSYM. */ -#define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */ -#define DT_MIPS_PIXIE_INIT 0x70000023 -#define DT_MIPS_SYMBOL_LIB 0x70000024 -#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025 -#define DT_MIPS_LOCAL_GOTIDX 0x70000026 -#define DT_MIPS_HIDDEN_GOTIDX 0x70000027 -#define DT_MIPS_PROTECTED_GOTIDX 0x70000028 -#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */ -#define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */ -#define DT_MIPS_DYNSTR_ALIGN 0x7000002b -#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */ -#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve - function stored in GOT. */ -#define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added - by rld on dlopen() calls. */ -#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */ -#define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */ -#define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */ -/* The address of .got.plt in an executable using the new non-PIC ABI. */ -#define DT_MIPS_PLTGOT 0x70000032 -/* The base of the PLT in an executable using the new non-PIC ABI if that - PLT is writable. For a non-writable PLT, this is omitted or has a zero - value. */ -#define DT_MIPS_RWPLT 0x70000034 -#define DT_MIPS_NUM 0x35 - -/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */ - -#define RHF_NONE 0 /* No flags */ -#define RHF_QUICKSTART (1 << 0) /* Use quickstart */ -#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */ -#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */ -#define RHF_NO_MOVE (1 << 3) -#define RHF_SGI_ONLY (1 << 4) -#define RHF_GUARANTEE_INIT (1 << 5) -#define RHF_DELTA_C_PLUS_PLUS (1 << 6) -#define RHF_GUARANTEE_START_INIT (1 << 7) -#define RHF_PIXIE (1 << 8) -#define RHF_DEFAULT_DELAY_LOAD (1 << 9) -#define RHF_REQUICKSTART (1 << 10) -#define RHF_REQUICKSTARTED (1 << 11) -#define RHF_CORD (1 << 12) -#define RHF_NO_UNRES_UNDEF (1 << 13) -#define RHF_RLD_ORDER_SAFE (1 << 14) - -/* Entries found in sections of type SHT_MIPS_LIBLIST. */ - -typedef struct -{ - Elf32_Word l_name; /* Name (string table index) */ - Elf32_Word l_time_stamp; /* Timestamp */ - Elf32_Word l_checksum; /* Checksum */ - Elf32_Word l_version; /* Interface version */ - Elf32_Word l_flags; /* Flags */ -} Elf32_Lib; - -typedef struct -{ - Elf64_Word l_name; /* Name (string table index) */ - Elf64_Word l_time_stamp; /* Timestamp */ - Elf64_Word l_checksum; /* Checksum */ - Elf64_Word l_version; /* Interface version */ - Elf64_Word l_flags; /* Flags */ -} Elf64_Lib; - - -/* Legal values for l_flags. */ - -#define LL_NONE 0 -#define LL_EXACT_MATCH (1 << 0) /* Require exact match */ -#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */ -#define LL_REQUIRE_MINOR (1 << 2) -#define LL_EXPORTS (1 << 3) -#define LL_DELAY_LOAD (1 << 4) -#define LL_DELTA (1 << 5) - -/* Entries found in sections of type SHT_MIPS_CONFLICT. */ - -typedef Elf32_Addr Elf32_Conflict; - - -/* HPPA specific definitions. */ - -/* Legal values for e_flags field of Elf32_Ehdr. */ - -#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */ -#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */ -#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */ -#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */ -#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch - prediction. */ -#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */ -#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */ - -/* Defined values for `e_flags & EF_PARISC_ARCH' are: */ - -#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */ -#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */ -#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */ - -/* Additional section indeces. */ - -#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared - symbols in ANSI C. */ -#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */ - -/* Legal values for sh_type field of Elf32_Shdr. */ - -#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */ -#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */ -#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */ - -/* Legal values for sh_flags field of Elf32_Shdr. */ - -#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */ -#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */ -#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */ - -/* Legal values for ST_TYPE subfield of st_info (symbol type). */ - -#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ - -#define STT_HP_OPAQUE (STT_LOOS + 0x1) -#define STT_HP_STUB (STT_LOOS + 0x2) - -/* HPPA relocs. */ - -#define R_PARISC_NONE 0 /* No reloc. */ -#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */ -#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */ -#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */ -#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */ -#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */ -#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */ -#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */ -#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */ -#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */ -#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */ -#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */ -#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */ -#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */ -#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */ -#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */ -#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */ -#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */ -#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */ -#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */ -#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */ -#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */ -#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */ -#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */ -#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */ -#define R_PARISC_FPTR64 64 /* 64 bits function address. */ -#define R_PARISC_PLABEL32 65 /* 32 bits function address. */ -#define R_PARISC_PLABEL21L 66 /* Left 21 bits of fdesc address. */ -#define R_PARISC_PLABEL14R 70 /* Right 14 bits of fdesc address. */ -#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */ -#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */ -#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */ -#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */ -#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */ -#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */ -#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */ -#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */ -#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */ -#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */ -#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */ -#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */ -#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */ -#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */ -#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */ -#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */ -#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */ -#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */ -#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */ -#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */ -#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */ -#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */ -#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */ -#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */ -#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */ -#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */ -#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */ -#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */ -#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */ -#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */ -#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */ -#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */ -#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */ -#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */ -#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */ -#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */ -#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */ -#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */ -#define R_PARISC_LORESERVE 128 -#define R_PARISC_COPY 128 /* Copy relocation. */ -#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */ -#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */ -#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */ -#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */ -#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */ -#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */ -#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/ -#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */ -#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */ -#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */ -#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */ -#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */ -#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */ -#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */ -#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */ -#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/ -#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/ -#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */ -#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */ -#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */ -#define R_PARISC_GNU_VTENTRY 232 -#define R_PARISC_GNU_VTINHERIT 233 -#define R_PARISC_TLS_GD21L 234 /* GD 21-bit left. */ -#define R_PARISC_TLS_GD14R 235 /* GD 14-bit right. */ -#define R_PARISC_TLS_GDCALL 236 /* GD call to __t_g_a. */ -#define R_PARISC_TLS_LDM21L 237 /* LD module 21-bit left. */ -#define R_PARISC_TLS_LDM14R 238 /* LD module 14-bit right. */ -#define R_PARISC_TLS_LDMCALL 239 /* LD module call to __t_g_a. */ -#define R_PARISC_TLS_LDO21L 240 /* LD offset 21-bit left. */ -#define R_PARISC_TLS_LDO14R 241 /* LD offset 14-bit right. */ -#define R_PARISC_TLS_DTPMOD32 242 /* DTP module 32-bit. */ -#define R_PARISC_TLS_DTPMOD64 243 /* DTP module 64-bit. */ -#define R_PARISC_TLS_DTPOFF32 244 /* DTP offset 32-bit. */ -#define R_PARISC_TLS_DTPOFF64 245 /* DTP offset 32-bit. */ -#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L -#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R -#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L -#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R -#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32 -#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64 -#define R_PARISC_HIRESERVE 255 - -/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ - -#define PT_HP_TLS (PT_LOOS + 0x0) -#define PT_HP_CORE_NONE (PT_LOOS + 0x1) -#define PT_HP_CORE_VERSION (PT_LOOS + 0x2) -#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3) -#define PT_HP_CORE_COMM (PT_LOOS + 0x4) -#define PT_HP_CORE_PROC (PT_LOOS + 0x5) -#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6) -#define PT_HP_CORE_STACK (PT_LOOS + 0x7) -#define PT_HP_CORE_SHM (PT_LOOS + 0x8) -#define PT_HP_CORE_MMF (PT_LOOS + 0x9) -#define PT_HP_PARALLEL (PT_LOOS + 0x10) -#define PT_HP_FASTBIND (PT_LOOS + 0x11) -#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12) -#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13) -#define PT_HP_STACK (PT_LOOS + 0x14) - -#define PT_PARISC_ARCHEXT 0x70000000 -#define PT_PARISC_UNWIND 0x70000001 - -/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */ - -#define PF_PARISC_SBP 0x08000000 - -#define PF_HP_PAGE_SIZE 0x00100000 -#define PF_HP_FAR_SHARED 0x00200000 -#define PF_HP_NEAR_SHARED 0x00400000 -#define PF_HP_CODE 0x01000000 -#define PF_HP_MODIFY 0x02000000 -#define PF_HP_LAZYSWAP 0x04000000 -#define PF_HP_SBP 0x08000000 - - -/* Alpha specific definitions. */ - -/* Legal values for e_flags field of Elf64_Ehdr. */ - -#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */ -#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */ - -/* Legal values for sh_type field of Elf64_Shdr. */ - -/* These two are primerily concerned with ECOFF debugging info. */ -#define SHT_ALPHA_DEBUG 0x70000001 -#define SHT_ALPHA_REGINFO 0x70000002 - -/* Legal values for sh_flags field of Elf64_Shdr. */ - -#define SHF_ALPHA_GPREL 0x10000000 - -/* Legal values for st_other field of Elf64_Sym. */ -#define STO_ALPHA_NOPV 0x80 /* No PV required. */ -#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */ - -/* Alpha relocs. */ - -#define R_ALPHA_NONE 0 /* No reloc */ -#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ -#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ -#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ -#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ -#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ -#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ -#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ -#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ -#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ -#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ -#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ -#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */ -#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */ -#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */ -#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ -#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ -#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ -#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ -#define R_ALPHA_TLS_GD_HI 28 -#define R_ALPHA_TLSGD 29 -#define R_ALPHA_TLS_LDM 30 -#define R_ALPHA_DTPMOD64 31 -#define R_ALPHA_GOTDTPREL 32 -#define R_ALPHA_DTPREL64 33 -#define R_ALPHA_DTPRELHI 34 -#define R_ALPHA_DTPRELLO 35 -#define R_ALPHA_DTPREL16 36 -#define R_ALPHA_GOTTPREL 37 -#define R_ALPHA_TPREL64 38 -#define R_ALPHA_TPRELHI 39 -#define R_ALPHA_TPRELLO 40 -#define R_ALPHA_TPREL16 41 -/* Keep this the last entry. */ -#define R_ALPHA_NUM 46 - -/* Magic values of the LITUSE relocation addend. */ -#define LITUSE_ALPHA_ADDR 0 -#define LITUSE_ALPHA_BASE 1 -#define LITUSE_ALPHA_BYTOFF 2 -#define LITUSE_ALPHA_JSR 3 -#define LITUSE_ALPHA_TLS_GD 4 -#define LITUSE_ALPHA_TLS_LDM 5 - -/* Legal values for d_tag of Elf64_Dyn. */ -#define DT_ALPHA_PLTRO (DT_LOPROC + 0) -#define DT_ALPHA_NUM 1 - -/* PowerPC specific declarations */ - -/* Values for Elf32/64_Ehdr.e_flags. */ -#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */ - -/* Cygnus local bits below */ -#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/ -#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib - flag */ - -/* PowerPC relocations defined by the ABIs */ -#define R_PPC_NONE 0 -#define R_PPC_ADDR32 1 /* 32bit absolute address */ -#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ -#define R_PPC_ADDR16 3 /* 16bit absolute address */ -#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ -#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ -#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ -#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ -#define R_PPC_ADDR14_BRTAKEN 8 -#define R_PPC_ADDR14_BRNTAKEN 9 -#define R_PPC_REL24 10 /* PC relative 26 bit */ -#define R_PPC_REL14 11 /* PC relative 16 bit */ -#define R_PPC_REL14_BRTAKEN 12 -#define R_PPC_REL14_BRNTAKEN 13 -#define R_PPC_GOT16 14 -#define R_PPC_GOT16_LO 15 -#define R_PPC_GOT16_HI 16 -#define R_PPC_GOT16_HA 17 -#define R_PPC_PLTREL24 18 -#define R_PPC_COPY 19 -#define R_PPC_GLOB_DAT 20 -#define R_PPC_JMP_SLOT 21 -#define R_PPC_RELATIVE 22 -#define R_PPC_LOCAL24PC 23 -#define R_PPC_UADDR32 24 -#define R_PPC_UADDR16 25 -#define R_PPC_REL32 26 -#define R_PPC_PLT32 27 -#define R_PPC_PLTREL32 28 -#define R_PPC_PLT16_LO 29 -#define R_PPC_PLT16_HI 30 -#define R_PPC_PLT16_HA 31 -#define R_PPC_SDAREL16 32 -#define R_PPC_SECTOFF 33 -#define R_PPC_SECTOFF_LO 34 -#define R_PPC_SECTOFF_HI 35 -#define R_PPC_SECTOFF_HA 36 - -/* PowerPC relocations defined for the TLS access ABI. */ -#define R_PPC_TLS 67 /* none (sym+add)@tls */ -#define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */ -#define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */ -#define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ -#define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ -#define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ -#define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */ -#define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */ -#define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ -#define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ -#define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ -#define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */ -#define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ -#define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ -#define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ -#define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ -#define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ -#define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ -#define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ -#define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ -#define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */ -#define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */ -#define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ -#define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ -#define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */ -#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */ -#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */ -#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */ - -/* The remaining relocs are from the Embedded ELF ABI, and are not - in the SVR4 ELF ABI. */ -#define R_PPC_EMB_NADDR32 101 -#define R_PPC_EMB_NADDR16 102 -#define R_PPC_EMB_NADDR16_LO 103 -#define R_PPC_EMB_NADDR16_HI 104 -#define R_PPC_EMB_NADDR16_HA 105 -#define R_PPC_EMB_SDAI16 106 -#define R_PPC_EMB_SDA2I16 107 -#define R_PPC_EMB_SDA2REL 108 -#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ -#define R_PPC_EMB_MRKREF 110 -#define R_PPC_EMB_RELSEC16 111 -#define R_PPC_EMB_RELST_LO 112 -#define R_PPC_EMB_RELST_HI 113 -#define R_PPC_EMB_RELST_HA 114 -#define R_PPC_EMB_BIT_FLD 115 -#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ - -/* Diab tool relocations. */ -#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ -#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ -#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ -#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ -#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ -#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ - -/* GNU extension to support local ifunc. */ -#define R_PPC_IRELATIVE 248 - -/* GNU relocs used in PIC code sequences. */ -#define R_PPC_REL16 249 /* half16 (sym+add-.) */ -#define R_PPC_REL16_LO 250 /* half16 (sym+add-.)@l */ -#define R_PPC_REL16_HI 251 /* half16 (sym+add-.)@h */ -#define R_PPC_REL16_HA 252 /* half16 (sym+add-.)@ha */ - -/* This is a phony reloc to handle any old fashioned TOC16 references - that may still be in object files. */ -#define R_PPC_TOC16 255 - -/* PowerPC specific values for the Dyn d_tag field. */ -#define DT_PPC_GOT (DT_LOPROC + 0) -#define DT_PPC_NUM 1 - -/* PowerPC64 relocations defined by the ABIs */ -#define R_PPC64_NONE R_PPC_NONE -#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address */ -#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned */ -#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address */ -#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of address */ -#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of address. */ -#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */ -#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned */ -#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN -#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN -#define R_PPC64_REL24 R_PPC_REL24 /* PC-rel. 26 bit, word aligned */ -#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit */ -#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN -#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN -#define R_PPC64_GOT16 R_PPC_GOT16 -#define R_PPC64_GOT16_LO R_PPC_GOT16_LO -#define R_PPC64_GOT16_HI R_PPC_GOT16_HI -#define R_PPC64_GOT16_HA R_PPC_GOT16_HA - -#define R_PPC64_COPY R_PPC_COPY -#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT -#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT -#define R_PPC64_RELATIVE R_PPC_RELATIVE - -#define R_PPC64_UADDR32 R_PPC_UADDR32 -#define R_PPC64_UADDR16 R_PPC_UADDR16 -#define R_PPC64_REL32 R_PPC_REL32 -#define R_PPC64_PLT32 R_PPC_PLT32 -#define R_PPC64_PLTREL32 R_PPC_PLTREL32 -#define R_PPC64_PLT16_LO R_PPC_PLT16_LO -#define R_PPC64_PLT16_HI R_PPC_PLT16_HI -#define R_PPC64_PLT16_HA R_PPC_PLT16_HA - -#define R_PPC64_SECTOFF R_PPC_SECTOFF -#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO -#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI -#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA -#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2 */ -#define R_PPC64_ADDR64 38 /* doubleword64 S + A */ -#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A) */ -#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A) */ -#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A) */ -#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A) */ -#define R_PPC64_UADDR64 43 /* doubleword64 S + A */ -#define R_PPC64_REL64 44 /* doubleword64 S + A - P */ -#define R_PPC64_PLT64 45 /* doubleword64 L + A */ -#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P */ -#define R_PPC64_TOC16 47 /* half16* S + A - .TOC */ -#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.) */ -#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.) */ -#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.) */ -#define R_PPC64_TOC 51 /* doubleword64 .TOC */ -#define R_PPC64_PLTGOT16 52 /* half16* M + A */ -#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A) */ -#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A) */ -#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A) */ - -#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2 */ -#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2 */ -#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2 */ -#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2 */ -#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2 */ -#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2 */ -#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2 */ -#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2 */ -#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2 */ -#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2 */ -#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2 */ - -/* PowerPC64 relocations defined for the TLS access ABI. */ -#define R_PPC64_TLS 67 /* none (sym+add)@tls */ -#define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */ -#define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */ -#define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ -#define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ -#define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ -#define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */ -#define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */ -#define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ -#define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ -#define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ -#define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */ -#define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ -#define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ -#define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ -#define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ -#define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ -#define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ -#define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ -#define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ -#define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */ -#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */ -#define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ -#define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ -#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */ -#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */ -#define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */ -#define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */ -#define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */ -#define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */ -#define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */ -#define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */ -#define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */ -#define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */ -#define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */ -#define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */ -#define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */ -#define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */ -#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */ -#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */ - -/* GNU extension to support local ifunc. */ -#define R_PPC64_JMP_IREL 247 -#define R_PPC64_IRELATIVE 248 -#define R_PPC64_REL16 249 /* half16 (sym+add-.) */ -#define R_PPC64_REL16_LO 250 /* half16 (sym+add-.)@l */ -#define R_PPC64_REL16_HI 251 /* half16 (sym+add-.)@h */ -#define R_PPC64_REL16_HA 252 /* half16 (sym+add-.)@ha */ - -/* PowerPC64 specific values for the Dyn d_tag field. */ -#define DT_PPC64_GLINK (DT_LOPROC + 0) -#define DT_PPC64_OPD (DT_LOPROC + 1) -#define DT_PPC64_OPDSZ (DT_LOPROC + 2) -#define DT_PPC64_NUM 3 - - -/* ARM specific declarations */ - -/* Processor specific flags for the ELF header e_flags field. */ -#define EF_ARM_RELEXEC 0x01 -#define EF_ARM_HASENTRY 0x02 -#define EF_ARM_INTERWORK 0x04 -#define EF_ARM_APCS_26 0x08 -#define EF_ARM_APCS_FLOAT 0x10 -#define EF_ARM_PIC 0x20 -#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */ -#define EF_ARM_NEW_ABI 0x80 -#define EF_ARM_OLD_ABI 0x100 -#define EF_ARM_SOFT_FLOAT 0x200 -#define EF_ARM_VFP_FLOAT 0x400 -#define EF_ARM_MAVERICK_FLOAT 0x800 - -#define EF_ARM_ABI_FLOAT_SOFT 0x200 /* NB conflicts with EF_ARM_SOFT_FLOAT */ -#define EF_ARM_ABI_FLOAT_HARD 0x400 /* NB conflicts with EF_ARM_VFP_FLOAT */ - - -/* Other constants defined in the ARM ELF spec. version B-01. */ -/* NB. These conflict with values defined above. */ -#define EF_ARM_SYMSARESORTED 0x04 -#define EF_ARM_DYNSYMSUSESEGIDX 0x08 -#define EF_ARM_MAPSYMSFIRST 0x10 -#define EF_ARM_EABIMASK 0XFF000000 - -/* Constants defined in AAELF. */ -#define EF_ARM_BE8 0x00800000 -#define EF_ARM_LE8 0x00400000 - -#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK) -#define EF_ARM_EABI_UNKNOWN 0x00000000 -#define EF_ARM_EABI_VER1 0x01000000 -#define EF_ARM_EABI_VER2 0x02000000 -#define EF_ARM_EABI_VER3 0x03000000 -#define EF_ARM_EABI_VER4 0x04000000 -#define EF_ARM_EABI_VER5 0x05000000 - -/* Additional symbol types for Thumb. */ -#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */ -#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */ - -/* ARM-specific values for sh_flags */ -#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ -#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined - in the input to a link step. */ - -/* ARM-specific program header flags */ -#define PF_ARM_SB 0x10000000 /* Segment contains the location - addressed by the static base. */ -#define PF_ARM_PI 0x20000000 /* Position-independent segment. */ -#define PF_ARM_ABS 0x40000000 /* Absolute segment. */ - -/* Processor specific values for the Phdr p_type field. */ -#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */ - -/* Processor specific values for the Shdr sh_type field. */ -#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */ -#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */ -#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */ - - -/* AArch64 relocs. */ - -#define R_AARCH64_NONE 0 /* No relocation. */ -#define R_AARCH64_ABS64 257 /* Direct 64 bit. */ -#define R_AARCH64_ABS32 258 /* Direct 32 bit. */ -#define R_AARCH64_ABS16 259 /* Direct 16-bit. */ -#define R_AARCH64_PREL64 260 /* PC-relative 64-bit. */ -#define R_AARCH64_PREL32 261 /* PC-relative 32-bit. */ -#define R_AARCH64_PREL16 262 /* PC-relative 16-bit. */ -#define R_AARCH64_MOVW_UABS_G0 263 /* Dir. MOVZ imm. from bits 15:0. */ -#define R_AARCH64_MOVW_UABS_G0_NC 264 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_UABS_G1 265 /* Dir. MOVZ imm. from bits 31:16. */ -#define R_AARCH64_MOVW_UABS_G1_NC 266 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_UABS_G2 267 /* Dir. MOVZ imm. from bits 47:32. */ -#define R_AARCH64_MOVW_UABS_G2_NC 268 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_UABS_G3 269 /* Dir. MOV{K,Z} imm. from 63:48. */ -#define R_AARCH64_MOVW_SABS_G0 270 /* Dir. MOV{N,Z} imm. from 15:0. */ -#define R_AARCH64_MOVW_SABS_G1 271 /* Dir. MOV{N,Z} imm. from 31:16. */ -#define R_AARCH64_MOVW_SABS_G2 272 /* Dir. MOV{N,Z} imm. from 47:32. */ -#define R_AARCH64_LD_PREL_LO19 273 /* PC-rel. LD imm. from bits 20:2. */ -#define R_AARCH64_ADR_PREL_LO21 274 /* PC-rel. ADR imm. from bits 20:0. */ -#define R_AARCH64_ADR_PREL_PG_HI21 275 /* Page-rel. ADRP imm. from 32:12. */ -#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 /* Likewise; no overflow check. */ -#define R_AARCH64_ADD_ABS_LO12_NC 277 /* Dir. ADD imm. from bits 11:0. */ -#define R_AARCH64_LDST8_ABS_LO12_NC 278 /* Likewise for LD/ST; no check. */ -#define R_AARCH64_TSTBR14 279 /* PC-rel. TBZ/TBNZ imm. from 15:2. */ -#define R_AARCH64_CONDBR19 280 /* PC-rel. cond. br. imm. from 20:2. */ -#define R_AARCH64_JUMP26 282 /* PC-rel. B imm. from bits 27:2. */ -#define R_AARCH64_CALL26 283 /* Likewise for CALL. */ -#define R_AARCH64_LDST16_ABS_LO12_NC 284 /* Dir. ADD imm. from bits 11:1. */ -#define R_AARCH64_LDST32_ABS_LO12_NC 285 /* Likewise for bits 11:2. */ -#define R_AARCH64_LDST64_ABS_LO12_NC 286 /* Likewise for bits 11:3. */ -#define R_AARCH64_MOVW_PREL_G0 287 /* PC-rel. MOV{N,Z} imm. from 15:0. */ -#define R_AARCH64_MOVW_PREL_G0_NC 288 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_PREL_G1 289 /* PC-rel. MOV{N,Z} imm. from 31:16. */ -#define R_AARCH64_MOVW_PREL_G1_NC 290 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_PREL_G2 291 /* PC-rel. MOV{N,Z} imm. from 47:32. */ -#define R_AARCH64_MOVW_PREL_G2_NC 292 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_PREL_G3 293 /* PC-rel. MOV{N,Z} imm. from 63:48. */ -#define R_AARCH64_LDST128_ABS_LO12_NC 299 /* Dir. ADD imm. from bits 11:4. */ -#define R_AARCH64_MOVW_GOTOFF_G0 300 /* GOT-rel. off. MOV{N,Z} imm. 15:0. */ -#define R_AARCH64_MOVW_GOTOFF_G0_NC 301 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_GOTOFF_G1 302 /* GOT-rel. o. MOV{N,Z} imm. 31:16. */ -#define R_AARCH64_MOVW_GOTOFF_G1_NC 303 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_GOTOFF_G2 304 /* GOT-rel. o. MOV{N,Z} imm. 47:32. */ -#define R_AARCH64_MOVW_GOTOFF_G2_NC 305 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_GOTOFF_G3 306 /* GOT-rel. o. MOV{N,Z} imm. 63:48. */ -#define R_AARCH64_GOTREL64 307 /* GOT-relative 64-bit. */ -#define R_AARCH64_GOTREL32 308 /* GOT-relative 32-bit. */ -#define R_AARCH64_GOT_LD_PREL19 309 /* PC-rel. GOT off. load imm. 20:2. */ -#define R_AARCH64_LD64_GOTOFF_LO15 310 /* GOT-rel. off. LD/ST imm. 14:3. */ -#define R_AARCH64_ADR_GOT_PAGE 311 /* P-page-rel. GOT off. ADRP 32:12. */ -#define R_AARCH64_LD64_GOT_LO12_NC 312 /* Dir. GOT off. LD/ST imm. 11:3. */ -#define R_AARCH64_LD64_GOTPAGE_LO15 313 /* GOT-page-rel. GOT off. LD/ST 14:3 */ -#define R_AARCH64_TLSGD_ADR_PREL21 512 /* PC-relative ADR imm. 20:0. */ -#define R_AARCH64_TLSGD_ADR_PAGE21 513 /* page-rel. ADRP imm. 32:12. */ -#define R_AARCH64_TLSGD_ADD_LO12_NC 514 /* direct ADD imm. from 11:0. */ -#define R_AARCH64_TLSGD_MOVW_G1 515 /* GOT-rel. MOV{N,Z} 31:16. */ -#define R_AARCH64_TLSGD_MOVW_G0_NC 516 /* GOT-rel. MOVK imm. 15:0. */ -#define R_AARCH64_TLSLD_ADR_PREL21 517 /* Like 512; local dynamic model. */ -#define R_AARCH64_TLSLD_ADR_PAGE21 518 /* Like 513; local dynamic model. */ -#define R_AARCH64_TLSLD_ADD_LO12_NC 519 /* Like 514; local dynamic model. */ -#define R_AARCH64_TLSLD_MOVW_G1 520 /* Like 515; local dynamic model. */ -#define R_AARCH64_TLSLD_MOVW_G0_NC 521 /* Like 516; local dynamic model. */ -#define R_AARCH64_TLSLD_LD_PREL19 522 /* TLS PC-rel. load imm. 20:2. */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 /* TLS DTP-rel. MOV{N,Z} 47:32. */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 /* TLS DTP-rel. MOV{N,Z} 31:16. */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 /* Likewise; MOVK; no check. */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 /* TLS DTP-rel. MOV{N,Z} 15:0. */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 /* Likewise; MOVK; no check. */ -#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 /* DTP-rel. ADD imm. from 23:12. */ -#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 /* DTP-rel. ADD imm. from 11:0. */ -#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 /* Likewise; no ovfl. check. */ -#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 /* DTP-rel. LD/ST imm. 11:0. */ -#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 /* Likewise; no check. */ -#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 /* DTP-rel. LD/ST imm. 11:1. */ -#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 /* Likewise; no check. */ -#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 /* DTP-rel. LD/ST imm. 11:2. */ -#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 /* Likewise; no check. */ -#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 /* DTP-rel. LD/ST imm. 11:3. */ -#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 /* Likewise; no check. */ -#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 /* GOT-rel. MOV{N,Z} 31:16. */ -#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 /* GOT-rel. MOVK 15:0. */ -#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 /* Page-rel. ADRP 32:12. */ -#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 /* Direct LD off. 11:3. */ -#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 /* PC-rel. load imm. 20:2. */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 /* TLS TP-rel. MOV{N,Z} 47:32. */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 /* TLS TP-rel. MOV{N,Z} 31:16. */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 /* Likewise; MOVK; no check. */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 /* TLS TP-rel. MOV{N,Z} 15:0. */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 /* Likewise; MOVK; no check. */ -#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 /* TP-rel. ADD imm. 23:12. */ -#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 /* TP-rel. ADD imm. 11:0. */ -#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 /* Likewise; no ovfl. check. */ -#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 /* TP-rel. LD/ST off. 11:0. */ -#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 /* Likewise; no ovfl. check. */ -#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 /* TP-rel. LD/ST off. 11:1. */ -#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 /* Likewise; no check. */ -#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 /* TP-rel. LD/ST off. 11:2. */ -#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 /* Likewise; no check. */ -#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 /* TP-rel. LD/ST off. 11:3. */ -#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 /* Likewise; no check. */ -#define R_AARCH64_TLSDESC_LD_PREL19 560 /* PC-rel. load immediate 20:2. */ -#define R_AARCH64_TLSDESC_ADR_PREL21 561 /* PC-rel. ADR immediate 20:0. */ -#define R_AARCH64_TLSDESC_ADR_PAGE21 562 /* Page-rel. ADRP imm. 32:12. */ -#define R_AARCH64_TLSDESC_LD64_LO12 563 /* Direct LD off. from 11:3. */ -#define R_AARCH64_TLSDESC_ADD_LO12 564 /* Direct ADD imm. from 11:0. */ -#define R_AARCH64_TLSDESC_OFF_G1 565 /* GOT-rel. MOV{N,Z} imm. 31:16. */ -#define R_AARCH64_TLSDESC_OFF_G0_NC 566 /* GOT-rel. MOVK imm. 15:0; no ck. */ -#define R_AARCH64_TLSDESC_LDR 567 /* Relax LDR. */ -#define R_AARCH64_TLSDESC_ADD 568 /* Relax ADD. */ -#define R_AARCH64_TLSDESC_CALL 569 /* Relax BLR. */ -#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570 /* TP-rel. LD/ST off. 11:4. */ -#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571 /* Likewise; no check. */ -#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572 /* DTP-rel. LD/ST imm. 11:4. */ -#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573 /* Likewise; no check. */ -#define R_AARCH64_COPY 1024 /* Copy symbol at runtime. */ -#define R_AARCH64_GLOB_DAT 1025 /* Create GOT entry. */ -#define R_AARCH64_JUMP_SLOT 1026 /* Create PLT entry. */ -#define R_AARCH64_RELATIVE 1027 /* Adjust by program base. */ -#define R_AARCH64_TLS_DTPMOD64 1028 /* Module number, 64 bit. */ -#define R_AARCH64_TLS_DTPREL64 1029 /* Module-relative offset, 64 bit. */ -#define R_AARCH64_TLS_TPREL64 1030 /* TP-relative offset, 64 bit. */ -#define R_AARCH64_TLSDESC 1031 /* TLS Descriptor. */ -#define R_AARCH64_IRELATIVE 1032 /* STT_GNU_IFUNC relocation. */ - -/* ARM relocs. */ - -#define R_ARM_NONE 0 /* No reloc */ -#define R_ARM_PC24 1 /* PC relative 26 bit branch */ -#define R_ARM_ABS32 2 /* Direct 32 bit */ -#define R_ARM_REL32 3 /* PC relative 32 bit */ -#define R_ARM_PC13 4 -#define R_ARM_ABS16 5 /* Direct 16 bit */ -#define R_ARM_ABS12 6 /* Direct 12 bit */ -#define R_ARM_THM_ABS5 7 -#define R_ARM_ABS8 8 /* Direct 8 bit */ -#define R_ARM_SBREL32 9 -#define R_ARM_THM_PC22 10 -#define R_ARM_THM_PC8 11 -#define R_ARM_AMP_VCALL9 12 -#define R_ARM_SWI24 13 /* Obsolete static relocation. */ -#define R_ARM_TLS_DESC 13 /* Dynamic relocation. */ -#define R_ARM_THM_SWI8 14 -#define R_ARM_XPC25 15 -#define R_ARM_THM_XPC22 16 -#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */ -#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */ -#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */ -#define R_ARM_COPY 20 /* Copy symbol at runtime */ -#define R_ARM_GLOB_DAT 21 /* Create GOT entry */ -#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ -#define R_ARM_RELATIVE 23 /* Adjust by program base */ -#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */ -#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */ -#define R_ARM_GOT32 26 /* 32 bit GOT entry */ -#define R_ARM_PLT32 27 /* 32 bit PLT address */ -#define R_ARM_CALL 28 -#define R_ARM_JUMP24 29 -#define R_ARM_THM_JUMP24 30 -#define R_ARM_ALU_PCREL_7_0 32 -#define R_ARM_ALU_PCREL_15_8 33 -#define R_ARM_ALU_PCREL_23_15 34 -#define R_ARM_LDR_SBREL_11_0 35 -#define R_ARM_ALU_SBREL_19_12 36 -#define R_ARM_ALU_SBREL_27_20 37 -#define R_ARM_V4BX 40 -#define R_ARM_PREL31 42 -#define R_ARM_MOVW_ABS_NC 43 -#define R_ARM_MOVT_ABS 44 -#define R_ARM_THM_MOVW_ABS_NC 47 -#define R_ARM_THM_MOVT_ABS 48 -#define R_ARM_TLS_GOTDESC 90 -#define R_ARM_TLS_CALL 91 -#define R_ARM_TLS_DESCSEQ 92 -#define R_ARM_THM_TLS_CALL 93 -#define R_ARM_GNU_VTENTRY 100 -#define R_ARM_GNU_VTINHERIT 101 -#define R_ARM_THM_PC11 102 /* thumb unconditional branch */ -#define R_ARM_THM_PC9 103 /* thumb conditional branch */ -#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic - thread local data */ -#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic - thread local data */ -#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS - block */ -#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of - static TLS block offset */ -#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static - TLS block */ -#define R_ARM_THM_TLS_DESCSEQ 129 -#define R_ARM_IRELATIVE 160 -#define R_ARM_RXPC25 249 -#define R_ARM_RSBREL32 250 -#define R_ARM_THM_RPC22 251 -#define R_ARM_RREL32 252 -#define R_ARM_RABS22 253 -#define R_ARM_RPC24 254 -#define R_ARM_RBASE 255 -/* Keep this the last entry. */ -#define R_ARM_NUM 256 - -/* TMS320C67xx specific declarations */ - -/* XXX: no ELF standard yet*/ - -/* TMS320C67xx relocs. */ -#define R_C60_32 1 -#define R_C60_GOT32 3 /* 32 bit GOT entry */ -#define R_C60_PLT32 4 /* 32 bit PLT address */ -#define R_C60_COPY 5 /* Copy symbol at runtime */ -#define R_C60_GLOB_DAT 6 /* Create GOT entry */ -#define R_C60_JMP_SLOT 7 /* Create PLT entry */ -#define R_C60_RELATIVE 8 /* Adjust by program base */ -#define R_C60_GOTOFF 9 /* 32 bit offset to GOT */ -#define R_C60_GOTPC 10 /* 32 bit PC relative offset to GOT */ - -#define R_C60HI16 0x55 /* high 16 bit MVKH embedded */ -#define R_C60LO16 0x54 /* low 16 bit MVKL embedded */ - -/* IA-64 specific declarations. */ - -/* Processor specific flags for the Ehdr e_flags field. */ -#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */ -#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */ -#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */ - -/* Processor specific values for the Phdr p_type field. */ -#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */ -#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */ -#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12) -#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13) -#define PT_IA_64_HP_STACK (PT_LOOS + 0x14) - -/* Processor specific flags for the Phdr p_flags field. */ -#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */ - -/* Processor specific values for the Shdr sh_type field. */ -#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */ -#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */ - -/* Processor specific flags for the Shdr sh_flags field. */ -#define SHF_IA_64_SHORT 0x10000000 /* section near gp */ -#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */ - -/* Processor specific values for the Dyn d_tag field. */ -#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0) -#define DT_IA_64_NUM 1 - -/* IA-64 relocations. */ -#define R_IA64_NONE 0x00 /* none */ -#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */ -#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */ -#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */ -#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */ -#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */ -#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */ -#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */ -#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */ -#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */ -#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */ -#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */ -#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */ -#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */ -#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */ -#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */ -#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */ -#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */ -#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */ -#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */ -#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */ -#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */ -#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */ -#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */ -#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */ -#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */ -#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */ -#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */ -#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */ -#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */ -#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */ -#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */ -#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */ -#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */ -#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */ -#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */ -#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */ -#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */ -#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */ -#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */ -#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */ -#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */ -#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */ -#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */ -#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */ -#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */ -#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */ -#define R_IA64_REL32MSB 0x6c /* data 4 + REL */ -#define R_IA64_REL32LSB 0x6d /* data 4 + REL */ -#define R_IA64_REL64MSB 0x6e /* data 8 + REL */ -#define R_IA64_REL64LSB 0x6f /* data 8 + REL */ -#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */ -#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */ -#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */ -#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */ -#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */ -#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */ -#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */ -#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */ -#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */ -#define R_IA64_COPY 0x84 /* copy relocation */ -#define R_IA64_SUB 0x85 /* Addend and symbol difference */ -#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */ -#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */ -#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */ -#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */ -#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */ -#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */ -#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */ -#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */ -#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */ -#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */ -#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */ -#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */ -#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */ -#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */ -#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */ -#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */ -#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */ -#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */ -#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */ - -/* SH specific declarations */ - -/* Processor specific flags for the ELF header e_flags field. */ -#define EF_SH_MACH_MASK 0x1f -#define EF_SH_UNKNOWN 0x0 -#define EF_SH1 0x1 -#define EF_SH2 0x2 -#define EF_SH3 0x3 -#define EF_SH_DSP 0x4 -#define EF_SH3_DSP 0x5 -#define EF_SH4AL_DSP 0x6 -#define EF_SH3E 0x8 -#define EF_SH4 0x9 -#define EF_SH2E 0xb -#define EF_SH4A 0xc -#define EF_SH2A 0xd -#define EF_SH4_NOFPU 0x10 -#define EF_SH4A_NOFPU 0x11 -#define EF_SH4_NOMMU_NOFPU 0x12 -#define EF_SH2A_NOFPU 0x13 -#define EF_SH3_NOMMU 0x14 -#define EF_SH2A_SH4_NOFPU 0x15 -#define EF_SH2A_SH3_NOFPU 0x16 -#define EF_SH2A_SH4 0x17 -#define EF_SH2A_SH3E 0x18 - -/* SH relocs. */ -#define R_SH_NONE 0 -#define R_SH_DIR32 1 -#define R_SH_REL32 2 -#define R_SH_DIR8WPN 3 -#define R_SH_IND12W 4 -#define R_SH_DIR8WPL 5 -#define R_SH_DIR8WPZ 6 -#define R_SH_DIR8BP 7 -#define R_SH_DIR8W 8 -#define R_SH_DIR8L 9 -#define R_SH_SWITCH16 25 -#define R_SH_SWITCH32 26 -#define R_SH_USES 27 -#define R_SH_COUNT 28 -#define R_SH_ALIGN 29 -#define R_SH_CODE 30 -#define R_SH_DATA 31 -#define R_SH_LABEL 32 -#define R_SH_SWITCH8 33 -#define R_SH_GNU_VTINHERIT 34 -#define R_SH_GNU_VTENTRY 35 -#define R_SH_TLS_GD_32 144 -#define R_SH_TLS_LD_32 145 -#define R_SH_TLS_LDO_32 146 -#define R_SH_TLS_IE_32 147 -#define R_SH_TLS_LE_32 148 -#define R_SH_TLS_DTPMOD32 149 -#define R_SH_TLS_DTPOFF32 150 -#define R_SH_TLS_TPOFF32 151 -#define R_SH_GOT32 160 -#define R_SH_PLT32 161 -#define R_SH_COPY 162 -#define R_SH_GLOB_DAT 163 -#define R_SH_JMP_SLOT 164 -#define R_SH_RELATIVE 165 -#define R_SH_GOTOFF 166 -#define R_SH_GOTPC 167 -/* Keep this the last entry. */ -#define R_SH_NUM 256 - -/* S/390 specific definitions. */ - -/* Valid values for the e_flags field. */ - -#define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. */ - -/* Additional s390 relocs */ - -#define R_390_NONE 0 /* No reloc. */ -#define R_390_8 1 /* Direct 8 bit. */ -#define R_390_12 2 /* Direct 12 bit. */ -#define R_390_16 3 /* Direct 16 bit. */ -#define R_390_32 4 /* Direct 32 bit. */ -#define R_390_PC32 5 /* PC relative 32 bit. */ -#define R_390_GOT12 6 /* 12 bit GOT offset. */ -#define R_390_GOT32 7 /* 32 bit GOT offset. */ -#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */ -#define R_390_COPY 9 /* Copy symbol at runtime. */ -#define R_390_GLOB_DAT 10 /* Create GOT entry. */ -#define R_390_JMP_SLOT 11 /* Create PLT entry. */ -#define R_390_RELATIVE 12 /* Adjust by program base. */ -#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */ -#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */ -#define R_390_GOT16 15 /* 16 bit GOT offset. */ -#define R_390_PC16 16 /* PC relative 16 bit. */ -#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */ -#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */ -#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */ -#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */ -#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */ -#define R_390_64 22 /* Direct 64 bit. */ -#define R_390_PC64 23 /* PC relative 64 bit. */ -#define R_390_GOT64 24 /* 64 bit GOT offset. */ -#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */ -#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */ -#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */ -#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */ -#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */ -#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */ -#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */ -#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */ -#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */ -#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */ -#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */ -#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */ -#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */ -#define R_390_TLS_GDCALL 38 /* Tag for function call in general - dynamic TLS code. */ -#define R_390_TLS_LDCALL 39 /* Tag for function call in local - dynamic TLS code. */ -#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic - thread local data. */ -#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic - thread local data. */ -#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS - block offset. */ -#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS - block offset. */ -#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS - block offset. */ -#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic - thread local data in LE code. */ -#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic - thread local data in LE code. */ -#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for - negated static TLS block offset. */ -#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for - negated static TLS block offset. */ -#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for - negated static TLS block offset. */ -#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to - static TLS block. */ -#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to - static TLS block. */ -#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS - block. */ -#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS - block. */ -#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */ -#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */ -#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS - block. */ -#define R_390_20 57 /* Direct 20 bit. */ -#define R_390_GOT20 58 /* 20 bit GOT offset. */ -#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */ -#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS - block offset. */ -#define R_390_IRELATIVE 61 /* STT_GNU_IFUNC relocation. */ -/* Keep this the last entry. */ -#define R_390_NUM 62 - - -/* CRIS relocations. */ -#define R_CRIS_NONE 0 -#define R_CRIS_8 1 -#define R_CRIS_16 2 -#define R_CRIS_32 3 -#define R_CRIS_8_PCREL 4 -#define R_CRIS_16_PCREL 5 -#define R_CRIS_32_PCREL 6 -#define R_CRIS_GNU_VTINHERIT 7 -#define R_CRIS_GNU_VTENTRY 8 -#define R_CRIS_COPY 9 -#define R_CRIS_GLOB_DAT 10 -#define R_CRIS_JUMP_SLOT 11 -#define R_CRIS_RELATIVE 12 -#define R_CRIS_16_GOT 13 -#define R_CRIS_32_GOT 14 -#define R_CRIS_16_GOTPLT 15 -#define R_CRIS_32_GOTPLT 16 -#define R_CRIS_32_GOTREL 17 -#define R_CRIS_32_PLT_GOTREL 18 -#define R_CRIS_32_PLT_PCREL 19 - -#define R_CRIS_NUM 20 - - -/* AMD x86-64 relocations. */ -#define R_X86_64_NONE 0 /* No reloc */ -#define R_X86_64_64 1 /* Direct 64 bit */ -#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ -#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ -#define R_X86_64_PLT32 4 /* 32 bit PLT address */ -#define R_X86_64_COPY 5 /* Copy symbol at runtime */ -#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ -#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ -#define R_X86_64_RELATIVE 8 /* Adjust by program base */ -#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative - offset to GOT */ -#define R_X86_64_32 10 /* Direct 32 bit zero extended */ -#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ -#define R_X86_64_16 12 /* Direct 16 bit zero extended */ -#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ -#define R_X86_64_8 14 /* Direct 8 bit sign extended */ -#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ -#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ -#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */ -#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */ -#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset - to two GOT entries for GD symbol */ -#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset - to two GOT entries for LD symbol */ -#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ -#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset - to GOT entry for IE symbol */ -#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */ -#define R_X86_64_PC64 24 /* PC relative 64 bit */ -#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */ -#define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative - offset to GOT */ -#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */ -#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset - to GOT entry */ -#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */ -#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */ -#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset - to PLT entry */ -#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */ -#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */ -#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */ -#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS - descriptor. */ -#define R_X86_64_TLSDESC 36 /* TLS descriptor. */ -#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */ -#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */ -#define R_X86_64_GOTPCRELX 41 /* like GOTPCREL, but optionally with - linker optimizations */ -#define R_X86_64_REX_GOTPCRELX 42 /* like GOTPCRELX, but a REX prefix - is present */ - -#define R_X86_64_NUM 39 - - -/* AM33 relocations. */ -#define R_MN10300_NONE 0 /* No reloc. */ -#define R_MN10300_32 1 /* Direct 32 bit. */ -#define R_MN10300_16 2 /* Direct 16 bit. */ -#define R_MN10300_8 3 /* Direct 8 bit. */ -#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */ -#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */ -#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */ -#define R_MN10300_GNU_VTINHERIT 7 /* Ancient C++ vtable garbage... */ -#define R_MN10300_GNU_VTENTRY 8 /* ... collection annotation. */ -#define R_MN10300_24 9 /* Direct 24 bit. */ -#define R_MN10300_GOTPC32 10 /* 32-bit PCrel offset to GOT. */ -#define R_MN10300_GOTPC16 11 /* 16-bit PCrel offset to GOT. */ -#define R_MN10300_GOTOFF32 12 /* 32-bit offset from GOT. */ -#define R_MN10300_GOTOFF24 13 /* 24-bit offset from GOT. */ -#define R_MN10300_GOTOFF16 14 /* 16-bit offset from GOT. */ -#define R_MN10300_PLT32 15 /* 32-bit PCrel to PLT entry. */ -#define R_MN10300_PLT16 16 /* 16-bit PCrel to PLT entry. */ -#define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */ -#define R_MN10300_GOT24 18 /* 24-bit offset to GOT entry. */ -#define R_MN10300_GOT16 19 /* 16-bit offset to GOT entry. */ -#define R_MN10300_COPY 20 /* Copy symbol at runtime. */ -#define R_MN10300_GLOB_DAT 21 /* Create GOT entry. */ -#define R_MN10300_JMP_SLOT 22 /* Create PLT entry. */ -#define R_MN10300_RELATIVE 23 /* Adjust by program base. */ -#define R_MN10300_TLS_GD 24 /* 32-bit offset for global dynamic. */ -#define R_MN10300_TLS_LD 25 /* 32-bit offset for local dynamic. */ -#define R_MN10300_TLS_LDO 26 /* Module-relative offset. */ -#define R_MN10300_TLS_GOTIE 27 /* GOT offset for static TLS block - offset. */ -#define R_MN10300_TLS_IE 28 /* GOT address for static TLS block - offset. */ -#define R_MN10300_TLS_LE 29 /* Offset relative to static TLS - block. */ -#define R_MN10300_TLS_DTPMOD 30 /* ID of module containing symbol. */ -#define R_MN10300_TLS_DTPOFF 31 /* Offset in module TLS block. */ -#define R_MN10300_TLS_TPOFF 32 /* Offset in static TLS block. */ -#define R_MN10300_SYM_DIFF 33 /* Adjustment for next reloc as needed - by linker relaxation. */ -#define R_MN10300_ALIGN 34 /* Alignment requirement for linker - relaxation. */ -#define R_MN10300_NUM 35 - - -/* M32R relocs. */ -#define R_M32R_NONE 0 /* No reloc. */ -#define R_M32R_16 1 /* Direct 16 bit. */ -#define R_M32R_32 2 /* Direct 32 bit. */ -#define R_M32R_24 3 /* Direct 24 bit. */ -#define R_M32R_10_PCREL 4 /* PC relative 10 bit shifted. */ -#define R_M32R_18_PCREL 5 /* PC relative 18 bit shifted. */ -#define R_M32R_26_PCREL 6 /* PC relative 26 bit shifted. */ -#define R_M32R_HI16_ULO 7 /* High 16 bit with unsigned low. */ -#define R_M32R_HI16_SLO 8 /* High 16 bit with signed low. */ -#define R_M32R_LO16 9 /* Low 16 bit. */ -#define R_M32R_SDA16 10 /* 16 bit offset in SDA. */ -#define R_M32R_GNU_VTINHERIT 11 -#define R_M32R_GNU_VTENTRY 12 -/* M32R relocs use SHT_RELA. */ -#define R_M32R_16_RELA 33 /* Direct 16 bit. */ -#define R_M32R_32_RELA 34 /* Direct 32 bit. */ -#define R_M32R_24_RELA 35 /* Direct 24 bit. */ -#define R_M32R_10_PCREL_RELA 36 /* PC relative 10 bit shifted. */ -#define R_M32R_18_PCREL_RELA 37 /* PC relative 18 bit shifted. */ -#define R_M32R_26_PCREL_RELA 38 /* PC relative 26 bit shifted. */ -#define R_M32R_HI16_ULO_RELA 39 /* High 16 bit with unsigned low */ -#define R_M32R_HI16_SLO_RELA 40 /* High 16 bit with signed low */ -#define R_M32R_LO16_RELA 41 /* Low 16 bit */ -#define R_M32R_SDA16_RELA 42 /* 16 bit offset in SDA */ -#define R_M32R_RELA_GNU_VTINHERIT 43 -#define R_M32R_RELA_GNU_VTENTRY 44 -#define R_M32R_REL32 45 /* PC relative 32 bit. */ - -#define R_M32R_GOT24 48 /* 24 bit GOT entry */ -#define R_M32R_26_PLTREL 49 /* 26 bit PC relative to PLT shifted */ -#define R_M32R_COPY 50 /* Copy symbol at runtime */ -#define R_M32R_GLOB_DAT 51 /* Create GOT entry */ -#define R_M32R_JMP_SLOT 52 /* Create PLT entry */ -#define R_M32R_RELATIVE 53 /* Adjust by program base */ -#define R_M32R_GOTOFF 54 /* 24 bit offset to GOT */ -#define R_M32R_GOTPC24 55 /* 24 bit PC relative offset to GOT */ -#define R_M32R_GOT16_HI_ULO 56 /* High 16 bit GOT entry with unsigned - low */ -#define R_M32R_GOT16_HI_SLO 57 /* High 16 bit GOT entry with signed - low */ -#define R_M32R_GOT16_LO 58 /* Low 16 bit GOT entry */ -#define R_M32R_GOTPC_HI_ULO 59 /* High 16 bit PC relative offset to - GOT with unsigned low */ -#define R_M32R_GOTPC_HI_SLO 60 /* High 16 bit PC relative offset to - GOT with signed low */ -#define R_M32R_GOTPC_LO 61 /* Low 16 bit PC relative offset to - GOT */ -#define R_M32R_GOTOFF_HI_ULO 62 /* High 16 bit offset to GOT - with unsigned low */ -#define R_M32R_GOTOFF_HI_SLO 63 /* High 16 bit offset to GOT - with signed low */ -#define R_M32R_GOTOFF_LO 64 /* Low 16 bit offset to GOT */ -#define R_M32R_NUM 256 /* Keep this the last entry. */ - - -/* TILEPro relocations. */ -#define R_TILEPRO_NONE 0 /* No reloc */ -#define R_TILEPRO_32 1 /* Direct 32 bit */ -#define R_TILEPRO_16 2 /* Direct 16 bit */ -#define R_TILEPRO_8 3 /* Direct 8 bit */ -#define R_TILEPRO_32_PCREL 4 /* PC relative 32 bit */ -#define R_TILEPRO_16_PCREL 5 /* PC relative 16 bit */ -#define R_TILEPRO_8_PCREL 6 /* PC relative 8 bit */ -#define R_TILEPRO_LO16 7 /* Low 16 bit */ -#define R_TILEPRO_HI16 8 /* High 16 bit */ -#define R_TILEPRO_HA16 9 /* High 16 bit, adjusted */ -#define R_TILEPRO_COPY 10 /* Copy relocation */ -#define R_TILEPRO_GLOB_DAT 11 /* Create GOT entry */ -#define R_TILEPRO_JMP_SLOT 12 /* Create PLT entry */ -#define R_TILEPRO_RELATIVE 13 /* Adjust by program base */ -#define R_TILEPRO_BROFF_X1 14 /* X1 pipe branch offset */ -#define R_TILEPRO_JOFFLONG_X1 15 /* X1 pipe jump offset */ -#define R_TILEPRO_JOFFLONG_X1_PLT 16 /* X1 pipe jump offset to PLT */ -#define R_TILEPRO_IMM8_X0 17 /* X0 pipe 8-bit */ -#define R_TILEPRO_IMM8_Y0 18 /* Y0 pipe 8-bit */ -#define R_TILEPRO_IMM8_X1 19 /* X1 pipe 8-bit */ -#define R_TILEPRO_IMM8_Y1 20 /* Y1 pipe 8-bit */ -#define R_TILEPRO_MT_IMM15_X1 21 /* X1 pipe mtspr */ -#define R_TILEPRO_MF_IMM15_X1 22 /* X1 pipe mfspr */ -#define R_TILEPRO_IMM16_X0 23 /* X0 pipe 16-bit */ -#define R_TILEPRO_IMM16_X1 24 /* X1 pipe 16-bit */ -#define R_TILEPRO_IMM16_X0_LO 25 /* X0 pipe low 16-bit */ -#define R_TILEPRO_IMM16_X1_LO 26 /* X1 pipe low 16-bit */ -#define R_TILEPRO_IMM16_X0_HI 27 /* X0 pipe high 16-bit */ -#define R_TILEPRO_IMM16_X1_HI 28 /* X1 pipe high 16-bit */ -#define R_TILEPRO_IMM16_X0_HA 29 /* X0 pipe high 16-bit, adjusted */ -#define R_TILEPRO_IMM16_X1_HA 30 /* X1 pipe high 16-bit, adjusted */ -#define R_TILEPRO_IMM16_X0_PCREL 31 /* X0 pipe PC relative 16 bit */ -#define R_TILEPRO_IMM16_X1_PCREL 32 /* X1 pipe PC relative 16 bit */ -#define R_TILEPRO_IMM16_X0_LO_PCREL 33 /* X0 pipe PC relative low 16 bit */ -#define R_TILEPRO_IMM16_X1_LO_PCREL 34 /* X1 pipe PC relative low 16 bit */ -#define R_TILEPRO_IMM16_X0_HI_PCREL 35 /* X0 pipe PC relative high 16 bit */ -#define R_TILEPRO_IMM16_X1_HI_PCREL 36 /* X1 pipe PC relative high 16 bit */ -#define R_TILEPRO_IMM16_X0_HA_PCREL 37 /* X0 pipe PC relative ha() 16 bit */ -#define R_TILEPRO_IMM16_X1_HA_PCREL 38 /* X1 pipe PC relative ha() 16 bit */ -#define R_TILEPRO_IMM16_X0_GOT 39 /* X0 pipe 16-bit GOT offset */ -#define R_TILEPRO_IMM16_X1_GOT 40 /* X1 pipe 16-bit GOT offset */ -#define R_TILEPRO_IMM16_X0_GOT_LO 41 /* X0 pipe low 16-bit GOT offset */ -#define R_TILEPRO_IMM16_X1_GOT_LO 42 /* X1 pipe low 16-bit GOT offset */ -#define R_TILEPRO_IMM16_X0_GOT_HI 43 /* X0 pipe high 16-bit GOT offset */ -#define R_TILEPRO_IMM16_X1_GOT_HI 44 /* X1 pipe high 16-bit GOT offset */ -#define R_TILEPRO_IMM16_X0_GOT_HA 45 /* X0 pipe ha() 16-bit GOT offset */ -#define R_TILEPRO_IMM16_X1_GOT_HA 46 /* X1 pipe ha() 16-bit GOT offset */ -#define R_TILEPRO_MMSTART_X0 47 /* X0 pipe mm "start" */ -#define R_TILEPRO_MMEND_X0 48 /* X0 pipe mm "end" */ -#define R_TILEPRO_MMSTART_X1 49 /* X1 pipe mm "start" */ -#define R_TILEPRO_MMEND_X1 50 /* X1 pipe mm "end" */ -#define R_TILEPRO_SHAMT_X0 51 /* X0 pipe shift amount */ -#define R_TILEPRO_SHAMT_X1 52 /* X1 pipe shift amount */ -#define R_TILEPRO_SHAMT_Y0 53 /* Y0 pipe shift amount */ -#define R_TILEPRO_SHAMT_Y1 54 /* Y1 pipe shift amount */ -#define R_TILEPRO_DEST_IMM8_X1 55 /* X1 pipe destination 8-bit */ -/* Relocs 56-59 are currently not defined. */ -#define R_TILEPRO_TLS_GD_CALL 60 /* "jal" for TLS GD */ -#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61 /* X0 pipe "addi" for TLS GD */ -#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62 /* X1 pipe "addi" for TLS GD */ -#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63 /* Y0 pipe "addi" for TLS GD */ -#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64 /* Y1 pipe "addi" for TLS GD */ -#define R_TILEPRO_TLS_IE_LOAD 65 /* "lw_tls" for TLS IE */ -#define R_TILEPRO_IMM16_X0_TLS_GD 66 /* X0 pipe 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X1_TLS_GD 67 /* X1 pipe 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68 /* X0 pipe low 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69 /* X1 pipe low 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70 /* X0 pipe high 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71 /* X1 pipe high 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72 /* X0 pipe ha() 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73 /* X1 pipe ha() 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X0_TLS_IE 74 /* X0 pipe 16-bit TLS IE offset */ -#define R_TILEPRO_IMM16_X1_TLS_IE 75 /* X1 pipe 16-bit TLS IE offset */ -#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76 /* X0 pipe low 16-bit TLS IE offset */ -#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77 /* X1 pipe low 16-bit TLS IE offset */ -#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78 /* X0 pipe high 16-bit TLS IE offset */ -#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79 /* X1 pipe high 16-bit TLS IE offset */ -#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80 /* X0 pipe ha() 16-bit TLS IE offset */ -#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81 /* X1 pipe ha() 16-bit TLS IE offset */ -#define R_TILEPRO_TLS_DTPMOD32 82 /* ID of module containing symbol */ -#define R_TILEPRO_TLS_DTPOFF32 83 /* Offset in TLS block */ -#define R_TILEPRO_TLS_TPOFF32 84 /* Offset in static TLS block */ -#define R_TILEPRO_IMM16_X0_TLS_LE 85 /* X0 pipe 16-bit TLS LE offset */ -#define R_TILEPRO_IMM16_X1_TLS_LE 86 /* X1 pipe 16-bit TLS LE offset */ -#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87 /* X0 pipe low 16-bit TLS LE offset */ -#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88 /* X1 pipe low 16-bit TLS LE offset */ -#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89 /* X0 pipe high 16-bit TLS LE offset */ -#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90 /* X1 pipe high 16-bit TLS LE offset */ -#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91 /* X0 pipe ha() 16-bit TLS LE offset */ -#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92 /* X1 pipe ha() 16-bit TLS LE offset */ - -#define R_TILEPRO_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ -#define R_TILEPRO_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ - -#define R_TILEPRO_NUM 130 - - -/* TILE-Gx relocations. */ -#define R_TILEGX_NONE 0 /* No reloc */ -#define R_TILEGX_64 1 /* Direct 64 bit */ -#define R_TILEGX_32 2 /* Direct 32 bit */ -#define R_TILEGX_16 3 /* Direct 16 bit */ -#define R_TILEGX_8 4 /* Direct 8 bit */ -#define R_TILEGX_64_PCREL 5 /* PC relative 64 bit */ -#define R_TILEGX_32_PCREL 6 /* PC relative 32 bit */ -#define R_TILEGX_16_PCREL 7 /* PC relative 16 bit */ -#define R_TILEGX_8_PCREL 8 /* PC relative 8 bit */ -#define R_TILEGX_HW0 9 /* hword 0 16-bit */ -#define R_TILEGX_HW1 10 /* hword 1 16-bit */ -#define R_TILEGX_HW2 11 /* hword 2 16-bit */ -#define R_TILEGX_HW3 12 /* hword 3 16-bit */ -#define R_TILEGX_HW0_LAST 13 /* last hword 0 16-bit */ -#define R_TILEGX_HW1_LAST 14 /* last hword 1 16-bit */ -#define R_TILEGX_HW2_LAST 15 /* last hword 2 16-bit */ -#define R_TILEGX_COPY 16 /* Copy relocation */ -#define R_TILEGX_GLOB_DAT 17 /* Create GOT entry */ -#define R_TILEGX_JMP_SLOT 18 /* Create PLT entry */ -#define R_TILEGX_RELATIVE 19 /* Adjust by program base */ -#define R_TILEGX_BROFF_X1 20 /* X1 pipe branch offset */ -#define R_TILEGX_JUMPOFF_X1 21 /* X1 pipe jump offset */ -#define R_TILEGX_JUMPOFF_X1_PLT 22 /* X1 pipe jump offset to PLT */ -#define R_TILEGX_IMM8_X0 23 /* X0 pipe 8-bit */ -#define R_TILEGX_IMM8_Y0 24 /* Y0 pipe 8-bit */ -#define R_TILEGX_IMM8_X1 25 /* X1 pipe 8-bit */ -#define R_TILEGX_IMM8_Y1 26 /* Y1 pipe 8-bit */ -#define R_TILEGX_DEST_IMM8_X1 27 /* X1 pipe destination 8-bit */ -#define R_TILEGX_MT_IMM14_X1 28 /* X1 pipe mtspr */ -#define R_TILEGX_MF_IMM14_X1 29 /* X1 pipe mfspr */ -#define R_TILEGX_MMSTART_X0 30 /* X0 pipe mm "start" */ -#define R_TILEGX_MMEND_X0 31 /* X0 pipe mm "end" */ -#define R_TILEGX_SHAMT_X0 32 /* X0 pipe shift amount */ -#define R_TILEGX_SHAMT_X1 33 /* X1 pipe shift amount */ -#define R_TILEGX_SHAMT_Y0 34 /* Y0 pipe shift amount */ -#define R_TILEGX_SHAMT_Y1 35 /* Y1 pipe shift amount */ -#define R_TILEGX_IMM16_X0_HW0 36 /* X0 pipe hword 0 */ -#define R_TILEGX_IMM16_X1_HW0 37 /* X1 pipe hword 0 */ -#define R_TILEGX_IMM16_X0_HW1 38 /* X0 pipe hword 1 */ -#define R_TILEGX_IMM16_X1_HW1 39 /* X1 pipe hword 1 */ -#define R_TILEGX_IMM16_X0_HW2 40 /* X0 pipe hword 2 */ -#define R_TILEGX_IMM16_X1_HW2 41 /* X1 pipe hword 2 */ -#define R_TILEGX_IMM16_X0_HW3 42 /* X0 pipe hword 3 */ -#define R_TILEGX_IMM16_X1_HW3 43 /* X1 pipe hword 3 */ -#define R_TILEGX_IMM16_X0_HW0_LAST 44 /* X0 pipe last hword 0 */ -#define R_TILEGX_IMM16_X1_HW0_LAST 45 /* X1 pipe last hword 0 */ -#define R_TILEGX_IMM16_X0_HW1_LAST 46 /* X0 pipe last hword 1 */ -#define R_TILEGX_IMM16_X1_HW1_LAST 47 /* X1 pipe last hword 1 */ -#define R_TILEGX_IMM16_X0_HW2_LAST 48 /* X0 pipe last hword 2 */ -#define R_TILEGX_IMM16_X1_HW2_LAST 49 /* X1 pipe last hword 2 */ -#define R_TILEGX_IMM16_X0_HW0_PCREL 50 /* X0 pipe PC relative hword 0 */ -#define R_TILEGX_IMM16_X1_HW0_PCREL 51 /* X1 pipe PC relative hword 0 */ -#define R_TILEGX_IMM16_X0_HW1_PCREL 52 /* X0 pipe PC relative hword 1 */ -#define R_TILEGX_IMM16_X1_HW1_PCREL 53 /* X1 pipe PC relative hword 1 */ -#define R_TILEGX_IMM16_X0_HW2_PCREL 54 /* X0 pipe PC relative hword 2 */ -#define R_TILEGX_IMM16_X1_HW2_PCREL 55 /* X1 pipe PC relative hword 2 */ -#define R_TILEGX_IMM16_X0_HW3_PCREL 56 /* X0 pipe PC relative hword 3 */ -#define R_TILEGX_IMM16_X1_HW3_PCREL 57 /* X1 pipe PC relative hword 3 */ -#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */ -#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */ -#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */ -#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */ -#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */ -#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */ -#define R_TILEGX_IMM16_X0_HW0_GOT 64 /* X0 pipe hword 0 GOT offset */ -#define R_TILEGX_IMM16_X1_HW0_GOT 65 /* X1 pipe hword 0 GOT offset */ -#define R_TILEGX_IMM16_X0_HW0_PLT_PCREL 66 /* X0 pipe PC-rel PLT hword 0 */ -#define R_TILEGX_IMM16_X1_HW0_PLT_PCREL 67 /* X1 pipe PC-rel PLT hword 0 */ -#define R_TILEGX_IMM16_X0_HW1_PLT_PCREL 68 /* X0 pipe PC-rel PLT hword 1 */ -#define R_TILEGX_IMM16_X1_HW1_PLT_PCREL 69 /* X1 pipe PC-rel PLT hword 1 */ -#define R_TILEGX_IMM16_X0_HW2_PLT_PCREL 70 /* X0 pipe PC-rel PLT hword 2 */ -#define R_TILEGX_IMM16_X1_HW2_PLT_PCREL 71 /* X1 pipe PC-rel PLT hword 2 */ -#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */ -#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */ -#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */ -#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */ -#define R_TILEGX_IMM16_X0_HW3_PLT_PCREL 76 /* X0 pipe PC-rel PLT hword 3 */ -#define R_TILEGX_IMM16_X1_HW3_PLT_PCREL 77 /* X1 pipe PC-rel PLT hword 3 */ -#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78 /* X0 pipe hword 0 TLS GD offset */ -#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79 /* X1 pipe hword 0 TLS GD offset */ -#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80 /* X0 pipe hword 0 TLS LE offset */ -#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81 /* X1 pipe hword 0 TLS LE offset */ -#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */ -#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */ -#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */ -#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */ -#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */ -#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */ -#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */ -#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */ -/* Relocs 90-91 are currently not defined. */ -#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92 /* X0 pipe hword 0 TLS IE offset */ -#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93 /* X1 pipe hword 0 TLS IE offset */ -#define R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL 94 /* X0 pipe PC-rel PLT last hword 0 */ -#define R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL 95 /* X1 pipe PC-rel PLT last hword 0 */ -#define R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL 96 /* X0 pipe PC-rel PLT last hword 1 */ -#define R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL 97 /* X1 pipe PC-rel PLT last hword 1 */ -#define R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL 98 /* X0 pipe PC-rel PLT last hword 2 */ -#define R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL 99 /* X1 pipe PC-rel PLT last hword 2 */ -#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */ -#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */ -#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */ -#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */ -/* Relocs 104-105 are currently not defined. */ -#define R_TILEGX_TLS_DTPMOD64 106 /* 64-bit ID of symbol's module */ -#define R_TILEGX_TLS_DTPOFF64 107 /* 64-bit offset in TLS block */ -#define R_TILEGX_TLS_TPOFF64 108 /* 64-bit offset in static TLS block */ -#define R_TILEGX_TLS_DTPMOD32 109 /* 32-bit ID of symbol's module */ -#define R_TILEGX_TLS_DTPOFF32 110 /* 32-bit offset in TLS block */ -#define R_TILEGX_TLS_TPOFF32 111 /* 32-bit offset in static TLS block */ -#define R_TILEGX_TLS_GD_CALL 112 /* "jal" for TLS GD */ -#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113 /* X0 pipe "addi" for TLS GD */ -#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114 /* X1 pipe "addi" for TLS GD */ -#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115 /* Y0 pipe "addi" for TLS GD */ -#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116 /* Y1 pipe "addi" for TLS GD */ -#define R_TILEGX_TLS_IE_LOAD 117 /* "ld_tls" for TLS IE */ -#define R_TILEGX_IMM8_X0_TLS_ADD 118 /* X0 pipe "addi" for TLS GD/IE */ -#define R_TILEGX_IMM8_X1_TLS_ADD 119 /* X1 pipe "addi" for TLS GD/IE */ -#define R_TILEGX_IMM8_Y0_TLS_ADD 120 /* Y0 pipe "addi" for TLS GD/IE */ -#define R_TILEGX_IMM8_Y1_TLS_ADD 121 /* Y1 pipe "addi" for TLS GD/IE */ - -#define R_TILEGX_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ -#define R_TILEGX_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ - -#define R_TILEGX_NUM 130 - - -#endif /* elf.h */ diff --git a/external/TCC/i386-asm.c b/external/TCC/i386-asm.c deleted file mode 100644 index 68a78613..00000000 --- a/external/TCC/i386-asm.c +++ /dev/null @@ -1,1502 +0,0 @@ -/* - * i386 specific functions for TCC assembler - * - * Copyright (c) 2001, 2002 Fabrice Bellard - * Copyright (c) 2009 Frédéric Feret (x86_64 support) - * - * 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "tcc.h" - -/* #define NB_ASM_REGS 8 */ -#define MAX_OPERANDS 3 -#define NB_SAVED_REGS 3 - -#define TOK_ASM_first TOK_ASM_clc -#define TOK_ASM_last TOK_ASM_emms -#define TOK_ASM_alllast TOK_ASM_pxor - -#define OPC_JMP 0x01 /* jmp operand */ -#define OPC_B 0x02 /* only used with OPC_WL */ -#define OPC_WL 0x04 /* accepts w, l or no suffix */ -#define OPC_BWL (OPC_B | OPC_WL) /* accepts b, w, l or no suffix */ -#define OPC_REG 0x08 /* register is added to opcode */ -#define OPC_MODRM 0x10 /* modrm encoding */ -#define OPC_FWAIT 0x20 /* add fwait opcode */ -#define OPC_TEST 0x40 /* test opcodes */ -#define OPC_SHIFT 0x80 /* shift opcodes */ -#define OPC_D16 0x0100 /* generate data16 prefix */ -#define OPC_ARITH 0x0200 /* arithmetic opcodes */ -#define OPC_SHORTJMP 0x0400 /* short jmp operand */ -#define OPC_FARITH 0x0800 /* FPU arithmetic opcodes */ -#ifdef TCC_TARGET_X86_64 -# define OPC_WLQ 0x1000 /* accepts w, l, q or no suffix */ -# define OPC_BWLQ (OPC_B | OPC_WLQ) /* accepts b, w, l, q or no suffix */ -# define OPC_WLX OPC_WLQ -#else -# define OPC_WLX OPC_WL -#endif - -#define OPC_GROUP_SHIFT 13 - -/* in order to compress the operand type, we use specific operands and - we or only with EA */ -enum { - OPT_REG8=0, /* warning: value is hardcoded from TOK_ASM_xxx */ - OPT_REG16, /* warning: value is hardcoded from TOK_ASM_xxx */ - OPT_REG32, /* warning: value is hardcoded from TOK_ASM_xxx */ -#ifdef TCC_TARGET_X86_64 - OPT_REG64, /* warning: value is hardcoded from TOK_ASM_xxx */ -#endif - OPT_MMX, /* warning: value is hardcoded from TOK_ASM_xxx */ - OPT_SSE, /* warning: value is hardcoded from TOK_ASM_xxx */ - OPT_CR, /* warning: value is hardcoded from TOK_ASM_xxx */ - OPT_TR, /* warning: value is hardcoded from TOK_ASM_xxx */ - OPT_DB, /* warning: value is hardcoded from TOK_ASM_xxx */ - OPT_SEG, - OPT_ST, - OPT_IM8, - OPT_IM8S, - OPT_IM16, - OPT_IM32, -#ifdef TCC_TARGET_X86_64 - OPT_IM64, -#endif - OPT_EAX, /* %al, %ax, %eax or %rax register */ - OPT_ST0, /* %st(0) register */ - OPT_CL, /* %cl register */ - OPT_DX, /* %dx register */ - OPT_ADDR, /* OP_EA with only offset */ - OPT_INDIR, /* *(expr) */ - /* composite types */ - OPT_COMPOSITE_FIRST, - OPT_IM, /* IM8 | IM16 | IM32 | IM64 */ - OPT_REG, /* REG8 | REG16 | REG32 | REG64 */ - OPT_REGW, /* REG16 | REG32 | REG64 */ - OPT_IMW, /* IM16 | IM32 | IM64 */ -#ifdef TCC_TARGET_X86_64 - OPT_IMNO64, /* IM16 | IM32 */ -#endif - /* can be ored with any OPT_xxx */ - OPT_EA = 0x80 -}; - -#define OP_REG8 (1 << OPT_REG8) -#define OP_REG16 (1 << OPT_REG16) -#define OP_REG32 (1 << OPT_REG32) -#define OP_MMX (1 << OPT_MMX) -#define OP_SSE (1 << OPT_SSE) -#define OP_CR (1 << OPT_CR) -#define OP_TR (1 << OPT_TR) -#define OP_DB (1 << OPT_DB) -#define OP_SEG (1 << OPT_SEG) -#define OP_ST (1 << OPT_ST) -#define OP_IM8 (1 << OPT_IM8) -#define OP_IM8S (1 << OPT_IM8S) -#define OP_IM16 (1 << OPT_IM16) -#define OP_IM32 (1 << OPT_IM32) -#define OP_EAX (1 << OPT_EAX) -#define OP_ST0 (1 << OPT_ST0) -#define OP_CL (1 << OPT_CL) -#define OP_DX (1 << OPT_DX) -#define OP_ADDR (1 << OPT_ADDR) -#define OP_INDIR (1 << OPT_INDIR) -#ifdef TCC_TARGET_X86_64 -# define OP_REG64 (1 << OPT_REG64) -# define OP_IM64 (1 << OPT_IM64) -#else -# define OP_REG64 0 -# define OP_IM64 0 -#endif - -#define OP_EA 0x40000000 -#define OP_REG (OP_REG8 | OP_REG16 | OP_REG32 | OP_REG64) - -#ifdef TCC_TARGET_X86_64 -# define OP_IM OP_IM64 -# define TREG_XAX TREG_RAX -# define TREG_XCX TREG_RCX -# define TREG_XDX TREG_RDX -#else -# define OP_IM OP_IM32 -# define TREG_XAX TREG_EAX -# define TREG_XCX TREG_ECX -# define TREG_XDX TREG_EDX -#endif - -typedef struct ASMInstr { - uint16_t sym; - uint16_t opcode; - uint16_t instr_type; - uint8_t nb_ops; - uint8_t op_type[MAX_OPERANDS]; /* see OP_xxx */ -} ASMInstr; - -typedef struct Operand { - uint32_t type; - int8_t reg; /* register, -1 if none */ - int8_t reg2; /* second register, -1 if none */ - uint8_t shift; - ExprValue e; -} Operand; - -static const uint8_t reg_to_size[9] = { -/* - [OP_REG8] = 0, - [OP_REG16] = 1, - [OP_REG32] = 2, -#ifdef TCC_TARGET_X86_64 - [OP_REG64] = 3, -#endif -*/ - 0, 0, 1, 0, 2, 0, 0, 0, 3 -}; - -#define NB_TEST_OPCODES 30 - -static const uint8_t test_bits[NB_TEST_OPCODES] = { - 0x00, /* o */ - 0x01, /* no */ - 0x02, /* b */ - 0x02, /* c */ - 0x02, /* nae */ - 0x03, /* nb */ - 0x03, /* nc */ - 0x03, /* ae */ - 0x04, /* e */ - 0x04, /* z */ - 0x05, /* ne */ - 0x05, /* nz */ - 0x06, /* be */ - 0x06, /* na */ - 0x07, /* nbe */ - 0x07, /* a */ - 0x08, /* s */ - 0x09, /* ns */ - 0x0a, /* p */ - 0x0a, /* pe */ - 0x0b, /* np */ - 0x0b, /* po */ - 0x0c, /* l */ - 0x0c, /* nge */ - 0x0d, /* nl */ - 0x0d, /* ge */ - 0x0e, /* le */ - 0x0e, /* ng */ - 0x0f, /* nle */ - 0x0f, /* g */ -}; - -static const uint8_t segment_prefixes[] = { - 0x26, /* es */ - 0x2e, /* cs */ - 0x36, /* ss */ - 0x3e, /* ds */ - 0x64, /* fs */ - 0x65 /* gs */ -}; - -static const ASMInstr asm_instrs[] = { -#define ALT(x) x -#define DEF_ASM_OP0(name, opcode) -#define DEF_ASM_OP0L(name, opcode, group, instr_type) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 0 }, -#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 1, { op0 }}, -#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 2, { op0, op1 }}, -#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 3, { op0, op1, op2 }}, -#ifdef TCC_TARGET_X86_64 -# include "x86_64-asm.h" -#else -# include "i386-asm.h" -#endif - /* last operation */ - { 0, }, -}; - -static const uint16_t op0_codes[] = { -#define ALT(x) -#define DEF_ASM_OP0(x, opcode) opcode, -#define DEF_ASM_OP0L(name, opcode, group, instr_type) -#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) -#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) -#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) -#ifdef TCC_TARGET_X86_64 -# include "x86_64-asm.h" -#else -# include "i386-asm.h" -#endif -}; - -static inline int get_reg_shift(TCCState *s1) -{ - int shift, v; -#ifdef I386_ASM_16 - if (s1->seg_size == 16) - tcc_error("invalid effective address"); -#endif - v = asm_int_expr(s1); - switch(v) { - case 1: - shift = 0; - break; - case 2: - shift = 1; - break; - case 4: - shift = 2; - break; - case 8: - shift = 3; - break; - default: - expect("1, 2, 4 or 8 constant"); - shift = 0; - break; - } - return shift; -} - -static int asm_parse_reg(void) -{ - int reg = 0; - if (tok != '%') - goto error_32; - next(); - if (tok >= TOK_ASM_eax && tok <= TOK_ASM_edi) { - reg = tok - TOK_ASM_eax; -#ifdef TCC_TARGET_X86_64 - } else if (tok >= TOK_ASM_rax && tok <= TOK_ASM_rdi) { - reg = tok - TOK_ASM_rax; -#endif -#ifdef I386_ASM_16 - } else if (tok >= TOK_ASM_ax && tok <= TOK_ASM_di) { - reg = tok - TOK_ASM_ax; -#endif - } else { - error_32: - expect("register"); - } - next(); - return reg; -} - -static void parse_operand(TCCState *s1, Operand *op) -{ - ExprValue e; - int reg, indir; - const char *p; - - indir = 0; - if (tok == '*') { - next(); - indir = OP_INDIR; - } - - if (tok == '%') { - next(); - if (tok >= TOK_ASM_al && tok <= TOK_ASM_db7) { - reg = tok - TOK_ASM_al; - op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */ - op->reg = reg & 7; - if ((op->type & OP_REG) && op->reg == TREG_XAX) - op->type |= OP_EAX; - else if (op->type == OP_REG8 && op->reg == TREG_XCX) - op->type |= OP_CL; - else if (op->type == OP_REG16 && op->reg == TREG_XDX) - op->type |= OP_DX; - } else if (tok >= TOK_ASM_dr0 && tok <= TOK_ASM_dr7) { - op->type = OP_DB; - op->reg = tok - TOK_ASM_dr0; - } else if (tok >= TOK_ASM_es && tok <= TOK_ASM_gs) { - op->type = OP_SEG; - op->reg = tok - TOK_ASM_es; - } else if (tok == TOK_ASM_st) { - op->type = OP_ST; - op->reg = 0; - next(); - if (tok == '(') { - next(); - if (tok != TOK_PPNUM) - goto reg_error; - p = tokc.str.data; - reg = p[0] - '0'; - if ((unsigned)reg >= 8 || p[1] != '\0') - goto reg_error; - op->reg = reg; - next(); - skip(')'); - } - if (op->reg == 0) - op->type |= OP_ST0; - goto no_skip; - } else { - reg_error: - tcc_error("unknown register"); - } - next(); - no_skip: ; - } else if (tok == '$') { - /* constant value */ - next(); - asm_expr(s1, &e); - op->type = OP_IM; - op->e.v = e.v; - op->e.sym = e.sym; - if (!op->e.sym) { - if (op->e.v == (uint8_t)op->e.v) - op->type |= OP_IM8; - if (op->e.v == (int8_t)op->e.v) - op->type |= OP_IM8S; - if (op->e.v == (uint16_t)op->e.v) - op->type |= OP_IM16; -#ifdef TCC_TARGET_X86_64 - if (op->e.v == (uint32_t)op->e.v) - op->type |= OP_IM32; -#endif - } - } else { - /* address(reg,reg2,shift) with all variants */ - op->type = OP_EA; - op->reg = -1; - op->reg2 = -1; - op->shift = 0; - if (tok != '(') { - asm_expr(s1, &e); - op->e.v = e.v; - op->e.sym = e.sym; - } else { - next(); - if (tok == '%') { - unget_tok('('); - op->e.v = 0; - op->e.sym = NULL; - } else { - /* bracketed offset expression */ - asm_expr(s1, &e); - if (tok != ')') - expect(")"); - next(); - op->e.v = e.v; - op->e.sym = e.sym; - } - } - if (tok == '(') { - next(); - if (tok != ',') { - op->reg = asm_parse_reg(); - } - if (tok == ',') { - next(); - if (tok != ',') { - op->reg2 = asm_parse_reg(); - } - if (tok == ',') { - next(); - op->shift = get_reg_shift(s1); - } - } - skip(')'); - } - if (op->reg == -1 && op->reg2 == -1) - op->type |= OP_ADDR; - } - op->type |= indir; -} - -/* XXX: unify with C code output ? */ -ST_FUNC void gen_expr32(ExprValue *pe) -{ - gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v); -} - -#ifdef TCC_TARGET_X86_64 -static void gen_expr64(ExprValue *pe) -{ - gen_addr64(pe->sym ? VT_SYM : 0, pe->sym, pe->v); -} -#endif - -/* XXX: unify with C code output ? */ -static void gen_disp32(ExprValue *pe) -{ - Sym *sym = pe->sym; - if (sym && sym->r == cur_text_section->sh_num) { - /* same section: we can output an absolute value. Note - that the TCC compiler behaves differently here because - it always outputs a relocation to ease (future) code - elimination in the linker */ - gen_le32(pe->v + sym->jnext - ind - 4); - } else { - if (sym && sym->type.t == VT_VOID) { - sym->type.t = VT_FUNC; - sym->type.ref = NULL; - } - gen_addrpc32(VT_SYM, sym, pe->v); - } -} - -#ifdef I386_ASM_16 -static void gen_expr16(ExprValue *pe) -{ - if (pe->sym) - greloc(cur_text_section, pe->sym, ind, R_386_16); - gen_le16(pe->v); -} -static void gen_disp16(ExprValue *pe) -{ - Sym *sym; - sym = pe->sym; - if (sym) { - if (sym->r == cur_text_section->sh_num) { - /* same section: we can output an absolute value. Note - that the TCC compiler behaves differently here because - it always outputs a relocation to ease (future) code - elimination in the linker */ - gen_le16(pe->v + sym->jnext - ind - 2); - } else { - greloc(cur_text_section, sym, ind, R_386_PC16); - gen_le16(pe->v - 2); - } - } else { - /* put an empty PC32 relocation */ - put_elf_reloc(symtab_section, cur_text_section, - ind, R_386_PC16, 0); - gen_le16(pe->v - 2); - } -} -#endif - -/* generate the modrm operand */ -static inline void asm_modrm(int reg, Operand *op) -{ - int mod, reg1, reg2, sib_reg1; - - if (op->type & (OP_REG | OP_MMX | OP_SSE)) { - g(0xc0 + (reg << 3) + op->reg); - } else if (op->reg == -1 && op->reg2 == -1) { - /* displacement only */ -#ifdef I386_ASM_16 - if (tcc_state->seg_size == 16) { - g(0x06 + (reg << 3)); - gen_expr16(&op->e); - } else if (tcc_state->seg_size == 32) -#endif - { - g(0x05 + (reg << 3)); - gen_expr32(&op->e); - } - } else { - sib_reg1 = op->reg; - /* fist compute displacement encoding */ - if (sib_reg1 == -1) { - sib_reg1 = 5; - mod = 0x00; - } else if (op->e.v == 0 && !op->e.sym && op->reg != 5) { - mod = 0x00; - } else if (op->e.v == (int8_t)op->e.v && !op->e.sym) { - mod = 0x40; - } else { - mod = 0x80; - } - /* compute if sib byte needed */ - reg1 = op->reg; - if (op->reg2 != -1) - reg1 = 4; -#ifdef I386_ASM_16 - if (tcc_state->seg_size == 32) { -#endif - g(mod + (reg << 3) + reg1); - if (reg1 == 4) { - /* add sib byte */ - reg2 = op->reg2; - if (reg2 == -1) - reg2 = 4; /* indicate no index */ - g((op->shift << 6) + (reg2 << 3) + sib_reg1); - } -#ifdef I386_ASM_16 - } else if (tcc_state->seg_size == 16) { - /* edi = 7, esi = 6 --> di = 5, si = 4 */ - if ((reg1 == 6) || (reg1 == 7)) { - reg1 -= 2; - /* ebx = 3 --> bx = 7 */ - } else if (reg1 == 3) { - reg1 = 7; - /* o32 = 5 --> o16 = 6 */ - } else if (reg1 == 5) { - reg1 = 6; - /* sib not valid in 16-bit mode */ - } else if (reg1 == 4) { - reg2 = op->reg2; - /* bp + si + offset */ - if ((sib_reg1 == 5) && (reg2 == 6)) { - reg1 = 2; - /* bp + di + offset */ - } else if ((sib_reg1 == 5) && (reg2 == 7)) { - reg1 = 3; - /* bx + si + offset */ - } else if ((sib_reg1 == 3) && (reg2 == 6)) { - reg1 = 0; - /* bx + di + offset */ - } else if ((sib_reg1 == 3) && (reg2 == 7)) { - reg1 = 1; - } else { - tcc_error("invalid effective address"); - } - if (op->e.v == 0) - mod = 0; - } else { - tcc_error("invalid register"); - } - g(mod + (reg << 3) + reg1); - } -#endif - /* add offset */ - if (mod == 0x40) { - g(op->e.v); - } else if (mod == 0x80 || op->reg == -1) { -#ifdef I386_ASM_16 - if (tcc_state->seg_size == 16) - gen_expr16(&op->e); - else if (tcc_state->seg_size == 32) -#endif - gen_expr32(&op->e); - } - } -} - -ST_FUNC void asm_opcode(TCCState *s1, int opcode) -{ - const ASMInstr *pa; - int i, modrm_index, reg, v, op1, is_short_jmp, seg_prefix; - int nb_ops, s; - Operand ops[MAX_OPERANDS], *pop; - int op_type[3]; /* decoded op type */ -#ifdef I386_ASM_16 - static int a32 = 0, o32 = 0, addr32 = 0, data32 = 0; -#endif - - /* force synthetic ';' after prefix instruction, so we can handle */ - /* one-line things like "rep stosb" instead of only "rep\nstosb" */ - if (opcode >= TOK_ASM_wait && opcode <= TOK_ASM_repnz) - unget_tok(';'); - - /* get operands */ - pop = ops; - nb_ops = 0; - seg_prefix = 0; - for(;;) { - if (tok == ';' || tok == TOK_LINEFEED) - break; - if (nb_ops >= MAX_OPERANDS) { - tcc_error("incorrect number of operands"); - } - parse_operand(s1, pop); - if (tok == ':') { - if (pop->type != OP_SEG || seg_prefix) - tcc_error("incorrect prefix"); - seg_prefix = segment_prefixes[pop->reg]; - next(); - parse_operand(s1, pop); -#ifndef I386_ASM_16 - if (!(pop->type & OP_EA)) { - tcc_error("segment prefix must be followed by memory reference"); - } -#endif - } - pop++; - nb_ops++; - if (tok != ',') - break; - next(); - } - - is_short_jmp = 0; - s = 0; /* avoid warning */ - - /* optimize matching by using a lookup table (no hashing is needed - !) */ - for(pa = asm_instrs; pa->sym != 0; pa++) { - s = 0; - if (pa->instr_type & OPC_FARITH) { - v = opcode - pa->sym; - if (!((unsigned)v < 8 * 6 && (v % 6) == 0)) - continue; - } else if (pa->instr_type & OPC_ARITH) { - if (!(opcode >= pa->sym && opcode < pa->sym + 8*NBWLX)) - continue; - s = (opcode - pa->sym) % NBWLX; - } else if (pa->instr_type & OPC_SHIFT) { - if (!(opcode >= pa->sym && opcode < pa->sym + 7*NBWLX)) - continue; - s = (opcode - pa->sym) % NBWLX; - } else if (pa->instr_type & OPC_TEST) { - if (!(opcode >= pa->sym && opcode < pa->sym + NB_TEST_OPCODES)) - continue; - } else if (pa->instr_type & OPC_B) { - if (!(opcode >= pa->sym && opcode < pa->sym + NBWLX)) - continue; - s = opcode - pa->sym; - } else if (pa->instr_type & OPC_WLX) { - if (!(opcode >= pa->sym && opcode < pa->sym + NBWLX-1)) - continue; - s = opcode - pa->sym + 1; - } else { - if (pa->sym != opcode) - continue; - } - if (pa->nb_ops != nb_ops) - continue; - /* now decode and check each operand */ - for(i = 0; i < nb_ops; i++) { - int op1, op2; - op1 = pa->op_type[i]; - op2 = op1 & 0x1f; - switch(op2) { - case OPT_IM: - v = OP_IM8 | OP_IM16 | OP_IM32 | OP_IM64; - break; - case OPT_REG: - v = OP_REG8 | OP_REG16 | OP_REG32 | OP_REG64; - break; - case OPT_REGW: - v = OP_REG16 | OP_REG32 | OP_REG64; - break; - case OPT_IMW: - v = OP_IM16 | OP_IM32 | OP_IM64; - break; -#ifdef TCC_TARGET_X86_64 - case OPT_IMNO64: - v = OP_IM16 | OP_IM32; - break; -#endif - default: - v = 1 << op2; - break; - } - if (op1 & OPT_EA) - v |= OP_EA; - op_type[i] = v; - if ((ops[i].type & v) == 0) - goto next; - } - /* all is matching ! */ - break; - next: ; - } - if (pa->sym == 0) { - if (opcode >= TOK_ASM_first && opcode <= TOK_ASM_last) { - int b; - b = op0_codes[opcode - TOK_ASM_first]; -#ifdef I386_ASM_16 - if (opcode == TOK_ASM_o32) { - if (s1->seg_size == 32) - tcc_error("incorrect prefix"); - else - o32 = data32 = 1; - } else if (opcode == TOK_ASM_a32) { - if (s1->seg_size == 32) - tcc_error("incorrect prefix"); - else - a32 = addr32 = 1; - } -#endif - if (b & 0xff00) - g(b >> 8); - g(b); - return; - } else if (opcode <= TOK_ASM_alllast) { - tcc_error("bad operand with opcode '%s'", - get_tok_str(opcode, NULL)); - } else { - tcc_error("unknown opcode '%s'", - get_tok_str(opcode, NULL)); - } - } - /* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */ - if (s == NBWLX-1) { - for(i = 0; s == NBWLX-1 && i < nb_ops; i++) { - if ((ops[i].type & OP_REG) && !(op_type[i] & (OP_CL | OP_DX))) - s = reg_to_size[ops[i].type & OP_REG]; - } - if (s == NBWLX-1) { - if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) && - (ops[0].type & (OP_SEG | OP_IM8S | OP_IM32 | OP_IM64))) - s = 2; - else - tcc_error("cannot infer opcode suffix"); - } - } - -#ifdef I386_ASM_16 - for(i = 0; i < nb_ops; i++) { - if (ops[i].type & OP_REG32) { - if (s1->seg_size == 16) - o32 = 1; - } else if (!(ops[i].type & OP_REG32)) { - if (s1->seg_size == 32) - o32 = 1; - } - } - - - if (s == 1 || (pa->instr_type & OPC_D16)) { - if (s1->seg_size == 32) - o32 = 1; - } else if (s == 2) { - if (s1->seg_size == 16) { - if (!(pa->instr_type & OPC_D16)) - o32 = 1; - } - } - - /* generate a16/a32 prefix if needed */ - if ((a32 == 1) && (addr32 == 0)) - g(0x67); - /* generate o16/o32 prefix if needed */ - if ((o32 == 1) && (data32 == 0)) - g(0x66); - - addr32 = data32 = 0; -#else - /* generate data16 prefix if needed */ - if (s == 1 || (pa->instr_type & OPC_D16)) - g(0x66); -#ifdef TCC_TARGET_X86_64 - else if (s == 3) { - /* generate REX prefix */ - if ((opcode != TOK_ASM_push && opcode != TOK_ASM_pop) - || !(ops[0].type & OP_REG64)) - g(0x48); - } -#endif -#endif - - /* now generates the operation */ - if (pa->instr_type & OPC_FWAIT) - g(0x9b); - if (seg_prefix) - g(seg_prefix); - - v = pa->opcode; - if ((v == 0x69 || v == 0x6b) && nb_ops == 2) { - /* kludge for imul $im, %reg */ - nb_ops = 3; - ops[2] = ops[1]; - op_type[2] = op_type[1]; - } else if (v == 0xcd && ops[0].e.v == 3 && !ops[0].e.sym) { - v--; /* int $3 case */ - nb_ops = 0; - } else if ((v == 0x06 || v == 0x07)) { - if (ops[0].reg >= 4) { - /* push/pop %fs or %gs */ - v = 0x0fa0 + (v - 0x06) + ((ops[0].reg - 4) << 3); - } else { - v += ops[0].reg << 3; - } - nb_ops = 0; - } else if (v <= 0x05) { - /* arith case */ - v += ((opcode - TOK_ASM_addb) / NBWLX) << 3; - } else if ((pa->instr_type & (OPC_FARITH | OPC_MODRM)) == OPC_FARITH) { - /* fpu arith case */ - v += ((opcode - pa->sym) / 6) << 3; - } - if (pa->instr_type & OPC_REG) { - for(i = 0; i < nb_ops; i++) { - if (op_type[i] & (OP_REG | OP_ST)) { - v += ops[i].reg; - break; - } - } - /* mov $im, %reg case */ - if (pa->opcode == 0xb0 && s >= 1) - v += 7; - } - if (pa->instr_type & OPC_B) - v += s >= 1; - if (pa->instr_type & OPC_TEST) - v += test_bits[opcode - pa->sym]; - if (pa->instr_type & OPC_SHORTJMP) { - Sym *sym; - int jmp_disp; - - /* see if we can really generate the jump with a byte offset */ - sym = ops[0].e.sym; - if (!sym) - goto no_short_jump; - if (sym->r != cur_text_section->sh_num) - goto no_short_jump; - jmp_disp = ops[0].e.v + sym->jnext - ind - 2; - if (jmp_disp == (int8_t)jmp_disp) { - /* OK to generate jump */ - is_short_jmp = 1; - ops[0].e.v = jmp_disp; - } else { - no_short_jump: - if (pa->instr_type & OPC_JMP) { - /* long jump will be allowed. need to modify the - opcode slightly */ - if (v == 0xeb) - v = 0xe9; - else - v += 0x0f10; - } else { - tcc_error("invalid displacement"); - } - } - } - op1 = v >> 8; - if (op1) - g(op1); - g(v); - - /* search which operand will used for modrm */ - modrm_index = 0; - if (pa->instr_type & OPC_SHIFT) { - reg = (opcode - pa->sym) / NBWLX; - if (reg == 6) - reg = 7; - } else if (pa->instr_type & OPC_ARITH) { - reg = (opcode - pa->sym) / NBWLX; - } else if (pa->instr_type & OPC_FARITH) { - reg = (opcode - pa->sym) / 6; - } else { - reg = (pa->instr_type >> OPC_GROUP_SHIFT) & 7; - } - if (pa->instr_type & OPC_MODRM) { - /* first look for an ea operand */ - for(i = 0;i < nb_ops; i++) { - if (op_type[i] & OP_EA) - goto modrm_found; - } - /* then if not found, a register or indirection (shift instructions) */ - for(i = 0;i < nb_ops; i++) { - if (op_type[i] & (OP_REG | OP_MMX | OP_SSE | OP_INDIR)) - goto modrm_found; - } -#ifdef ASM_DEBUG - tcc_error("bad op table"); -#endif - modrm_found: - modrm_index = i; - /* if a register is used in another operand then it is - used instead of group */ - for(i = 0;i < nb_ops; i++) { - v = op_type[i]; - if (i != modrm_index && - (v & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_TR | OP_DB | OP_SEG))) { - reg = ops[i].reg; - break; - } - } - - asm_modrm(reg, &ops[modrm_index]); - } - - /* emit constants */ -#ifndef TCC_TARGET_X86_64 - if (pa->opcode == 0x9a || pa->opcode == 0xea) { - /* ljmp or lcall kludge */ -#ifdef I386_ASM_16 - if (s1->seg_size == 16 && o32 == 0) - gen_expr16(&ops[1].e); - else -#endif - gen_expr32(&ops[1].e); - if (ops[0].e.sym) - tcc_error("cannot relocate"); - gen_le16(ops[0].e.v); - return; - } -#endif - for(i = 0;i < nb_ops; i++) { - v = op_type[i]; - if (v & (OP_IM8 | OP_IM16 | OP_IM32 | OP_IM64 | OP_IM8S | OP_ADDR)) { - /* if multiple sizes are given it means we must look - at the op size */ - if ((v | OP_IM8 | OP_IM64) == (OP_IM8 | OP_IM16 | OP_IM32 | OP_IM64)) { - if (s == 0) - v = OP_IM8; - else if (s == 1) - v = OP_IM16; - else if (s == 2 || (v & OP_IM64) == 0) - v = OP_IM32; - else - v = OP_IM64; - } - if (v & (OP_IM8 | OP_IM8S)) { - if (ops[i].e.sym) - goto error_relocate; - g(ops[i].e.v); - } else if (v & OP_IM16) { -#ifdef I386_ASM_16 - if (s1->seg_size == 16) - gen_expr16(&ops[i].e); - else -#endif - if (ops[i].e.sym) - error_relocate: - tcc_error("cannot relocate"); - else - gen_le16(ops[i].e.v); - } else { - if (pa->instr_type & (OPC_JMP | OPC_SHORTJMP)) { - if (is_short_jmp) - g(ops[i].e.v); -#ifdef I386_ASM_16 - else if (s1->seg_size == 16) - gen_disp16(&ops[i].e); -#endif - else - gen_disp32(&ops[i].e); - } else { -#ifdef I386_ASM_16 - if (s1->seg_size == 16 && !((o32 == 1) && (v & OP_IM32))) - gen_expr16(&ops[i].e); - else -#endif -#ifdef TCC_TARGET_X86_64 - if (v & OP_IM64) - gen_expr64(&ops[i].e); - else -#endif - gen_expr32(&ops[i].e); - } - } -#ifdef I386_ASM_16 - } else if (v & (OP_REG16 | OP_REG32)) { - if (pa->instr_type & (OPC_JMP | OPC_SHORTJMP)) { - /* jmp $r */ - g(0xE0 + ops[i].reg); - } -#endif -#ifdef TCC_TARGET_X86_64 - } else if (v & (OP_REG32 | OP_REG64)) { - if (pa->instr_type & (OPC_JMP | OPC_SHORTJMP)) { - /* jmp $r */ - g(0xE0 + ops[i].reg); - } -#endif - } - } -#ifdef I386_ASM_16 - a32 = o32 = 0; -#endif -} - -/* return the constraint priority (we allocate first the lowest - numbered constraints) */ -static inline int constraint_priority(const char *str) -{ - int priority, c, pr; - - /* we take the lowest priority */ - priority = 0; - for(;;) { - c = *str; - if (c == '\0') - break; - str++; - switch(c) { - case 'A': - pr = 0; - break; - case 'a': - case 'b': - case 'c': - case 'd': - case 'S': - case 'D': - pr = 1; - break; - case 'q': - pr = 2; - break; - case 'r': - pr = 3; - break; - case 'N': - case 'M': - case 'I': - case 'i': - case 'm': - case 'g': - pr = 4; - break; - default: - tcc_error("unknown constraint '%c'", c); - pr = 0; - } - if (pr > priority) - priority = pr; - } - return priority; -} - -static const char *skip_constraint_modifiers(const char *p) -{ - while (*p == '=' || *p == '&' || *p == '+' || *p == '%') - p++; - return p; -} - -#define REG_OUT_MASK 0x01 -#define REG_IN_MASK 0x02 - -#define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask) - -ST_FUNC void asm_compute_constraints(ASMOperand *operands, - int nb_operands, int nb_outputs, - const uint8_t *clobber_regs, - int *pout_reg) -{ - ASMOperand *op; - int sorted_op[MAX_ASM_OPERANDS]; - int i, j, k, p1, p2, tmp, reg, c, reg_mask; - const char *str; - uint8_t regs_allocated[NB_ASM_REGS]; - - /* init fields */ - for(i=0;iinput_index = -1; - op->ref_index = -1; - op->reg = -1; - op->is_memory = 0; - op->is_rw = 0; - } - /* compute constraint priority and evaluate references to output - constraints if input constraints */ - for(i=0;iconstraint; - str = skip_constraint_modifiers(str); - if (isnum(*str) || *str == '[') { - /* this is a reference to another constraint */ - k = find_constraint(operands, nb_operands, str, NULL); - if ((unsigned)k >= i || i < nb_outputs) - tcc_error("invalid reference in constraint %d ('%s')", - i, str); - op->ref_index = k; - if (operands[k].input_index >= 0) - tcc_error("cannot reference twice the same operand"); - operands[k].input_index = i; - op->priority = 5; - } else { - op->priority = constraint_priority(str); - } - } - - /* sort operands according to their priority */ - for(i=0;iconstraint; - /* no need to allocate references */ - if (op->ref_index >= 0) - continue; - /* select if register is used for output, input or both */ - if (op->input_index >= 0) { - reg_mask = REG_IN_MASK | REG_OUT_MASK; - } else if (j < nb_outputs) { - reg_mask = REG_OUT_MASK; - } else { - reg_mask = REG_IN_MASK; - } - try_next: - c = *str++; - switch(c) { - case '=': - goto try_next; - case '+': - op->is_rw = 1; - /* FALL THRU */ - case '&': - if (j >= nb_outputs) - tcc_error("'%c' modifier can only be applied to outputs", c); - reg_mask = REG_IN_MASK | REG_OUT_MASK; - goto try_next; - case 'A': - /* allocate both eax and edx */ - if (is_reg_allocated(TREG_XAX) || - is_reg_allocated(TREG_XDX)) - goto try_next; - op->is_llong = 1; - op->reg = TREG_XAX; - regs_allocated[TREG_XAX] |= reg_mask; - regs_allocated[TREG_XDX] |= reg_mask; - break; - case 'a': - reg = TREG_XAX; - goto alloc_reg; - case 'b': - reg = 3; - goto alloc_reg; - case 'c': - reg = TREG_XCX; - goto alloc_reg; - case 'd': - reg = TREG_XDX; - goto alloc_reg; - case 'S': - reg = 6; - goto alloc_reg; - case 'D': - reg = 7; - alloc_reg: - if (is_reg_allocated(reg)) - goto try_next; - goto reg_found; - case 'q': - /* eax, ebx, ecx or edx */ - for(reg = 0; reg < 4; reg++) { - if (!is_reg_allocated(reg)) - goto reg_found; - } - goto try_next; - case 'r': - /* any general register */ - for(reg = 0; reg < 8; reg++) { - if (!is_reg_allocated(reg)) - goto reg_found; - } - goto try_next; - reg_found: - /* now we can reload in the register */ - op->is_llong = 0; - op->reg = reg; - regs_allocated[reg] |= reg_mask; - break; - case 'i': - if (!((op->vt->r & (VT_VALMASK | VT_LVAL)) == VT_CONST)) - goto try_next; - break; - case 'I': - case 'N': - case 'M': - if (!((op->vt->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)) - goto try_next; - break; - case 'm': - case 'g': - /* nothing special to do because the operand is already in - memory, except if the pointer itself is stored in a - memory variable (VT_LLOCAL case) */ - /* XXX: fix constant case */ - /* if it is a reference to a memory zone, it must lie - in a register, so we reserve the register in the - input registers and a load will be generated - later */ - if (j < nb_outputs || c == 'm') { - if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) { - /* any general register */ - for(reg = 0; reg < 8; reg++) { - if (!(regs_allocated[reg] & REG_IN_MASK)) - goto reg_found1; - } - goto try_next; - reg_found1: - /* now we can reload in the register */ - regs_allocated[reg] |= REG_IN_MASK; - op->reg = reg; - op->is_memory = 1; - } - } - break; - default: - tcc_error("asm constraint %d ('%s') could not be satisfied", - j, op->constraint); - break; - } - /* if a reference is present for that operand, we assign it too */ - if (op->input_index >= 0) { - operands[op->input_index].reg = op->reg; - operands[op->input_index].is_llong = op->is_llong; - } - } - - /* compute out_reg. It is used to store outputs registers to memory - locations references by pointers (VT_LLOCAL case) */ - *pout_reg = -1; - for(i=0;ireg >= 0 && - (op->vt->r & VT_VALMASK) == VT_LLOCAL && - !op->is_memory) { - for(reg = 0; reg < 8; reg++) { - if (!(regs_allocated[reg] & REG_OUT_MASK)) - goto reg_found2; - } - tcc_error("could not find free output register for reloading"); - reg_found2: - *pout_reg = reg; - break; - } - } - - /* print sorted constraints */ -#ifdef ASM_DEBUG - for(i=0;iid ? get_tok_str(op->id, NULL) : "", - op->constraint, - op->vt->r, - op->reg); - } - if (*pout_reg >= 0) - printf("out_reg=%d\n", *pout_reg); -#endif -} - -ST_FUNC void subst_asm_operand(CString *add_str, - SValue *sv, int modifier) -{ - int r, reg, size, val; - char buf[64]; - - r = sv->r; - if ((r & VT_VALMASK) == VT_CONST) { - if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n') - cstr_ccat(add_str, '$'); - if (r & VT_SYM) { - cstr_cat(add_str, get_tok_str(sv->sym->v, NULL)); - if ((uint32_t)sv->c.i != 0) { - cstr_ccat(add_str, '+'); - } else { - return; - } - } - val = sv->c.i; - if (modifier == 'n') - val = -val; - snprintf(buf, sizeof(buf), "%d", (int)sv->c.i); - cstr_cat(add_str, buf); - } else if ((r & VT_VALMASK) == VT_LOCAL) { - snprintf(buf, sizeof(buf), "%d(%%ebp)", (int)sv->c.i); - cstr_cat(add_str, buf); - } else if (r & VT_LVAL) { - reg = r & VT_VALMASK; - if (reg >= VT_CONST) - tcc_error("internal compiler error"); - snprintf(buf, sizeof(buf), "(%%%s)", - get_tok_str(TOK_ASM_eax + reg, NULL)); - cstr_cat(add_str, buf); - } else { - /* register case */ - reg = r & VT_VALMASK; - if (reg >= VT_CONST) - tcc_error("internal compiler error"); - - /* choose register operand size */ - if ((sv->type.t & VT_BTYPE) == VT_BYTE) - size = 1; - else if ((sv->type.t & VT_BTYPE) == VT_SHORT) - size = 2; -#ifdef TCC_TARGET_X86_64 - else if ((sv->type.t & VT_BTYPE) == VT_LLONG) - size = 8; -#endif - else - size = 4; - if (size == 1 && reg >= 4) - size = 4; - - if (modifier == 'b') { - if (reg >= 4) - tcc_error("cannot use byte register"); - size = 1; - } else if (modifier == 'h') { - if (reg >= 4) - tcc_error("cannot use byte register"); - size = -1; - } else if (modifier == 'w') { - size = 2; -#ifdef TCC_TARGET_X86_64 - } else if (modifier == 'q') { - size = 8; -#endif - } - - switch(size) { - case -1: - reg = TOK_ASM_ah + reg; - break; - case 1: - reg = TOK_ASM_al + reg; - break; - case 2: - reg = TOK_ASM_ax + reg; - break; - default: - reg = TOK_ASM_eax + reg; - break; -#ifdef TCC_TARGET_X86_64 - case 8: - reg = TOK_ASM_rax + reg; - break; -#endif - } - snprintf(buf, sizeof(buf), "%%%s", get_tok_str(reg, NULL)); - cstr_cat(add_str, buf); - } -} - -/* generate prolog and epilog code for asm statement */ -ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, - int nb_outputs, int is_output, - uint8_t *clobber_regs, - int out_reg) -{ - uint8_t regs_allocated[NB_ASM_REGS]; - ASMOperand *op; - int i, reg; - static uint8_t reg_saved[NB_SAVED_REGS] = { 3, 6, 7 }; - - /* mark all used registers */ - memcpy(regs_allocated, clobber_regs, sizeof(regs_allocated)); - for(i = 0; i < nb_operands;i++) { - op = &operands[i]; - if (op->reg >= 0) - regs_allocated[op->reg] = 1; - } - if (!is_output) { - /* generate reg save code */ - for(i = 0; i < NB_SAVED_REGS; i++) { - reg = reg_saved[i]; - if (regs_allocated[reg]) { -#ifdef I386_ASM_16 - if (tcc_state->seg_size == 16) - g(0x66); -#endif - g(0x50 + reg); - } - } - - /* generate load code */ - for(i = 0; i < nb_operands; i++) { - op = &operands[i]; - if (op->reg >= 0) { - if ((op->vt->r & VT_VALMASK) == VT_LLOCAL && - op->is_memory) { - /* memory reference case (for both input and - output cases) */ - SValue sv; - sv = *op->vt; - sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL; - load(op->reg, &sv); - } else if (i >= nb_outputs || op->is_rw) { - /* load value in register */ - load(op->reg, op->vt); - if (op->is_llong) { - SValue sv; - sv = *op->vt; - sv.c.i += 4; - load(TREG_XDX, &sv); - } - } - } - } - } else { - /* generate save code */ - for(i = 0 ; i < nb_outputs; i++) { - op = &operands[i]; - if (op->reg >= 0) { - if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) { - if (!op->is_memory) { - SValue sv; - sv = *op->vt; - sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL; - load(out_reg, &sv); - - sv.r = (sv.r & ~VT_VALMASK) | out_reg; - store(op->reg, &sv); - } - } else { - store(op->reg, op->vt); - if (op->is_llong) { - SValue sv; - sv = *op->vt; - sv.c.i += 4; - store(TREG_XDX, &sv); - } - } - } - } - /* generate reg restore code */ - for(i = NB_SAVED_REGS - 1; i >= 0; i--) { - reg = reg_saved[i]; - if (regs_allocated[reg]) { -#ifdef I386_ASM_16 - if (tcc_state->seg_size == 16) - g(0x66); -#endif - g(0x58 + reg); - } - } - } -} - -ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str) -{ - int reg; - TokenSym *ts; - - if (!strcmp(str, "memory") || - !strcmp(str, "cc")) - return; - ts = tok_alloc(str, strlen(str)); - reg = ts->tok; - if (reg >= TOK_ASM_eax && reg <= TOK_ASM_edi) { - reg -= TOK_ASM_eax; - } else if (reg >= TOK_ASM_ax && reg <= TOK_ASM_di) { - reg -= TOK_ASM_ax; -#ifdef TCC_TARGET_X86_64 - } else if (reg >= TOK_ASM_rax && reg <= TOK_ASM_rdi) { - reg -= TOK_ASM_rax; -#endif - } else { - tcc_error("invalid clobber register '%s'", str); - } - clobber_regs[reg] = 1; -} diff --git a/external/TCC/i386-asm.h b/external/TCC/i386-asm.h deleted file mode 100644 index 486cffe9..00000000 --- a/external/TCC/i386-asm.h +++ /dev/null @@ -1,500 +0,0 @@ - DEF_ASM_OP0(clc, 0xf8) /* must be first OP0 */ - DEF_ASM_OP0(cld, 0xfc) - DEF_ASM_OP0(cli, 0xfa) - DEF_ASM_OP0(clts, 0x0f06) - DEF_ASM_OP0(cmc, 0xf5) - DEF_ASM_OP0(lahf, 0x9f) - DEF_ASM_OP0(sahf, 0x9e) - DEF_ASM_OP0(pusha, 0x60) - DEF_ASM_OP0(popa, 0x61) - DEF_ASM_OP0(pushfl, 0x9c) - DEF_ASM_OP0(popfl, 0x9d) - DEF_ASM_OP0(pushf, 0x9c) - DEF_ASM_OP0(popf, 0x9d) - DEF_ASM_OP0(stc, 0xf9) - DEF_ASM_OP0(std, 0xfd) - DEF_ASM_OP0(sti, 0xfb) - DEF_ASM_OP0(aaa, 0x37) - DEF_ASM_OP0(aas, 0x3f) - DEF_ASM_OP0(daa, 0x27) - DEF_ASM_OP0(das, 0x2f) - DEF_ASM_OP0(aad, 0xd50a) - DEF_ASM_OP0(aam, 0xd40a) - DEF_ASM_OP0(cbw, 0x6698) - DEF_ASM_OP0(cwd, 0x6699) - DEF_ASM_OP0(cwde, 0x98) - DEF_ASM_OP0(cdq, 0x99) - DEF_ASM_OP0(cbtw, 0x6698) - DEF_ASM_OP0(cwtl, 0x98) - DEF_ASM_OP0(cwtd, 0x6699) - DEF_ASM_OP0(cltd, 0x99) - DEF_ASM_OP0(int3, 0xcc) - DEF_ASM_OP0(into, 0xce) - DEF_ASM_OP0(iret, 0xcf) - DEF_ASM_OP0(rsm, 0x0faa) - DEF_ASM_OP0(hlt, 0xf4) - DEF_ASM_OP0(nop, 0x90) - DEF_ASM_OP0(pause, 0xf390) - DEF_ASM_OP0(xlat, 0xd7) - - /* strings */ -ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL)) -ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL)) - -ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL)) -ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL)) - -ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL)) -ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL)) - -ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL)) -ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL)) - -ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL)) -ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL)) - -ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL)) -ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL)) - - /* bits */ - -ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW)) -ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW)) - -ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) - -ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) - -ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) - -ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) - - /* prefixes */ - DEF_ASM_OP0(wait, 0x9b) - DEF_ASM_OP0(fwait, 0x9b) -#ifdef I386_ASM_16 - DEF_ASM_OP0(a32, 0x67) - DEF_ASM_OP0(o32, 0x66) -#else - DEF_ASM_OP0(aword, 0x67) - DEF_ASM_OP0(addr16, 0x67) - ALT(DEF_ASM_OP0(word, 0x66)) - DEF_ASM_OP0(data16, 0x66) -#endif - DEF_ASM_OP0(lock, 0xf0) - DEF_ASM_OP0(rep, 0xf3) - DEF_ASM_OP0(repe, 0xf3) - DEF_ASM_OP0(repz, 0xf3) - DEF_ASM_OP0(repne, 0xf2) - DEF_ASM_OP0(repnz, 0xf2) - - DEF_ASM_OP0(invd, 0x0f08) - DEF_ASM_OP0(wbinvd, 0x0f09) - DEF_ASM_OP0(cpuid, 0x0fa2) - DEF_ASM_OP0(wrmsr, 0x0f30) - DEF_ASM_OP0(rdtsc, 0x0f31) - DEF_ASM_OP0(rdmsr, 0x0f32) - DEF_ASM_OP0(rdpmc, 0x0f33) - DEF_ASM_OP0(ud2, 0x0f0b) - - /* NOTE: we took the same order as gas opcode definition order */ -ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX)) -ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR)) -ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) -ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG)) -ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA)) - -ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG)) - -ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32)) -ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32)) -ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32)) -ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR)) -ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB)) -ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR)) - -ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16)) -ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW)) -ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32)) - -ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW)) -ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S)) -ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32)) -ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG)) - -ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW)) -ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG)) - -ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX)) -ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG)) -ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) - -ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX)) -ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8)) -ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX)) -ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX)) - -ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8)) -ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8)) -ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX)) -ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX)) - -ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG)) - -ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32)) - - /* arith */ -ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */ -ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) -ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX)) -ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG)) - -ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) -ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX)) -ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG)) - -ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW)) -ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) -ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW)) -ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) - -ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) -ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) - -ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) -ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) - -ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG)) -ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW)) -ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW)) -ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW)) -ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW)) - -ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) -ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX)) -ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) -ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX)) - - /* shifts */ -ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG)) - -ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) -ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) -ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW)) -ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) -ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) -ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW)) - -ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR)) -ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR)) -ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR)) -ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR)) -#ifdef I386_ASM_16 -ALT(DEF_ASM_OP1(jmp, 0xff, 0, OPC_JMP | OPC_WL, OPT_REGW)) -#endif - -ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32)) -ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA)) -ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32)) -ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA)) - -ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8)) -ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA)) -ALT(DEF_ASM_OP1(setob, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA)) - DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8) - DEF_ASM_OP0(leave, 0xc9) - DEF_ASM_OP0(ret, 0xc3) - DEF_ASM_OP0(retl,0xc3) -ALT(DEF_ASM_OP1(retl,0xc2, 0, 0, OPT_IM16)) -ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16)) - DEF_ASM_OP0(lret, 0xcb) -ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16)) - -ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR)) - DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR) - - /* float */ - /* specific fcomp handling */ -ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0)) - -ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST)) -ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0)) -ALT(DEF_ASM_OP2(fadd, 0xdcc0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST)) -ALT(DEF_ASM_OP2(fmul, 0xdcc8, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST)) -ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH)) -ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST)) -ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0)) -ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST)) -ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH)) -ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) -ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) -ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) -ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) - - DEF_ASM_OP0(fucompp, 0xdae9) - DEF_ASM_OP0(ftst, 0xd9e4) - DEF_ASM_OP0(fxam, 0xd9e5) - DEF_ASM_OP0(fld1, 0xd9e8) - DEF_ASM_OP0(fldl2t, 0xd9e9) - DEF_ASM_OP0(fldl2e, 0xd9ea) - DEF_ASM_OP0(fldpi, 0xd9eb) - DEF_ASM_OP0(fldlg2, 0xd9ec) - DEF_ASM_OP0(fldln2, 0xd9ed) - DEF_ASM_OP0(fldz, 0xd9ee) - - DEF_ASM_OP0(f2xm1, 0xd9f0) - DEF_ASM_OP0(fyl2x, 0xd9f1) - DEF_ASM_OP0(fptan, 0xd9f2) - DEF_ASM_OP0(fpatan, 0xd9f3) - DEF_ASM_OP0(fxtract, 0xd9f4) - DEF_ASM_OP0(fprem1, 0xd9f5) - DEF_ASM_OP0(fdecstp, 0xd9f6) - DEF_ASM_OP0(fincstp, 0xd9f7) - DEF_ASM_OP0(fprem, 0xd9f8) - DEF_ASM_OP0(fyl2xp1, 0xd9f9) - DEF_ASM_OP0(fsqrt, 0xd9fa) - DEF_ASM_OP0(fsincos, 0xd9fb) - DEF_ASM_OP0(frndint, 0xd9fc) - DEF_ASM_OP0(fscale, 0xd9fd) - DEF_ASM_OP0(fsin, 0xd9fe) - DEF_ASM_OP0(fcos, 0xd9ff) - DEF_ASM_OP0(fchs, 0xd9e0) - DEF_ASM_OP0(fabs, 0xd9e1) - DEF_ASM_OP0(fninit, 0xdbe3) - DEF_ASM_OP0(fnclex, 0xdbe2) - DEF_ASM_OP0(fnop, 0xd9d0) - - /* fp load */ - DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST) - DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST) - DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA) -ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA)) - DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA) - DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA) - - /* fp store */ - DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST) - DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST) - DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA) -ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA)) - DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA) - - DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST) - DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA) - - /* exchange */ - DEF_ASM_OP0(fxch, 0xd9c9) -ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST)) - - /* misc FPU */ - DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST ) - DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST ) - - DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT) - DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA ) - DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA ) - DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ) - DEF_ASM_OP0(fnstsw, 0xdfe0) -ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX )) -ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA )) - DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX ) -ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT)) -ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )) - DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT) - DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA ) - DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA ) - DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA ) - DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA ) - DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA ) - DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA ) - DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST ) - DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST ) - DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA ) - DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA ) - - /* segments */ - DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA) - DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32) - DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG) - DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG) -ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG)) - DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG) - DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA) - DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA) - DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA) - DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA) - DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA) - -#ifdef I386_ASM_16 - /* 386 */ - DEF_ASM_OP0(loadall386, 0x0f07) -#endif - - /* 486 */ - DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 ) -ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA )) -ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA )) - DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA ) - - DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA) - DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA) - - /* pentium */ - DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA ) - - /* pentium pro */ - ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) -#ifdef I386_ASM_16 -ALT(DEF_ASM_OP2(cmovno, 0x0f41, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(cmovc, 0x0f42, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(cmovnc, 0x0f43, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(cmovz, 0x0f44, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(cmovnz, 0x0f45, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(cmovna, 0x0f46, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(cmova, 0x0f47, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) -#endif - DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 ) - DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 ) - DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 ) - DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 ) - DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 ) - DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 ) - DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 ) - DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 ) - - DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 ) - DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 ) - DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 ) - DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 ) - - /* mmx */ - DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */ - - DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX ) -ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 )) - DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX )) - DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - - /* sse */ - DEF_ASM_OP2(movups, 0x0f10, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE ) -ALT(DEF_ASM_OP2(movups, 0x0f11, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 )) - DEF_ASM_OP2(movaps, 0x0f28, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE ) -ALT(DEF_ASM_OP2(movaps, 0x0f29, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 )) - DEF_ASM_OP2(movhps, 0x0f16, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE ) -ALT(DEF_ASM_OP2(movhps, 0x0f17, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 )) - DEF_ASM_OP2(addps, 0x0f58, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) - DEF_ASM_OP2(cvtpi2ps, 0x0f2a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_SSE ) - DEF_ASM_OP2(cvtps2pi, 0x0f2d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX ) - DEF_ASM_OP2(cvttps2pi, 0x0f2c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX ) - DEF_ASM_OP2(divps, 0x0f5e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) - DEF_ASM_OP2(maxps, 0x0f5f, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) - DEF_ASM_OP2(minps, 0x0f5d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) - DEF_ASM_OP2(mulps, 0x0f59, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) - DEF_ASM_OP2(pavgb, 0x0fe0, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) - DEF_ASM_OP2(pavgw, 0x0fe3, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) - DEF_ASM_OP2(pmaxsw, 0x0fee, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pmaxub, 0x0fde, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pminsw, 0x0fea, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pminub, 0x0fda, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(rcpss, 0x0f53, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) - DEF_ASM_OP2(rsqrtps, 0x0f52, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) - DEF_ASM_OP2(sqrtps, 0x0f51, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) - DEF_ASM_OP2(subps, 0x0f5c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) - -#undef ALT -#undef DEF_ASM_OP0 -#undef DEF_ASM_OP0L -#undef DEF_ASM_OP1 -#undef DEF_ASM_OP2 -#undef DEF_ASM_OP3 diff --git a/external/TCC/i386-gen.c b/external/TCC/i386-gen.c deleted file mode 100644 index c18b9c34..00000000 --- a/external/TCC/i386-gen.c +++ /dev/null @@ -1,1134 +0,0 @@ -/* - * X86 code generator for TCC - * - * Copyright (c) 2001-2004 Fabrice Bellard - * - * 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef TARGET_DEFS_ONLY - -/* number of available registers */ -#define NB_REGS 4 -#define NB_ASM_REGS 8 - -/* a register can belong to several classes. The classes must be - sorted from more general to more precise (see gv2() code which does - assumptions on it). */ -#define RC_INT 0x0001 /* generic integer register */ -#define RC_FLOAT 0x0002 /* generic float register */ -#define RC_EAX 0x0004 -#define RC_ST0 0x0008 -#define RC_ECX 0x0010 -#define RC_EDX 0x0020 -#define RC_IRET RC_EAX /* function return: integer register */ -#define RC_LRET RC_EDX /* function return: second integer register */ -#define RC_FRET RC_ST0 /* function return: float register */ - -/* pretty names for the registers */ -enum { - TREG_EAX = 0, - TREG_ECX, - TREG_EDX, - TREG_ST0, - TREG_ESP = 4 -}; - -/* return registers for function */ -#define REG_IRET TREG_EAX /* single word int return register */ -#define REG_LRET TREG_EDX /* second word return register (for long long) */ -#define REG_FRET TREG_ST0 /* float return register */ - -/* defined if function parameters must be evaluated in reverse order */ -#define INVERT_FUNC_PARAMS - -/* defined if structures are passed as pointers. Otherwise structures - are directly pushed on stack. */ -/* #define FUNC_STRUCT_PARAM_AS_PTR */ - -/* pointer size, in bytes */ -#define PTR_SIZE 4 - -/* long double size and alignment, in bytes */ -#define LDOUBLE_SIZE 12 -#define LDOUBLE_ALIGN 4 -/* maximum alignment (for aligned attribute support) */ -#define MAX_ALIGN 8 - - -#define psym oad - -/******************************************************/ -/* ELF defines */ - -#define EM_TCC_TARGET EM_386 - -/* relocation type for 32 bit data relocation */ -#define R_DATA_32 R_386_32 -#define R_DATA_PTR R_386_32 -#define R_JMP_SLOT R_386_JMP_SLOT -#define R_COPY R_386_COPY - -#define ELF_START_ADDR 0x08048000 -#define ELF_PAGE_SIZE 0x1000 - -/******************************************************/ -#else /* ! TARGET_DEFS_ONLY */ -/******************************************************/ -#include "tcc.h" - -ST_DATA const int reg_classes[NB_REGS] = { - /* eax */ RC_INT | RC_EAX, - /* ecx */ RC_INT | RC_ECX, - /* edx */ RC_INT | RC_EDX, - /* st0 */ RC_FLOAT | RC_ST0, -}; - -static unsigned long func_sub_sp_offset; -static int func_ret_sub; -#ifdef CONFIG_TCC_BCHECK -static addr_t func_bound_offset; -#endif - -/* XXX: make it faster ? */ -ST_FUNC void g(int c) -{ - int ind1; - ind1 = ind + 1; - if (ind1 > cur_text_section->data_allocated) - section_realloc(cur_text_section, ind1); - cur_text_section->data[ind] = c; - ind = ind1; -} - -ST_FUNC void o(unsigned int c) -{ - while (c) { - g(c); - c = c >> 8; - } -} - -ST_FUNC void gen_le16(int v) -{ - g(v); - g(v >> 8); -} - -ST_FUNC void gen_le32(int c) -{ - g(c); - g(c >> 8); - g(c >> 16); - g(c >> 24); -} - -/* output a symbol and patch all calls to it */ -ST_FUNC void gsym_addr(int t, int a) -{ - while (t) { - unsigned char *ptr = cur_text_section->data + t; - uint32_t n = read32le(ptr); /* next value */ - write32le(ptr, a - t - 4); - t = n; - } -} - -ST_FUNC void gsym(int t) -{ - gsym_addr(t, ind); -} - -/* psym is used to put an instruction with a data field which is a - reference to a symbol. It is in fact the same as oad ! */ -#define psym oad - -/* instruction + 4 bytes data. Return the address of the data */ -ST_FUNC int oad(int c, int s) -{ - int ind1; - - o(c); - ind1 = ind + 4; - if (ind1 > cur_text_section->data_allocated) - section_realloc(cur_text_section, ind1); - write32le(cur_text_section->data + ind, s); - s = ind; - ind = ind1; - return s; -} - -/* output constant with relocation if 'r & VT_SYM' is true */ -ST_FUNC void gen_addr32(int r, Sym *sym, int c) -{ - if (r & VT_SYM) - greloc(cur_text_section, sym, ind, R_386_32); - gen_le32(c); -} - -ST_FUNC void gen_addrpc32(int r, Sym *sym, int c) -{ - if (r & VT_SYM) - greloc(cur_text_section, sym, ind, R_386_PC32); - gen_le32(c - 4); -} - -/* generate a modrm reference. 'op_reg' contains the addtionnal 3 - opcode bits */ -static void gen_modrm(int op_reg, int r, Sym *sym, int c) -{ - op_reg = op_reg << 3; - if ((r & VT_VALMASK) == VT_CONST) { - /* constant memory reference */ - o(0x05 | op_reg); - gen_addr32(r, sym, c); - } else if ((r & VT_VALMASK) == VT_LOCAL) { - /* currently, we use only ebp as base */ - if (c == (char)c) { - /* short reference */ - o(0x45 | op_reg); - g(c); - } else { - oad(0x85 | op_reg, c); - } - } else { - g(0x00 | op_reg | (r & VT_VALMASK)); - } -} - -/* load 'r' from value 'sv' */ -ST_FUNC void load(int r, SValue *sv) -{ - int v, t, ft, fc, fr; - SValue v1; - -#ifdef TCC_TARGET_PE - SValue v2; - sv = pe_getimport(sv, &v2); -#endif - - fr = sv->r; - ft = sv->type.t; - fc = sv->c.i; - - v = fr & VT_VALMASK; - if (fr & VT_LVAL) { - if (v == VT_LLOCAL) { - v1.type.t = VT_INT; - v1.r = VT_LOCAL | VT_LVAL; - v1.c.i = fc; - fr = r; - if (!(reg_classes[fr] & RC_INT)) - fr = get_reg(RC_INT); - load(fr, &v1); - } - if ((ft & VT_BTYPE) == VT_FLOAT) { - o(0xd9); /* flds */ - r = 0; - } else if ((ft & VT_BTYPE) == VT_DOUBLE) { - o(0xdd); /* fldl */ - r = 0; - } else if ((ft & VT_BTYPE) == VT_LDOUBLE) { - o(0xdb); /* fldt */ - r = 5; - } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) { - o(0xbe0f); /* movsbl */ - } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) { - o(0xb60f); /* movzbl */ - } else if ((ft & VT_TYPE) == VT_SHORT) { - o(0xbf0f); /* movswl */ - } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) { - o(0xb70f); /* movzwl */ - } else { - o(0x8b); /* movl */ - } - gen_modrm(r, fr, sv->sym, fc); - } else { - if (v == VT_CONST) { - o(0xb8 + r); /* mov $xx, r */ - gen_addr32(fr, sv->sym, fc); - } else if (v == VT_LOCAL) { - if (fc) { - o(0x8d); /* lea xxx(%ebp), r */ - gen_modrm(r, VT_LOCAL, sv->sym, fc); - } else { - o(0x89); - o(0xe8 + r); /* mov %ebp, r */ - } - } else if (v == VT_CMP) { - oad(0xb8 + r, 0); /* mov $0, r */ - o(0x0f); /* setxx %br */ - o(fc); - o(0xc0 + r); - } else if (v == VT_JMP || v == VT_JMPI) { - t = v & 1; - oad(0xb8 + r, t); /* mov $1, r */ - o(0x05eb); /* jmp after */ - gsym(fc); - oad(0xb8 + r, t ^ 1); /* mov $0, r */ - } else if (v != r) { - o(0x89); - o(0xc0 + r + v * 8); /* mov v, r */ - } - } -} - -/* store register 'r' in lvalue 'v' */ -ST_FUNC void store(int r, SValue *v) -{ - int fr, bt, ft, fc; - -#ifdef TCC_TARGET_PE - SValue v2; - v = pe_getimport(v, &v2); -#endif - - ft = v->type.t; - fc = v->c.i; - fr = v->r & VT_VALMASK; - bt = ft & VT_BTYPE; - /* XXX: incorrect if float reg to reg */ - if (bt == VT_FLOAT) { - o(0xd9); /* fsts */ - r = 2; - } else if (bt == VT_DOUBLE) { - o(0xdd); /* fstpl */ - r = 2; - } else if (bt == VT_LDOUBLE) { - o(0xc0d9); /* fld %st(0) */ - o(0xdb); /* fstpt */ - r = 7; - } else { - if (bt == VT_SHORT) - o(0x66); - if (bt == VT_BYTE || bt == VT_BOOL) - o(0x88); - else - o(0x89); - } - if (fr == VT_CONST || - fr == VT_LOCAL || - (v->r & VT_LVAL)) { - gen_modrm(r, v->r, v->sym, fc); - } else if (fr != r) { - o(0xc0 + fr + r * 8); /* mov r, fr */ - } -} - -static void gadd_sp(int val) -{ - if (val == (char)val) { - o(0xc483); - g(val); - } else { - oad(0xc481, val); /* add $xxx, %esp */ - } -} - -static void gen_static_call(int v) -{ - Sym *sym; - - sym = external_global_sym(v, &func_old_type, 0); - oad(0xe8, -4); - greloc(cur_text_section, sym, ind-4, R_386_PC32); -} - -/* 'is_jmp' is '1' if it is a jump */ -static void gcall_or_jmp(int is_jmp) -{ - int r; - if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { - /* constant case */ - if (vtop->r & VT_SYM) { - /* relocation case */ - greloc(cur_text_section, vtop->sym, - ind + 1, R_386_PC32); - } else { - /* put an empty PC32 relocation */ - put_elf_reloc(symtab_section, cur_text_section, - ind + 1, R_386_PC32, 0); - } - oad(0xe8 + is_jmp, vtop->c.i - 4); /* call/jmp im */ - } else { - /* otherwise, indirect call */ - r = gv(RC_INT); - o(0xff); /* call/jmp *r */ - o(0xd0 + r + (is_jmp << 4)); - } -} - -static uint8_t fastcall_regs[3] = { TREG_EAX, TREG_EDX, TREG_ECX }; -static uint8_t fastcallw_regs[2] = { TREG_ECX, TREG_EDX }; - -/* Return the number of registers needed to return the struct, or 0 if - returning via struct pointer. */ -ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize) -{ -#ifdef TCC_TARGET_PE - int size, align; - - *ret_align = 1; // Never have to re-align return values for x86 - *regsize = 4; - size = type_size(vt, &align); - if (size > 8) { - return 0; - } else if (size > 4) { - ret->ref = NULL; - ret->t = VT_LLONG; - return 1; - } else { - ret->ref = NULL; - ret->t = VT_INT; - return 1; - } -#else - *ret_align = 1; // Never have to re-align return values for x86 - return 0; -#endif -} - -/* Generate function call. The function address is pushed first, then - all the parameters in call order. This functions pops all the - parameters and the function address. */ -ST_FUNC void gfunc_call(int nb_args) -{ - int size, align, r, args_size, i, func_call; - Sym *func_sym; - - args_size = 0; - for(i = 0;i < nb_args; i++) { - if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { - size = type_size(&vtop->type, &align); - /* align to stack align size */ - size = (size + 3) & ~3; - /* allocate the necessary size on stack */ - oad(0xec81, size); /* sub $xxx, %esp */ - /* generate structure store */ - r = get_reg(RC_INT); - o(0x89); /* mov %esp, r */ - o(0xe0 + r); - vset(&vtop->type, r | VT_LVAL, 0); - vswap(); - vstore(); - args_size += size; - } else if (is_float(vtop->type.t)) { - gv(RC_FLOAT); /* only one float register */ - if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) - size = 4; - else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) - size = 8; - else - size = 12; - oad(0xec81, size); /* sub $xxx, %esp */ - if (size == 12) - o(0x7cdb); - else - o(0x5cd9 + size - 4); /* fstp[s|l] 0(%esp) */ - g(0x24); - g(0x00); - args_size += size; - } else { - /* simple type (currently always same size) */ - /* XXX: implicit cast ? */ - r = gv(RC_INT); - if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { - size = 8; - o(0x50 + vtop->r2); /* push r */ - } else { - size = 4; - } - o(0x50 + r); /* push r */ - args_size += size; - } - vtop--; - } - save_regs(0); /* save used temporary registers */ - func_sym = vtop->type.ref; - func_call = func_sym->a.func_call; - /* fast call case */ - if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) || - func_call == FUNC_FASTCALLW) { - int fastcall_nb_regs; - uint8_t *fastcall_regs_ptr; - if (func_call == FUNC_FASTCALLW) { - fastcall_regs_ptr = fastcallw_regs; - fastcall_nb_regs = 2; - } else { - fastcall_regs_ptr = fastcall_regs; - fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1; - } - for(i = 0;i < fastcall_nb_regs; i++) { - if (args_size <= 0) - break; - o(0x58 + fastcall_regs_ptr[i]); /* pop r */ - /* XXX: incorrect for struct/floats */ - args_size -= 4; - } - } -#ifndef TCC_TARGET_PE - else if ((vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT) - args_size -= 4; -#endif - gcall_or_jmp(0); - - if (args_size && func_call != FUNC_STDCALL) - gadd_sp(args_size); - vtop--; -} - -#ifdef TCC_TARGET_PE -#define FUNC_PROLOG_SIZE 10 -#else -#define FUNC_PROLOG_SIZE 9 -#endif - -/* generate function prolog of type 't' */ -ST_FUNC void gfunc_prolog(CType *func_type) -{ - int addr, align, size, func_call, fastcall_nb_regs; - int param_index, param_addr; - uint8_t *fastcall_regs_ptr; - Sym *sym; - CType *type; - - sym = func_type->ref; - func_call = sym->a.func_call; - addr = 8; - loc = 0; - func_vc = 0; - - if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) { - fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1; - fastcall_regs_ptr = fastcall_regs; - } else if (func_call == FUNC_FASTCALLW) { - fastcall_nb_regs = 2; - fastcall_regs_ptr = fastcallw_regs; - } else { - fastcall_nb_regs = 0; - fastcall_regs_ptr = NULL; - } - param_index = 0; - - ind += FUNC_PROLOG_SIZE; - func_sub_sp_offset = ind; - /* if the function returns a structure, then add an - implicit pointer parameter */ - func_vt = sym->type; - func_var = (sym->c == FUNC_ELLIPSIS); -#ifdef TCC_TARGET_PE - size = type_size(&func_vt,&align); - if (((func_vt.t & VT_BTYPE) == VT_STRUCT) && (size > 8)) { -#else - if ((func_vt.t & VT_BTYPE) == VT_STRUCT) { -#endif - /* XXX: fastcall case ? */ - func_vc = addr; - addr += 4; - param_index++; - } - /* define parameters */ - while ((sym = sym->next) != NULL) { - type = &sym->type; - size = type_size(type, &align); - size = (size + 3) & ~3; -#ifdef FUNC_STRUCT_PARAM_AS_PTR - /* structs are passed as pointer */ - if ((type->t & VT_BTYPE) == VT_STRUCT) { - size = 4; - } -#endif - if (param_index < fastcall_nb_regs) { - /* save FASTCALL register */ - loc -= 4; - o(0x89); /* movl */ - gen_modrm(fastcall_regs_ptr[param_index], VT_LOCAL, NULL, loc); - param_addr = loc; - } else { - param_addr = addr; - addr += size; - } - sym_push(sym->v & ~SYM_FIELD, type, - VT_LOCAL | lvalue_type(type->t), param_addr); - param_index++; - } - func_ret_sub = 0; - /* pascal type call ? */ - if (func_call == FUNC_STDCALL) - func_ret_sub = addr - 8; -#ifndef TCC_TARGET_PE - else if (func_vc) - func_ret_sub = 4; -#endif - -#ifdef CONFIG_TCC_BCHECK - /* leave some room for bound checking code */ - if (tcc_state->do_bounds_check) { - oad(0xb8, 0); /* lbound section pointer */ - oad(0xb8, 0); /* call to function */ - func_bound_offset = lbounds_section->data_offset; - } -#endif -} - -/* generate function epilog */ -ST_FUNC void gfunc_epilog(void) -{ - addr_t v, saved_ind; - -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check - && func_bound_offset != lbounds_section->data_offset) { - addr_t saved_ind; - addr_t *bounds_ptr; - Sym *sym_data; - /* add end of table info */ - bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t)); - *bounds_ptr = 0; - /* generate bound local allocation */ - saved_ind = ind; - ind = func_sub_sp_offset; - sym_data = get_sym_ref(&char_pointer_type, lbounds_section, - func_bound_offset, lbounds_section->data_offset); - greloc(cur_text_section, sym_data, - ind + 1, R_386_32); - oad(0xb8, 0); /* mov %eax, xxx */ - gen_static_call(TOK___bound_local_new); - - ind = saved_ind; - /* generate bound check local freeing */ - o(0x5250); /* save returned value, if any */ - greloc(cur_text_section, sym_data, - ind + 1, R_386_32); - oad(0xb8, 0); /* mov %eax, xxx */ - gen_static_call(TOK___bound_local_delete); - - o(0x585a); /* restore returned value, if any */ - } -#endif - o(0xc9); /* leave */ - if (func_ret_sub == 0) { - o(0xc3); /* ret */ - } else { - o(0xc2); /* ret n */ - g(func_ret_sub); - g(func_ret_sub >> 8); - } - /* align local size to word & save local variables */ - - v = (-loc + 3) & -4; - saved_ind = ind; - ind = func_sub_sp_offset - FUNC_PROLOG_SIZE; -#ifdef TCC_TARGET_PE - if (v >= 4096) { - oad(0xb8, v); /* mov stacksize, %eax */ - gen_static_call(TOK___chkstk); /* call __chkstk, (does the stackframe too) */ - } else -#endif - { - o(0xe58955); /* push %ebp, mov %esp, %ebp */ - o(0xec81); /* sub esp, stacksize */ - gen_le32(v); -#if FUNC_PROLOG_SIZE == 10 - o(0x90); /* adjust to FUNC_PROLOG_SIZE */ -#endif - } - ind = saved_ind; -} - -/* generate a jump to a label */ -ST_FUNC int gjmp(int t) -{ - return psym(0xe9, t); -} - -/* generate a jump to a fixed address */ -ST_FUNC void gjmp_addr(int a) -{ - int r; - r = a - ind - 2; - if (r == (char)r) { - g(0xeb); - g(r); - } else { - oad(0xe9, a - ind - 5); - } -} - -/* generate a test. set 'inv' to invert test. Stack entry is popped */ -ST_FUNC int gtst(int inv, int t) -{ - int v = vtop->r & VT_VALMASK; - if (v == VT_CMP) { - /* fast case : can jump directly since flags are set */ - g(0x0f); - t = psym((vtop->c.i - 16) ^ inv, t); - } else if (v == VT_JMP || v == VT_JMPI) { - /* && or || optimization */ - if ((v & 1) == inv) { - /* insert vtop->c jump list in t */ - uint32_t n1, n = vtop->c.i; - if (n) { - while ((n1 = read32le(cur_text_section->data + n))) - n = n1; - write32le(cur_text_section->data + n, t); - t = vtop->c.i; - } - } else { - t = gjmp(t); - gsym(vtop->c.i); - } - } - vtop--; - return t; -} - -/* generate an integer binary operation */ -ST_FUNC void gen_opi(int op) -{ - int r, fr, opc, c; - - switch(op) { - case '+': - case TOK_ADDC1: /* add with carry generation */ - opc = 0; - gen_op8: - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - /* constant case */ - vswap(); - r = gv(RC_INT); - vswap(); - c = vtop->c.i; - if (c == (char)c) { - /* generate inc and dec for smaller code */ - if (c==1 && opc==0) { - o (0x40 | r); // inc - } else if (c==1 && opc==5) { - o (0x48 | r); // dec - } else { - o(0x83); - o(0xc0 | (opc << 3) | r); - g(c); - } - } else { - o(0x81); - oad(0xc0 | (opc << 3) | r, c); - } - } else { - gv2(RC_INT, RC_INT); - r = vtop[-1].r; - fr = vtop[0].r; - o((opc << 3) | 0x01); - o(0xc0 + r + fr * 8); - } - vtop--; - if (op >= TOK_ULT && op <= TOK_GT) { - vtop->r = VT_CMP; - vtop->c.i = op; - } - break; - case '-': - case TOK_SUBC1: /* sub with carry generation */ - opc = 5; - goto gen_op8; - case TOK_ADDC2: /* add with carry use */ - opc = 2; - goto gen_op8; - case TOK_SUBC2: /* sub with carry use */ - opc = 3; - goto gen_op8; - case '&': - opc = 4; - goto gen_op8; - case '^': - opc = 6; - goto gen_op8; - case '|': - opc = 1; - goto gen_op8; - case '*': - gv2(RC_INT, RC_INT); - r = vtop[-1].r; - fr = vtop[0].r; - vtop--; - o(0xaf0f); /* imul fr, r */ - o(0xc0 + fr + r * 8); - break; - case TOK_SHL: - opc = 4; - goto gen_shift; - case TOK_SHR: - opc = 5; - goto gen_shift; - case TOK_SAR: - opc = 7; - gen_shift: - opc = 0xc0 | (opc << 3); - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - /* constant case */ - vswap(); - r = gv(RC_INT); - vswap(); - c = vtop->c.i & 0x1f; - o(0xc1); /* shl/shr/sar $xxx, r */ - o(opc | r); - g(c); - } else { - /* we generate the shift in ecx */ - gv2(RC_INT, RC_ECX); - r = vtop[-1].r; - o(0xd3); /* shl/shr/sar %cl, r */ - o(opc | r); - } - vtop--; - break; - case '/': - case TOK_UDIV: - case TOK_PDIV: - case '%': - case TOK_UMOD: - case TOK_UMULL: - /* first operand must be in eax */ - /* XXX: need better constraint for second operand */ - gv2(RC_EAX, RC_ECX); - r = vtop[-1].r; - fr = vtop[0].r; - vtop--; - save_reg(TREG_EDX); - if (op == TOK_UMULL) { - o(0xf7); /* mul fr */ - o(0xe0 + fr); - vtop->r2 = TREG_EDX; - r = TREG_EAX; - } else { - if (op == TOK_UDIV || op == TOK_UMOD) { - o(0xf7d231); /* xor %edx, %edx, div fr, %eax */ - o(0xf0 + fr); - } else { - o(0xf799); /* cltd, idiv fr, %eax */ - o(0xf8 + fr); - } - if (op == '%' || op == TOK_UMOD) - r = TREG_EDX; - else - r = TREG_EAX; - } - vtop->r = r; - break; - default: - opc = 7; - goto gen_op8; - } -} - -/* generate a floating point operation 'v = t1 op t2' instruction. The - two operands are guaranted to have the same floating point type */ -/* XXX: need to use ST1 too */ -ST_FUNC void gen_opf(int op) -{ - int a, ft, fc, swapped, r; - - /* convert constants to memory references */ - if ((vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { - vswap(); - gv(RC_FLOAT); - vswap(); - } - if ((vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) - gv(RC_FLOAT); - - /* must put at least one value in the floating point register */ - if ((vtop[-1].r & VT_LVAL) && - (vtop[0].r & VT_LVAL)) { - vswap(); - gv(RC_FLOAT); - vswap(); - } - swapped = 0; - /* swap the stack if needed so that t1 is the register and t2 is - the memory reference */ - if (vtop[-1].r & VT_LVAL) { - vswap(); - swapped = 1; - } - if (op >= TOK_ULT && op <= TOK_GT) { - /* load on stack second operand */ - load(TREG_ST0, vtop); - save_reg(TREG_EAX); /* eax is used by FP comparison code */ - if (op == TOK_GE || op == TOK_GT) - swapped = !swapped; - else if (op == TOK_EQ || op == TOK_NE) - swapped = 0; - if (swapped) - o(0xc9d9); /* fxch %st(1) */ - if (op == TOK_EQ || op == TOK_NE) - o(0xe9da); /* fucompp */ - else - o(0xd9de); /* fcompp */ - o(0xe0df); /* fnstsw %ax */ - if (op == TOK_EQ) { - o(0x45e480); /* and $0x45, %ah */ - o(0x40fC80); /* cmp $0x40, %ah */ - } else if (op == TOK_NE) { - o(0x45e480); /* and $0x45, %ah */ - o(0x40f480); /* xor $0x40, %ah */ - op = TOK_NE; - } else if (op == TOK_GE || op == TOK_LE) { - o(0x05c4f6); /* test $0x05, %ah */ - op = TOK_EQ; - } else { - o(0x45c4f6); /* test $0x45, %ah */ - op = TOK_EQ; - } - vtop--; - vtop->r = VT_CMP; - vtop->c.i = op; - } else { - /* no memory reference possible for long double operations */ - if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { - load(TREG_ST0, vtop); - swapped = !swapped; - } - - switch(op) { - default: - case '+': - a = 0; - break; - case '-': - a = 4; - if (swapped) - a++; - break; - case '*': - a = 1; - break; - case '/': - a = 6; - if (swapped) - a++; - break; - } - ft = vtop->type.t; - fc = vtop->c.i; - if ((ft & VT_BTYPE) == VT_LDOUBLE) { - o(0xde); /* fxxxp %st, %st(1) */ - o(0xc1 + (a << 3)); - } else { - /* if saved lvalue, then we must reload it */ - r = vtop->r; - if ((r & VT_VALMASK) == VT_LLOCAL) { - SValue v1; - r = get_reg(RC_INT); - v1.type.t = VT_INT; - v1.r = VT_LOCAL | VT_LVAL; - v1.c.i = fc; - load(r, &v1); - fc = 0; - } - - if ((ft & VT_BTYPE) == VT_DOUBLE) - o(0xdc); - else - o(0xd8); - gen_modrm(a, r, vtop->sym, fc); - } - vtop--; - } -} - -/* convert integers to fp 't' type. Must handle 'int', 'unsigned int' - and 'long long' cases. */ -ST_FUNC void gen_cvt_itof(int t) -{ - save_reg(TREG_ST0); - gv(RC_INT); - if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { - /* signed long long to float/double/long double (unsigned case - is handled generically) */ - o(0x50 + vtop->r2); /* push r2 */ - o(0x50 + (vtop->r & VT_VALMASK)); /* push r */ - o(0x242cdf); /* fildll (%esp) */ - o(0x08c483); /* add $8, %esp */ - } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == - (VT_INT | VT_UNSIGNED)) { - /* unsigned int to float/double/long double */ - o(0x6a); /* push $0 */ - g(0x00); - o(0x50 + (vtop->r & VT_VALMASK)); /* push r */ - o(0x242cdf); /* fildll (%esp) */ - o(0x08c483); /* add $8, %esp */ - } else { - /* int to float/double/long double */ - o(0x50 + (vtop->r & VT_VALMASK)); /* push r */ - o(0x2404db); /* fildl (%esp) */ - o(0x04c483); /* add $4, %esp */ - } - vtop->r = TREG_ST0; -} - -/* convert fp to int 't' type */ -ST_FUNC void gen_cvt_ftoi(int t) -{ - #ifndef COMMIT_4ad186c5ef61_IS_FIXED - /* a good version but it takes a more time to execute */ - gv(RC_FLOAT); - save_reg(TREG_EAX); - save_reg(TREG_EDX); - gen_static_call(TOK___tcc_cvt_ftol); - vtop->r = TREG_EAX; /* mark reg as used */ - if (t == VT_LLONG) - vtop->r2 = TREG_EDX; - #else - /* a new version with a bug: t2a = 44100312 */ - /* - #include - int main() { - int t1 = 176401255; - float f = 0.25f; - int t2a = (int)(t1 * f); // must be 44100313 - int t2b = (int)(t1 * (float)0.25f); - printf("t2a=%d t2b=%d \n",t2a,t2b); - return 0; - } - */ - int bt = vtop->type.t & VT_BTYPE; - if (bt == VT_FLOAT) - vpush_global_sym(&func_old_type, TOK___fixsfdi); - else if (bt == VT_LDOUBLE) - vpush_global_sym(&func_old_type, TOK___fixxfdi); - else - vpush_global_sym(&func_old_type, TOK___fixdfdi); - vswap(); - gfunc_call(1); - vpushi(0); - vtop->r = REG_IRET; - vtop->r2 = REG_LRET; - #endif -} - -/* convert from one floating point type to another */ -ST_FUNC void gen_cvt_ftof(int t) -{ - /* all we have to do on i386 is to put the float in a register */ - gv(RC_FLOAT); -} - -/* computed goto support */ -ST_FUNC void ggoto(void) -{ - gcall_or_jmp(1); - vtop--; -} - -/* bound check support functions */ -#ifdef CONFIG_TCC_BCHECK - -/* generate a bounded pointer addition */ -ST_FUNC void gen_bounded_ptr_add(void) -{ - /* prepare fast i386 function call (args in eax and edx) */ - gv2(RC_EAX, RC_EDX); - /* save all temporary registers */ - vtop -= 2; - save_regs(0); - /* do a fast function call */ - gen_static_call(TOK___bound_ptr_add); - /* returned pointer is in eax */ - vtop++; - vtop->r = TREG_EAX | VT_BOUNDED; - /* address of bounding function call point */ - vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel)); -} - -/* patch pointer addition in vtop so that pointer dereferencing is - also tested */ -ST_FUNC void gen_bounded_ptr_deref(void) -{ - addr_t func; - addr_t size, align; - Elf32_Rel *rel; - Sym *sym; - - size = 0; - /* XXX: put that code in generic part of tcc */ - if (!is_float(vtop->type.t)) { - if (vtop->r & VT_LVAL_BYTE) - size = 1; - else if (vtop->r & VT_LVAL_SHORT) - size = 2; - } - if (!size) - size = type_size(&vtop->type, &align); - switch(size) { - case 1: func = TOK___bound_ptr_indir1; break; - case 2: func = TOK___bound_ptr_indir2; break; - case 4: func = TOK___bound_ptr_indir4; break; - case 8: func = TOK___bound_ptr_indir8; break; - case 12: func = TOK___bound_ptr_indir12; break; - case 16: func = TOK___bound_ptr_indir16; break; - default: - tcc_error("unhandled size when dereferencing bounded pointer"); - func = 0; - break; - } - - /* patch relocation */ - /* XXX: find a better solution ? */ - rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.i); - sym = external_global_sym(func, &func_old_type, 0); - if (!sym->c) - put_extern_sym(sym, NULL, 0, 0); - rel->r_info = ELF32_R_INFO(sym->c, ELF32_R_TYPE(rel->r_info)); -} -#endif - -/* Save the stack pointer onto the stack */ -ST_FUNC void gen_vla_sp_save(int addr) { - /* mov %esp,addr(%ebp)*/ - o(0x89); - gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr); -} - -/* Restore the SP from a location on the stack */ -ST_FUNC void gen_vla_sp_restore(int addr) { - o(0x8b); - gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr); -} - -/* Subtract from the stack pointer, and push the resulting value onto the stack */ -ST_FUNC void gen_vla_alloc(CType *type, int align) { -#ifdef TCC_TARGET_PE - /* alloca does more than just adjust %rsp on Windows */ - vpush_global_sym(&func_old_type, TOK_alloca); - vswap(); /* Move alloca ref past allocation size */ - gfunc_call(1); -#else - int r; - r = gv(RC_INT); /* allocation size */ - /* sub r,%rsp */ - o(0x2b); - o(0xe0 | r); - /* We align to 16 bytes rather than align */ - /* and ~15, %esp */ - o(0xf0e483); - vpop(); -#endif -} - -/* end of X86 code generator */ -/*************************************************************/ -#endif -/*************************************************************/ diff --git a/external/TCC/i386-tok.h b/external/TCC/i386-tok.h deleted file mode 100644 index b0ca3edb..00000000 --- a/external/TCC/i386-tok.h +++ /dev/null @@ -1,244 +0,0 @@ -/* ------------------------------------------------------------------ */ -/* WARNING: relative order of tokens is important. */ - -/* register */ - DEF_ASM(al) - DEF_ASM(cl) - DEF_ASM(dl) - DEF_ASM(bl) - DEF_ASM(ah) - DEF_ASM(ch) - DEF_ASM(dh) - DEF_ASM(bh) - DEF_ASM(ax) - DEF_ASM(cx) - DEF_ASM(dx) - DEF_ASM(bx) - DEF_ASM(sp) - DEF_ASM(bp) - DEF_ASM(si) - DEF_ASM(di) - DEF_ASM(eax) - DEF_ASM(ecx) - DEF_ASM(edx) - DEF_ASM(ebx) - DEF_ASM(esp) - DEF_ASM(ebp) - DEF_ASM(esi) - DEF_ASM(edi) -#ifdef TCC_TARGET_X86_64 - DEF_ASM(rax) - DEF_ASM(rcx) - DEF_ASM(rdx) - DEF_ASM(rbx) - DEF_ASM(rsp) - DEF_ASM(rbp) - DEF_ASM(rsi) - DEF_ASM(rdi) -#endif - DEF_ASM(mm0) - DEF_ASM(mm1) - DEF_ASM(mm2) - DEF_ASM(mm3) - DEF_ASM(mm4) - DEF_ASM(mm5) - DEF_ASM(mm6) - DEF_ASM(mm7) - DEF_ASM(xmm0) - DEF_ASM(xmm1) - DEF_ASM(xmm2) - DEF_ASM(xmm3) - DEF_ASM(xmm4) - DEF_ASM(xmm5) - DEF_ASM(xmm6) - DEF_ASM(xmm7) - DEF_ASM(cr0) - DEF_ASM(cr1) - DEF_ASM(cr2) - DEF_ASM(cr3) - DEF_ASM(cr4) - DEF_ASM(cr5) - DEF_ASM(cr6) - DEF_ASM(cr7) - DEF_ASM(tr0) - DEF_ASM(tr1) - DEF_ASM(tr2) - DEF_ASM(tr3) - DEF_ASM(tr4) - DEF_ASM(tr5) - DEF_ASM(tr6) - DEF_ASM(tr7) - DEF_ASM(db0) - DEF_ASM(db1) - DEF_ASM(db2) - DEF_ASM(db3) - DEF_ASM(db4) - DEF_ASM(db5) - DEF_ASM(db6) - DEF_ASM(db7) - DEF_ASM(dr0) - DEF_ASM(dr1) - DEF_ASM(dr2) - DEF_ASM(dr3) - DEF_ASM(dr4) - DEF_ASM(dr5) - DEF_ASM(dr6) - DEF_ASM(dr7) - DEF_ASM(es) - DEF_ASM(cs) - DEF_ASM(ss) - DEF_ASM(ds) - DEF_ASM(fs) - DEF_ASM(gs) - DEF_ASM(st) - - /* generic two operands */ - DEF_BWLX(mov) - - DEF_BWLX(add) - DEF_BWLX(or) - DEF_BWLX(adc) - DEF_BWLX(sbb) - DEF_BWLX(and) - DEF_BWLX(sub) - DEF_BWLX(xor) - DEF_BWLX(cmp) - - /* unary ops */ - DEF_BWLX(inc) - DEF_BWLX(dec) - DEF_BWLX(not) - DEF_BWLX(neg) - DEF_BWLX(mul) - DEF_BWLX(imul) - DEF_BWLX(div) - DEF_BWLX(idiv) - - DEF_BWLX(xchg) - DEF_BWLX(test) - - /* shifts */ - DEF_BWLX(rol) - DEF_BWLX(ror) - DEF_BWLX(rcl) - DEF_BWLX(rcr) - DEF_BWLX(shl) - DEF_BWLX(shr) - DEF_BWLX(sar) - - DEF_ASM(shldw) - DEF_ASM(shldl) - DEF_ASM(shld) - DEF_ASM(shrdw) - DEF_ASM(shrdl) - DEF_ASM(shrd) - - DEF_ASM(pushw) - DEF_ASM(pushl) -#ifdef TCC_TARGET_X86_64 - DEF_ASM(pushq) -#endif - DEF_ASM(push) - - DEF_ASM(popw) - DEF_ASM(popl) -#ifdef TCC_TARGET_X86_64 - DEF_ASM(popq) -#endif - DEF_ASM(pop) - - DEF_BWL(in) - DEF_BWL(out) - - DEF_WL(movzb) - DEF_ASM(movzwl) - DEF_ASM(movsbw) - DEF_ASM(movsbl) - DEF_ASM(movswl) -#ifdef TCC_TARGET_X86_64 - DEF_ASM(movslq) -#endif - - DEF_WLX(lea) - - DEF_ASM(les) - DEF_ASM(lds) - DEF_ASM(lss) - DEF_ASM(lfs) - DEF_ASM(lgs) - - DEF_ASM(call) - DEF_ASM(jmp) - DEF_ASM(lcall) - DEF_ASM(ljmp) - - DEF_ASMTEST(j,) - - DEF_ASMTEST(set,) - DEF_ASMTEST(set,b) - DEF_ASMTEST(cmov,) - - DEF_WLX(bsf) - DEF_WLX(bsr) - DEF_WLX(bt) - DEF_WLX(bts) - DEF_WLX(btr) - DEF_WLX(btc) - - DEF_WLX(lsl) - - /* generic FP ops */ - DEF_FP(add) - DEF_FP(mul) - - DEF_ASM(fcom) - DEF_ASM(fcom_1) /* non existent op, just to have a regular table */ - DEF_FP1(com) - - DEF_FP(comp) - DEF_FP(sub) - DEF_FP(subr) - DEF_FP(div) - DEF_FP(divr) - - DEF_BWLX(xadd) - DEF_BWLX(cmpxchg) - - /* string ops */ - DEF_BWLX(cmps) - DEF_BWLX(scmp) - DEF_BWL(ins) - DEF_BWL(outs) - DEF_BWLX(lods) - DEF_BWLX(slod) - DEF_BWLX(movs) - DEF_BWLX(smov) - DEF_BWLX(scas) - DEF_BWLX(ssca) - DEF_BWLX(stos) - DEF_BWLX(ssto) - - /* generic asm ops */ -#define ALT(x) -#define DEF_ASM_OP0(name, opcode) DEF_ASM(name) -#define DEF_ASM_OP0L(name, opcode, group, instr_type) -#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) -#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) -#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) -#ifdef TCC_TARGET_X86_64 -# include "x86_64-asm.h" -#else -# include "i386-asm.h" -#endif - -#define ALT(x) -#define DEF_ASM_OP0(name, opcode) -#define DEF_ASM_OP0L(name, opcode, group, instr_type) DEF_ASM(name) -#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) DEF_ASM(name) -#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) DEF_ASM(name) -#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) DEF_ASM(name) -#ifdef TCC_TARGET_X86_64 -# include "x86_64-asm.h" -#else -# include "i386-asm.h" -#endif diff --git a/external/TCC/il-gen.c b/external/TCC/il-gen.c deleted file mode 100644 index cf3aff53..00000000 --- a/external/TCC/il-gen.c +++ /dev/null @@ -1,655 +0,0 @@ -/* - * CIL code generator for TCC - * - * Copyright (c) 2002 Fabrice Bellard - * - * 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* number of available registers */ -#define NB_REGS 3 - -/* a register can belong to several classes. The classes must be - sorted from more general to more precise (see gv2() code which does - assumptions on it). */ -#define RC_ST 0x0001 /* any stack entry */ -#define RC_ST0 0x0002 /* top of stack */ -#define RC_ST1 0x0004 /* top - 1 */ - -#define RC_INT RC_ST -#define RC_FLOAT RC_ST -#define RC_IRET RC_ST0 /* function return: integer register */ -#define RC_LRET RC_ST0 /* function return: second integer register */ -#define RC_FRET RC_ST0 /* function return: float register */ - -/* pretty names for the registers */ -enum { - REG_ST0 = 0, - REG_ST1, - REG_ST2, -}; - -const int reg_classes[NB_REGS] = { - /* ST0 */ RC_ST | RC_ST0, - /* ST1 */ RC_ST | RC_ST1, - /* ST2 */ RC_ST, -}; - -/* return registers for function */ -#define REG_IRET REG_ST0 /* single word int return register */ -#define REG_LRET REG_ST0 /* second word return register (for long long) */ -#define REG_FRET REG_ST0 /* float return register */ - -/* defined if function parameters must be evaluated in reverse order */ -/* #define INVERT_FUNC_PARAMS */ - -/* defined if structures are passed as pointers. Otherwise structures - are directly pushed on stack. */ -/* #define FUNC_STRUCT_PARAM_AS_PTR */ - -/* pointer size, in bytes */ -#define PTR_SIZE 4 - -/* long double size and alignment, in bytes */ -#define LDOUBLE_SIZE 8 -#define LDOUBLE_ALIGN 8 - -/* function call context */ -typedef struct GFuncContext { - int func_call; /* func call type (FUNC_STDCALL or FUNC_CDECL) */ -} GFuncContext; - -/******************************************************/ -/* opcode definitions */ - -#define IL_OP_PREFIX 0xFE - -enum ILOPCodes { -#define OP(name, str, n) IL_OP_ ## name = n, -#include "il-opcodes.h" -#undef OP -}; - -char *il_opcodes_str[] = { -#define OP(name, str, n) [n] = str, -#include "il-opcodes.h" -#undef OP -}; - -/******************************************************/ - -/* arguments variable numbers start from there */ -#define ARG_BASE 0x70000000 - -static FILE *il_outfile; - -static void out_byte(int c) -{ - *(char *)ind++ = c; -} - -static void out_le32(int c) -{ - out_byte(c); - out_byte(c >> 8); - out_byte(c >> 16); - out_byte(c >> 24); -} - -static void init_outfile(void) -{ - if (!il_outfile) { - il_outfile = stdout; - fprintf(il_outfile, - ".assembly extern mscorlib\n" - "{\n" - ".ver 1:0:2411:0\n" - "}\n\n"); - } -} - -static void out_op1(int op) -{ - if (op & 0x100) - out_byte(IL_OP_PREFIX); - out_byte(op & 0xff); -} - -/* output an opcode with prefix */ -static void out_op(int op) -{ - out_op1(op); - fprintf(il_outfile, " %s\n", il_opcodes_str[op]); -} - -static void out_opb(int op, int c) -{ - out_op1(op); - out_byte(c); - fprintf(il_outfile, " %s %d\n", il_opcodes_str[op], c); -} - -static void out_opi(int op, int c) -{ - out_op1(op); - out_le32(c); - fprintf(il_outfile, " %s 0x%x\n", il_opcodes_str[op], c); -} - -/* XXX: not complete */ -static void il_type_to_str(char *buf, int buf_size, - int t, const char *varstr) -{ - int bt; - Sym *s, *sa; - char buf1[256]; - const char *tstr; - - t = t & VT_TYPE; - bt = t & VT_BTYPE; - buf[0] = '\0'; - if (t & VT_UNSIGNED) - pstrcat(buf, buf_size, "unsigned "); - switch(bt) { - case VT_VOID: - tstr = "void"; - goto add_tstr; - case VT_BOOL: - tstr = "bool"; - goto add_tstr; - case VT_BYTE: - tstr = "int8"; - goto add_tstr; - case VT_SHORT: - tstr = "int16"; - goto add_tstr; - case VT_ENUM: - case VT_INT: - case VT_LONG: - tstr = "int32"; - goto add_tstr; - case VT_LLONG: - tstr = "int64"; - goto add_tstr; - case VT_FLOAT: - tstr = "float32"; - goto add_tstr; - case VT_DOUBLE: - case VT_LDOUBLE: - tstr = "float64"; - add_tstr: - pstrcat(buf, buf_size, tstr); - break; - case VT_STRUCT: - tcc_error("structures not handled yet"); - break; - case VT_FUNC: - s = sym_find((unsigned)t >> VT_STRUCT_SHIFT); - il_type_to_str(buf, buf_size, s->t, varstr); - pstrcat(buf, buf_size, "("); - sa = s->next; - while (sa != NULL) { - il_type_to_str(buf1, sizeof(buf1), sa->t, NULL); - pstrcat(buf, buf_size, buf1); - sa = sa->next; - if (sa) - pstrcat(buf, buf_size, ", "); - } - pstrcat(buf, buf_size, ")"); - goto no_var; - case VT_PTR: - s = sym_find((unsigned)t >> VT_STRUCT_SHIFT); - pstrcpy(buf1, sizeof(buf1), "*"); - if (varstr) - pstrcat(buf1, sizeof(buf1), varstr); - il_type_to_str(buf, buf_size, s->t, buf1); - goto no_var; - } - if (varstr) { - pstrcat(buf, buf_size, " "); - pstrcat(buf, buf_size, varstr); - } - no_var: ; -} - - -/* patch relocation entry with value 'val' */ -void greloc_patch1(Reloc *p, int val) -{ -} - -/* output a symbol and patch all calls to it */ -void gsym_addr(t, a) -{ -} - -/* output jump and return symbol */ -static int out_opj(int op, int c) -{ - out_op1(op); - out_le32(0); - if (c == 0) { - c = ind - (int)cur_text_section->data; - } - fprintf(il_outfile, " %s L%d\n", il_opcodes_str[op], c); - return c; -} - -void gsym(int t) -{ - fprintf(il_outfile, "L%d:\n", t); -} - -/* load 'r' from value 'sv' */ -void load(int r, SValue *sv) -{ - int v, fc, ft; - - v = sv->r & VT_VALMASK; - fc = sv->c.i; - ft = sv->t; - - if (sv->r & VT_LVAL) { - if (v == VT_LOCAL) { - if (fc >= ARG_BASE) { - fc -= ARG_BASE; - if (fc >= 0 && fc <= 4) { - out_op(IL_OP_LDARG_0 + fc); - } else if (fc <= 0xff) { - out_opb(IL_OP_LDARG_S, fc); - } else { - out_opi(IL_OP_LDARG, fc); - } - } else { - if (fc >= 0 && fc <= 4) { - out_op(IL_OP_LDLOC_0 + fc); - } else if (fc <= 0xff) { - out_opb(IL_OP_LDLOC_S, fc); - } else { - out_opi(IL_OP_LDLOC, fc); - } - } - } else if (v == VT_CONST) { - /* XXX: handle globals */ - out_opi(IL_OP_LDSFLD, 0); - } else { - if ((ft & VT_BTYPE) == VT_FLOAT) { - out_op(IL_OP_LDIND_R4); - } else if ((ft & VT_BTYPE) == VT_DOUBLE) { - out_op(IL_OP_LDIND_R8); - } else if ((ft & VT_BTYPE) == VT_LDOUBLE) { - out_op(IL_OP_LDIND_R8); - } else if ((ft & VT_TYPE) == VT_BYTE) - out_op(IL_OP_LDIND_I1); - else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) - out_op(IL_OP_LDIND_U1); - else if ((ft & VT_TYPE) == VT_SHORT) - out_op(IL_OP_LDIND_I2); - else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) - out_op(IL_OP_LDIND_U2); - else - out_op(IL_OP_LDIND_I4); - } - } else { - if (v == VT_CONST) { - /* XXX: handle globals */ - if (fc >= -1 && fc <= 8) { - out_op(IL_OP_LDC_I4_M1 + fc + 1); - } else { - out_opi(IL_OP_LDC_I4, fc); - } - } else if (v == VT_LOCAL) { - if (fc >= ARG_BASE) { - fc -= ARG_BASE; - if (fc <= 0xff) { - out_opb(IL_OP_LDARGA_S, fc); - } else { - out_opi(IL_OP_LDARGA, fc); - } - } else { - if (fc <= 0xff) { - out_opb(IL_OP_LDLOCA_S, fc); - } else { - out_opi(IL_OP_LDLOCA, fc); - } - } - } else { - /* XXX: do it */ - } - } -} - -/* store register 'r' in lvalue 'v' */ -void store(int r, SValue *sv) -{ - int v, fc, ft; - - v = sv->r & VT_VALMASK; - fc = sv->c.i; - ft = sv->t; - if (v == VT_LOCAL) { - if (fc >= ARG_BASE) { - fc -= ARG_BASE; - /* XXX: check IL arg store semantics */ - if (fc <= 0xff) { - out_opb(IL_OP_STARG_S, fc); - } else { - out_opi(IL_OP_STARG, fc); - } - } else { - if (fc >= 0 && fc <= 4) { - out_op(IL_OP_STLOC_0 + fc); - } else if (fc <= 0xff) { - out_opb(IL_OP_STLOC_S, fc); - } else { - out_opi(IL_OP_STLOC, fc); - } - } - } else if (v == VT_CONST) { - /* XXX: handle globals */ - out_opi(IL_OP_STSFLD, 0); - } else { - if ((ft & VT_BTYPE) == VT_FLOAT) - out_op(IL_OP_STIND_R4); - else if ((ft & VT_BTYPE) == VT_DOUBLE) - out_op(IL_OP_STIND_R8); - else if ((ft & VT_BTYPE) == VT_LDOUBLE) - out_op(IL_OP_STIND_R8); - else if ((ft & VT_BTYPE) == VT_BYTE) - out_op(IL_OP_STIND_I1); - else if ((ft & VT_BTYPE) == VT_SHORT) - out_op(IL_OP_STIND_I2); - else - out_op(IL_OP_STIND_I4); - } -} - -/* start function call and return function call context */ -void gfunc_start(GFuncContext *c, int func_call) -{ - c->func_call = func_call; -} - -/* push function parameter which is in (vtop->t, vtop->c). Stack entry - is then popped. */ -void gfunc_param(GFuncContext *c) -{ - if ((vtop->t & VT_BTYPE) == VT_STRUCT) { - tcc_error("structures passed as value not handled yet"); - } else { - /* simply push on stack */ - gv(RC_ST0); - } - vtop--; -} - -/* generate function call with address in (vtop->t, vtop->c) and free function - context. Stack entry is popped */ -void gfunc_call(GFuncContext *c) -{ - char buf[1024]; - - if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { - /* XXX: more info needed from tcc */ - il_type_to_str(buf, sizeof(buf), vtop->t, "xxx"); - fprintf(il_outfile, " call %s\n", buf); - } else { - /* indirect call */ - gv(RC_INT); - il_type_to_str(buf, sizeof(buf), vtop->t, NULL); - fprintf(il_outfile, " calli %s\n", buf); - } - vtop--; -} - -/* generate function prolog of type 't' */ -void gfunc_prolog(int t) -{ - int addr, u, func_call; - Sym *sym; - char buf[1024]; - - init_outfile(); - - /* XXX: pass function name to gfunc_prolog */ - il_type_to_str(buf, sizeof(buf), t, funcname); - fprintf(il_outfile, ".method static %s il managed\n", buf); - fprintf(il_outfile, "{\n"); - /* XXX: cannot do better now */ - fprintf(il_outfile, " .maxstack %d\n", NB_REGS); - fprintf(il_outfile, " .locals (int32, int32, int32, int32, int32, int32, int32, int32)\n"); - - if (!strcmp(funcname, "main")) - fprintf(il_outfile, " .entrypoint\n"); - - sym = sym_find((unsigned)t >> VT_STRUCT_SHIFT); - func_call = sym->r; - - addr = ARG_BASE; - /* if the function returns a structure, then add an - implicit pointer parameter */ - func_vt = sym->t; - func_var = (sym->c == FUNC_ELLIPSIS); - if ((func_vt & VT_BTYPE) == VT_STRUCT) { - func_vc = addr; - addr++; - } - /* define parameters */ - while ((sym = sym->next) != NULL) { - u = sym->t; - sym_push(sym->v & ~SYM_FIELD, u, - VT_LOCAL | lvalue_type(sym->type.t), addr); - addr++; - } -} - -/* generate function epilog */ -void gfunc_epilog(void) -{ - out_op(IL_OP_RET); - fprintf(il_outfile, "}\n\n"); -} - -/* generate a jump to a label */ -int gjmp(int t) -{ - return out_opj(IL_OP_BR, t); -} - -/* generate a jump to a fixed address */ -void gjmp_addr(int a) -{ - /* XXX: handle syms */ - out_opi(IL_OP_BR, a); -} - -/* generate a test. set 'inv' to invert test. Stack entry is popped */ -int gtst(int inv, int t) -{ - int v, *p, c; - - v = vtop->r & VT_VALMASK; - if (v == VT_CMP) { - c = vtop->c.i ^ inv; - switch(c) { - case TOK_EQ: - c = IL_OP_BEQ; - break; - case TOK_NE: - c = IL_OP_BNE_UN; - break; - case TOK_LT: - c = IL_OP_BLT; - break; - case TOK_LE: - c = IL_OP_BLE; - break; - case TOK_GT: - c = IL_OP_BGT; - break; - case TOK_GE: - c = IL_OP_BGE; - break; - case TOK_ULT: - c = IL_OP_BLT_UN; - break; - case TOK_ULE: - c = IL_OP_BLE_UN; - break; - case TOK_UGT: - c = IL_OP_BGT_UN; - break; - case TOK_UGE: - c = IL_OP_BGE_UN; - break; - } - t = out_opj(c, t); - } else if (v == VT_JMP || v == VT_JMPI) { - /* && or || optimization */ - if ((v & 1) == inv) { - /* insert vtop->c jump list in t */ - p = &vtop->c.i; - while (*p != 0) - p = (int *)*p; - *p = t; - t = vtop->c.i; - } else { - t = gjmp(t); - gsym(vtop->c.i); - } - } - vtop--; - return t; -} - -/* generate an integer binary operation */ -void gen_opi(int op) -{ - gv2(RC_ST1, RC_ST0); - switch(op) { - case '+': - out_op(IL_OP_ADD); - goto std_op; - case '-': - out_op(IL_OP_SUB); - goto std_op; - case '&': - out_op(IL_OP_AND); - goto std_op; - case '^': - out_op(IL_OP_XOR); - goto std_op; - case '|': - out_op(IL_OP_OR); - goto std_op; - case '*': - out_op(IL_OP_MUL); - goto std_op; - case TOK_SHL: - out_op(IL_OP_SHL); - goto std_op; - case TOK_SHR: - out_op(IL_OP_SHR_UN); - goto std_op; - case TOK_SAR: - out_op(IL_OP_SHR); - goto std_op; - case '/': - case TOK_PDIV: - out_op(IL_OP_DIV); - goto std_op; - case TOK_UDIV: - out_op(IL_OP_DIV_UN); - goto std_op; - case '%': - out_op(IL_OP_REM); - goto std_op; - case TOK_UMOD: - out_op(IL_OP_REM_UN); - std_op: - vtop--; - vtop[0].r = REG_ST0; - break; - case TOK_EQ: - case TOK_NE: - case TOK_LT: - case TOK_LE: - case TOK_GT: - case TOK_GE: - case TOK_ULT: - case TOK_ULE: - case TOK_UGT: - case TOK_UGE: - vtop--; - vtop[0].r = VT_CMP; - vtop[0].c.i = op; - break; - } -} - -/* generate a floating point operation 'v = t1 op t2' instruction. The - two operands are guaranted to have the same floating point type */ -void gen_opf(int op) -{ - /* same as integer */ - gen_opi(op); -} - -/* convert integers to fp 't' type. Must handle 'int', 'unsigned int' - and 'long long' cases. */ -void gen_cvt_itof(int t) -{ - gv(RC_ST0); - if (t == VT_FLOAT) - out_op(IL_OP_CONV_R4); - else - out_op(IL_OP_CONV_R8); -} - -/* convert fp to int 't' type */ -/* XXX: handle long long case */ -void gen_cvt_ftoi(int t) -{ - gv(RC_ST0); - switch(t) { - case VT_INT | VT_UNSIGNED: - out_op(IL_OP_CONV_U4); - break; - case VT_LLONG: - out_op(IL_OP_CONV_I8); - break; - case VT_LLONG | VT_UNSIGNED: - out_op(IL_OP_CONV_U8); - break; - default: - out_op(IL_OP_CONV_I4); - break; - } -} - -/* convert from one floating point type to another */ -void gen_cvt_ftof(int t) -{ - gv(RC_ST0); - if (t == VT_FLOAT) { - out_op(IL_OP_CONV_R4); - } else { - out_op(IL_OP_CONV_R8); - } -} - -/* end of CIL code generator */ -/*************************************************************/ - diff --git a/external/TCC/il-opcodes.h b/external/TCC/il-opcodes.h deleted file mode 100644 index d53ffb2c..00000000 --- a/external/TCC/il-opcodes.h +++ /dev/null @@ -1,251 +0,0 @@ -/* - * CIL opcode definition - * - * Copyright (c) 2002 Fabrice Bellard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -OP(NOP, "nop", 0x00) -OP(BREAK, "break", 0x01) -OP(LDARG_0, "ldarg.0", 0x02) -OP(LDARG_1, "ldarg.1", 0x03) -OP(LDARG_2, "ldarg.2", 0x04) -OP(LDARG_3, "ldarg.3", 0x05) -OP(LDLOC_0, "ldloc.0", 0x06) -OP(LDLOC_1, "ldloc.1", 0x07) -OP(LDLOC_2, "ldloc.2", 0x08) -OP(LDLOC_3, "ldloc.3", 0x09) -OP(STLOC_0, "stloc.0", 0x0a) -OP(STLOC_1, "stloc.1", 0x0b) -OP(STLOC_2, "stloc.2", 0x0c) -OP(STLOC_3, "stloc.3", 0x0d) -OP(LDARG_S, "ldarg.s", 0x0e) -OP(LDARGA_S, "ldarga.s", 0x0f) -OP(STARG_S, "starg.s", 0x10) -OP(LDLOC_S, "ldloc.s", 0x11) -OP(LDLOCA_S, "ldloca.s", 0x12) -OP(STLOC_S, "stloc.s", 0x13) -OP(LDNULL, "ldnull", 0x14) -OP(LDC_I4_M1, "ldc.i4.m1", 0x15) -OP(LDC_I4_0, "ldc.i4.0", 0x16) -OP(LDC_I4_1, "ldc.i4.1", 0x17) -OP(LDC_I4_2, "ldc.i4.2", 0x18) -OP(LDC_I4_3, "ldc.i4.3", 0x19) -OP(LDC_I4_4, "ldc.i4.4", 0x1a) -OP(LDC_I4_5, "ldc.i4.5", 0x1b) -OP(LDC_I4_6, "ldc.i4.6", 0x1c) -OP(LDC_I4_7, "ldc.i4.7", 0x1d) -OP(LDC_I4_8, "ldc.i4.8", 0x1e) -OP(LDC_I4_S, "ldc.i4.s", 0x1f) -OP(LDC_I4, "ldc.i4", 0x20) -OP(LDC_I8, "ldc.i8", 0x21) -OP(LDC_R4, "ldc.r4", 0x22) -OP(LDC_R8, "ldc.r8", 0x23) -OP(LDPTR, "ldptr", 0x24) -OP(DUP, "dup", 0x25) -OP(POP, "pop", 0x26) -OP(JMP, "jmp", 0x27) -OP(CALL, "call", 0x28) -OP(CALLI, "calli", 0x29) -OP(RET, "ret", 0x2a) -OP(BR_S, "br.s", 0x2b) -OP(BRFALSE_S, "brfalse.s", 0x2c) -OP(BRTRUE_S, "brtrue.s", 0x2d) -OP(BEQ_S, "beq.s", 0x2e) -OP(BGE_S, "bge.s", 0x2f) -OP(BGT_S, "bgt.s", 0x30) -OP(BLE_S, "ble.s", 0x31) -OP(BLT_S, "blt.s", 0x32) -OP(BNE_UN_S, "bne.un.s", 0x33) -OP(BGE_UN_S, "bge.un.s", 0x34) -OP(BGT_UN_S, "bgt.un.s", 0x35) -OP(BLE_UN_S, "ble.un.s", 0x36) -OP(BLT_UN_S, "blt.un.s", 0x37) -OP(BR, "br", 0x38) -OP(BRFALSE, "brfalse", 0x39) -OP(BRTRUE, "brtrue", 0x3a) -OP(BEQ, "beq", 0x3b) -OP(BGE, "bge", 0x3c) -OP(BGT, "bgt", 0x3d) -OP(BLE, "ble", 0x3e) -OP(BLT, "blt", 0x3f) -OP(BNE_UN, "bne.un", 0x40) -OP(BGE_UN, "bge.un", 0x41) -OP(BGT_UN, "bgt.un", 0x42) -OP(BLE_UN, "ble.un", 0x43) -OP(BLT_UN, "blt.un", 0x44) -OP(SWITCH, "switch", 0x45) -OP(LDIND_I1, "ldind.i1", 0x46) -OP(LDIND_U1, "ldind.u1", 0x47) -OP(LDIND_I2, "ldind.i2", 0x48) -OP(LDIND_U2, "ldind.u2", 0x49) -OP(LDIND_I4, "ldind.i4", 0x4a) -OP(LDIND_U4, "ldind.u4", 0x4b) -OP(LDIND_I8, "ldind.i8", 0x4c) -OP(LDIND_I, "ldind.i", 0x4d) -OP(LDIND_R4, "ldind.r4", 0x4e) -OP(LDIND_R8, "ldind.r8", 0x4f) -OP(LDIND_REF, "ldind.ref", 0x50) -OP(STIND_REF, "stind.ref", 0x51) -OP(STIND_I1, "stind.i1", 0x52) -OP(STIND_I2, "stind.i2", 0x53) -OP(STIND_I4, "stind.i4", 0x54) -OP(STIND_I8, "stind.i8", 0x55) -OP(STIND_R4, "stind.r4", 0x56) -OP(STIND_R8, "stind.r8", 0x57) -OP(ADD, "add", 0x58) -OP(SUB, "sub", 0x59) -OP(MUL, "mul", 0x5a) -OP(DIV, "div", 0x5b) -OP(DIV_UN, "div.un", 0x5c) -OP(REM, "rem", 0x5d) -OP(REM_UN, "rem.un", 0x5e) -OP(AND, "and", 0x5f) -OP(OR, "or", 0x60) -OP(XOR, "xor", 0x61) -OP(SHL, "shl", 0x62) -OP(SHR, "shr", 0x63) -OP(SHR_UN, "shr.un", 0x64) -OP(NEG, "neg", 0x65) -OP(NOT, "not", 0x66) -OP(CONV_I1, "conv.i1", 0x67) -OP(CONV_I2, "conv.i2", 0x68) -OP(CONV_I4, "conv.i4", 0x69) -OP(CONV_I8, "conv.i8", 0x6a) -OP(CONV_R4, "conv.r4", 0x6b) -OP(CONV_R8, "conv.r8", 0x6c) -OP(CONV_U4, "conv.u4", 0x6d) -OP(CONV_U8, "conv.u8", 0x6e) -OP(CALLVIRT, "callvirt", 0x6f) -OP(CPOBJ, "cpobj", 0x70) -OP(LDOBJ, "ldobj", 0x71) -OP(LDSTR, "ldstr", 0x72) -OP(NEWOBJ, "newobj", 0x73) -OP(CASTCLASS, "castclass", 0x74) -OP(ISINST, "isinst", 0x75) -OP(CONV_R_UN, "conv.r.un", 0x76) -OP(ANN_DATA_S, "ann.data.s", 0x77) -OP(UNBOX, "unbox", 0x79) -OP(THROW, "throw", 0x7a) -OP(LDFLD, "ldfld", 0x7b) -OP(LDFLDA, "ldflda", 0x7c) -OP(STFLD, "stfld", 0x7d) -OP(LDSFLD, "ldsfld", 0x7e) -OP(LDSFLDA, "ldsflda", 0x7f) -OP(STSFLD, "stsfld", 0x80) -OP(STOBJ, "stobj", 0x81) -OP(CONV_OVF_I1_UN, "conv.ovf.i1.un", 0x82) -OP(CONV_OVF_I2_UN, "conv.ovf.i2.un", 0x83) -OP(CONV_OVF_I4_UN, "conv.ovf.i4.un", 0x84) -OP(CONV_OVF_I8_UN, "conv.ovf.i8.un", 0x85) -OP(CONV_OVF_U1_UN, "conv.ovf.u1.un", 0x86) -OP(CONV_OVF_U2_UN, "conv.ovf.u2.un", 0x87) -OP(CONV_OVF_U4_UN, "conv.ovf.u4.un", 0x88) -OP(CONV_OVF_U8_UN, "conv.ovf.u8.un", 0x89) -OP(CONV_OVF_I_UN, "conv.ovf.i.un", 0x8a) -OP(CONV_OVF_U_UN, "conv.ovf.u.un", 0x8b) -OP(BOX, "box", 0x8c) -OP(NEWARR, "newarr", 0x8d) -OP(LDLEN, "ldlen", 0x8e) -OP(LDELEMA, "ldelema", 0x8f) -OP(LDELEM_I1, "ldelem.i1", 0x90) -OP(LDELEM_U1, "ldelem.u1", 0x91) -OP(LDELEM_I2, "ldelem.i2", 0x92) -OP(LDELEM_U2, "ldelem.u2", 0x93) -OP(LDELEM_I4, "ldelem.i4", 0x94) -OP(LDELEM_U4, "ldelem.u4", 0x95) -OP(LDELEM_I8, "ldelem.i8", 0x96) -OP(LDELEM_I, "ldelem.i", 0x97) -OP(LDELEM_R4, "ldelem.r4", 0x98) -OP(LDELEM_R8, "ldelem.r8", 0x99) -OP(LDELEM_REF, "ldelem.ref", 0x9a) -OP(STELEM_I, "stelem.i", 0x9b) -OP(STELEM_I1, "stelem.i1", 0x9c) -OP(STELEM_I2, "stelem.i2", 0x9d) -OP(STELEM_I4, "stelem.i4", 0x9e) -OP(STELEM_I8, "stelem.i8", 0x9f) -OP(STELEM_R4, "stelem.r4", 0xa0) -OP(STELEM_R8, "stelem.r8", 0xa1) -OP(STELEM_REF, "stelem.ref", 0xa2) -OP(CONV_OVF_I1, "conv.ovf.i1", 0xb3) -OP(CONV_OVF_U1, "conv.ovf.u1", 0xb4) -OP(CONV_OVF_I2, "conv.ovf.i2", 0xb5) -OP(CONV_OVF_U2, "conv.ovf.u2", 0xb6) -OP(CONV_OVF_I4, "conv.ovf.i4", 0xb7) -OP(CONV_OVF_U4, "conv.ovf.u4", 0xb8) -OP(CONV_OVF_I8, "conv.ovf.i8", 0xb9) -OP(CONV_OVF_U8, "conv.ovf.u8", 0xba) -OP(REFANYVAL, "refanyval", 0xc2) -OP(CKFINITE, "ckfinite", 0xc3) -OP(MKREFANY, "mkrefany", 0xc6) -OP(ANN_CALL, "ann.call", 0xc7) -OP(ANN_CATCH, "ann.catch", 0xc8) -OP(ANN_DEAD, "ann.dead", 0xc9) -OP(ANN_HOISTED, "ann.hoisted", 0xca) -OP(ANN_HOISTED_CALL, "ann.hoisted.call", 0xcb) -OP(ANN_LAB, "ann.lab", 0xcc) -OP(ANN_DEF, "ann.def", 0xcd) -OP(ANN_REF_S, "ann.ref.s", 0xce) -OP(ANN_PHI, "ann.phi", 0xcf) -OP(LDTOKEN, "ldtoken", 0xd0) -OP(CONV_U2, "conv.u2", 0xd1) -OP(CONV_U1, "conv.u1", 0xd2) -OP(CONV_I, "conv.i", 0xd3) -OP(CONV_OVF_I, "conv.ovf.i", 0xd4) -OP(CONV_OVF_U, "conv.ovf.u", 0xd5) -OP(ADD_OVF, "add.ovf", 0xd6) -OP(ADD_OVF_UN, "add.ovf.un", 0xd7) -OP(MUL_OVF, "mul.ovf", 0xd8) -OP(MUL_OVF_UN, "mul.ovf.un", 0xd9) -OP(SUB_OVF, "sub.ovf", 0xda) -OP(SUB_OVF_UN, "sub.ovf.un", 0xdb) -OP(ENDFINALLY, "endfinally", 0xdc) -OP(LEAVE, "leave", 0xdd) -OP(LEAVE_S, "leave.s", 0xde) -OP(STIND_I, "stind.i", 0xdf) -OP(CONV_U, "conv.u", 0xe0) - -/* prefix instructions. we use an opcode >= 256 to ease coding */ - -OP(ARGLIST, "arglist", 0x100) -OP(CEQ, "ceq", 0x101) -OP(CGT, "cgt", 0x102) -OP(CGT_UN, "cgt.un", 0x103) -OP(CLT, "clt", 0x104) -OP(CLT_UN, "clt.un", 0x105) -OP(LDFTN, "ldftn", 0x106) -OP(LDVIRTFTN, "ldvirtftn", 0x107) -OP(JMPI, "jmpi", 0x108) -OP(LDARG, "ldarg", 0x109) -OP(LDARGA, "ldarga", 0x10a) -OP(STARG, "starg", 0x10b) -OP(LDLOC, "ldloc", 0x10c) -OP(LDLOCA, "ldloca", 0x10d) -OP(STLOC, "stloc", 0x10e) -OP(LOCALLOC, "localloc", 0x10f) -OP(ENDFILTER, "endfilter", 0x111) -OP(UNALIGNED, "unaligned", 0x112) -OP(VOLATILE, "volatile", 0x113) -OP(TAIL, "tail", 0x114) -OP(INITOBJ, "initobj", 0x115) -OP(ANN_LIVE, "ann.live", 0x116) -OP(CPBLK, "cpblk", 0x117) -OP(INITBLK, "initblk", 0x118) -OP(ANN_REF, "ann.ref", 0x119) -OP(RETHROW, "rethrow", 0x11a) -OP(SIZEOF, "sizeof", 0x11c) -OP(REFANYTYPE, "refanytype", 0x11d) -OP(ANN_DATA, "ann.data", 0x122) -OP(ANN_ARG, "ann.arg", 0x123) diff --git a/external/TCC/lib/alloca-arm.S b/external/TCC/lib/alloca-arm.S deleted file mode 100644 index 9deae630..00000000 --- a/external/TCC/lib/alloca-arm.S +++ /dev/null @@ -1,11 +0,0 @@ - .text - .align 2 - .global alloca - .type alloca, %function -alloca: - rsb sp, r0, sp - bic sp, sp, #7 - mov r0, sp - mov pc, lr - .size alloca, .-alloca - .section .note.GNU-stack,"",%progbits diff --git a/external/TCC/lib/alloca86-bt.S b/external/TCC/lib/alloca86-bt.S deleted file mode 100644 index 52155053..00000000 --- a/external/TCC/lib/alloca86-bt.S +++ /dev/null @@ -1,47 +0,0 @@ -/* ---------------------------------------------- */ -/* alloca86-bt.S */ - -.globl __bound_alloca - -__bound_alloca: - pop %edx - pop %eax - mov %eax, %ecx - add $3,%eax - and $-4,%eax - jz p6 - -#ifdef TCC_TARGET_PE -p4: - cmp $4096,%eax - jbe p5 - test %eax,-4096(%esp) - sub $4096,%esp - sub $4096,%eax - jmp p4 - -p5: -#endif - - sub %eax,%esp - mov %esp,%eax - - push %edx - push %eax - push %ecx - push %eax - call __bound_new_region - add $8, %esp - pop %eax - pop %edx - -p6: - push %edx - push %edx - ret - -/* mark stack as nonexecutable */ -#if defined __ELF__ && defined __linux__ - .section .note.GNU-stack,"",@progbits -#endif -/* ---------------------------------------------- */ diff --git a/external/TCC/lib/alloca86.S b/external/TCC/lib/alloca86.S deleted file mode 100644 index a17e07f2..00000000 --- a/external/TCC/lib/alloca86.S +++ /dev/null @@ -1,35 +0,0 @@ -/* ---------------------------------------------- */ -/* alloca86.S */ - -.globl alloca - -alloca: - pop %edx - pop %eax - add $3,%eax - and $-4,%eax - jz p3 - -#ifdef TCC_TARGET_PE -p1: - cmp $4096,%eax - jbe p2 - test %eax,-4096(%esp) - sub $4096,%esp - sub $4096,%eax - jmp p1 -p2: -#endif - - sub %eax,%esp - mov %esp,%eax -p3: - push %edx - push %edx - ret - -/* mark stack as nonexecutable */ -#if defined __ELF__ && defined __linux__ - .section .note.GNU-stack,"",@progbits -#endif -/* ---------------------------------------------- */ diff --git a/external/TCC/lib/alloca86_64-bt.S b/external/TCC/lib/alloca86_64-bt.S deleted file mode 100644 index ab8629da..00000000 --- a/external/TCC/lib/alloca86_64-bt.S +++ /dev/null @@ -1,60 +0,0 @@ -/* ---------------------------------------------- */ -/* alloca86_64.S */ - -.globl __bound_alloca -__bound_alloca: - -#ifdef TCC_TARGET_PE - # bound checking is not implemented - pop %rdx - mov %rcx,%rax - add $15,%rax - and $-16,%rax - jz p3 - -p1: - cmp $4096,%rax - jbe p2 - test %rax,-4096(%rsp) - sub $4096,%rsp - sub $4096,%rax - jmp p1 -p2: - - sub %rax,%rsp - mov %rsp,%rax - add $32,%rax - -p3: - push %rdx - ret -#else - pop %rdx - mov %rdi,%rax - movl %rax,%rsi # size, a second parm to the __bound_new_region - - add $15,%rax - and $-16,%rax - jz p3 - - - sub %rax,%rsp - mov %rsp,%rdi # pointer, a first parm to the __bound_new_region - mov %rsp,%rax - - push %rdx - push %rax - call __bound_new_region - pop %rax - pop %rdx - -p3: - push %rdx - ret -#endif - -/* mark stack as nonexecutable */ -#if defined __ELF__ && defined __linux__ - .section .note.GNU-stack,"",@progbits -#endif -/* ---------------------------------------------- */ diff --git a/external/TCC/lib/alloca86_64.S b/external/TCC/lib/alloca86_64.S deleted file mode 100644 index 4a741047..00000000 --- a/external/TCC/lib/alloca86_64.S +++ /dev/null @@ -1,42 +0,0 @@ -/* ---------------------------------------------- */ -/* alloca86_64.S */ - -.globl alloca - -alloca: - pop %rdx -#ifdef TCC_TARGET_PE - mov %rcx,%rax -#else - mov %rdi,%rax -#endif - add $15,%rax - and $-16,%rax - jz p3 - -#ifdef TCC_TARGET_PE -p1: - cmp $4096,%rax - jbe p2 - test %rax,-4096(%rsp) - sub $4096,%rsp - sub $4096,%rax - jmp p1 -p2: -#endif - - sub %rax,%rsp - mov %rsp,%rax -#ifdef TCC_TARGET_PE - add $32,%rax -#endif - -p3: - push %rdx - ret - -/* mark stack as nonexecutable */ -#if defined __ELF__ && defined __linux__ - .section .note.GNU-stack,"",@progbits -#endif -/* ---------------------------------------------- */ diff --git a/external/TCC/lib/armeabi.c b/external/TCC/lib/armeabi.c deleted file mode 100644 index 0d1217ba..00000000 --- a/external/TCC/lib/armeabi.c +++ /dev/null @@ -1,489 +0,0 @@ -/* TCC ARM runtime EABI - Copyright (C) 2013 Thomas Preud'homme - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE.*/ - -#include - -/* We rely on the little endianness and EABI calling convention for this to - work */ - -typedef struct double_unsigned_struct { - unsigned low; - unsigned high; -} double_unsigned_struct; - -typedef struct unsigned_int_struct { - unsigned low; - int high; -} unsigned_int_struct; - -#define REGS_RETURN(name, type) \ - void name ## _return(type ret) {} - - -/* Float helper functions */ - -#define FLOAT_EXP_BITS 8 -#define FLOAT_FRAC_BITS 23 - -#define DOUBLE_EXP_BITS 11 -#define DOUBLE_FRAC_BITS 52 - -#define ONE_EXP(type) ((1 << (type ## _EXP_BITS - 1)) - 1) - -REGS_RETURN(unsigned_int_struct, unsigned_int_struct) -REGS_RETURN(double_unsigned_struct, double_unsigned_struct) - -/* float -> integer: (sign) 1.fraction x 2^(exponent - exp_for_one) */ - - -/* float to [unsigned] long long conversion */ -#define DEFINE__AEABI_F2XLZ(name, with_sign) \ -void __aeabi_ ## name(unsigned val) \ -{ \ - int exp, high_shift, sign; \ - double_unsigned_struct ret; \ - \ - /* compute sign */ \ - sign = val >> 31; \ - \ - /* compute real exponent */ \ - exp = val >> FLOAT_FRAC_BITS; \ - exp &= (1 << FLOAT_EXP_BITS) - 1; \ - exp -= ONE_EXP(FLOAT); \ - \ - /* undefined behavior if truncated value cannot be represented */ \ - if (with_sign) { \ - if (exp > 62) /* |val| too big, double cannot represent LLONG_MAX */ \ - return; \ - } else { \ - if ((sign && exp >= 0) || exp > 63) /* if val < 0 || val too big */ \ - return; \ - } \ - \ - val &= (1 << FLOAT_FRAC_BITS) - 1; \ - if (exp >= 32) { \ - ret.high = 1 << (exp - 32); \ - if (exp - 32 >= FLOAT_FRAC_BITS) { \ - ret.high |= val << (exp - 32 - FLOAT_FRAC_BITS); \ - ret.low = 0; \ - } else { \ - high_shift = FLOAT_FRAC_BITS - (exp - 32); \ - ret.high |= val >> high_shift; \ - ret.low = val << (32 - high_shift); \ - } \ - } else { \ - ret.high = 0; \ - ret.low = 1 << exp; \ - if (exp > FLOAT_FRAC_BITS) \ - ret.low |= val << (exp - FLOAT_FRAC_BITS); \ - else \ - ret.low |= val >> (FLOAT_FRAC_BITS - exp); \ - } \ - \ - /* encode negative integer using 2's complement */ \ - if (with_sign && sign) { \ - ret.low = ~ret.low; \ - ret.high = ~ret.high; \ - if (ret.low == UINT_MAX) { \ - ret.low = 0; \ - ret.high++; \ - } else \ - ret.low++; \ - } \ - \ - double_unsigned_struct_return(ret); \ -} - -/* float to unsigned long long conversion */ -DEFINE__AEABI_F2XLZ(f2ulz, 0) - -/* float to long long conversion */ -DEFINE__AEABI_F2XLZ(f2lz, 1) - -/* double to [unsigned] long long conversion */ -#define DEFINE__AEABI_D2XLZ(name, with_sign) \ -void __aeabi_ ## name(double_unsigned_struct val) \ -{ \ - int exp, high_shift, sign; \ - double_unsigned_struct ret; \ - \ - /* compute sign */ \ - sign = val.high >> 31; \ - \ - /* compute real exponent */ \ - exp = (val.high >> (DOUBLE_FRAC_BITS - 32)); \ - exp &= (1 << DOUBLE_EXP_BITS) - 1; \ - exp -= ONE_EXP(DOUBLE); \ - \ - /* undefined behavior if truncated value cannot be represented */ \ - if (with_sign) { \ - if (exp > 62) /* |val| too big, double cannot represent LLONG_MAX */ \ - return; \ - } else { \ - if ((sign && exp >= 0) || exp > 63) /* if val < 0 || val too big */ \ - return; \ - } \ - \ - val.high &= (1 << (DOUBLE_FRAC_BITS - 32)) - 1; \ - if (exp >= 32) { \ - ret.high = 1 << (exp - 32); \ - if (exp >= DOUBLE_FRAC_BITS) { \ - high_shift = exp - DOUBLE_FRAC_BITS; \ - ret.high |= val.high << high_shift; \ - ret.high |= val.low >> (32 - high_shift); \ - ret.low = val.low << high_shift; \ - } else { \ - high_shift = DOUBLE_FRAC_BITS - exp; \ - ret.high |= val.high >> high_shift; \ - ret.low = val.high << (32 - high_shift); \ - ret.low |= val.low >> high_shift; \ - } \ - } else { \ - ret.high = 0; \ - ret.low = 1 << exp; \ - if (exp > DOUBLE_FRAC_BITS - 32) { \ - high_shift = exp - DOUBLE_FRAC_BITS - 32; \ - ret.low |= val.high << high_shift; \ - ret.low |= val.low >> (32 - high_shift); \ - } else \ - ret.low |= val.high >> (DOUBLE_FRAC_BITS - 32 - exp); \ - } \ - \ - /* encode negative integer using 2's complement */ \ - if (with_sign && sign) { \ - ret.low = ~ret.low; \ - ret.high = ~ret.high; \ - if (ret.low == UINT_MAX) { \ - ret.low = 0; \ - ret.high++; \ - } else \ - ret.low++; \ - } \ - \ - double_unsigned_struct_return(ret); \ -} - -/* double to unsigned long long conversion */ -DEFINE__AEABI_D2XLZ(d2ulz, 0) - -/* double to long long conversion */ -DEFINE__AEABI_D2XLZ(d2lz, 1) - -/* long long to float conversion */ -#define DEFINE__AEABI_XL2F(name, with_sign) \ -unsigned __aeabi_ ## name(unsigned long long v) \ -{ \ - int s /* shift */, flb /* first lost bit */, sign = 0; \ - unsigned p = 0 /* power */, ret; \ - double_unsigned_struct val; \ - \ - /* fraction in negative float is encoded in 1's complement */ \ - if (with_sign && (v & (1ULL << 63))) { \ - sign = 1; \ - v = ~v + 1; \ - } \ - val.low = v; \ - val.high = v >> 32; \ - /* fill fraction bits */ \ - for (s = 31, p = 1 << 31; p && !(val.high & p); s--, p >>= 1); \ - if (p) { \ - ret = val.high & (p - 1); \ - if (s < FLOAT_FRAC_BITS) { \ - ret <<= FLOAT_FRAC_BITS - s; \ - ret |= val.low >> (32 - (FLOAT_FRAC_BITS - s)); \ - flb = (val.low >> (32 - (FLOAT_FRAC_BITS - s - 1))) & 1; \ - } else { \ - flb = (ret >> (s - FLOAT_FRAC_BITS - 1)) & 1; \ - ret >>= s - FLOAT_FRAC_BITS; \ - } \ - s += 32; \ - } else { \ - for (s = 31, p = 1 << 31; p && !(val.low & p); s--, p >>= 1); \ - if (p) { \ - ret = val.low & (p - 1); \ - if (s <= FLOAT_FRAC_BITS) { \ - ret <<= FLOAT_FRAC_BITS - s; \ - flb = 0; \ - } else { \ - flb = (ret >> (s - FLOAT_FRAC_BITS - 1)) & 1; \ - ret >>= s - FLOAT_FRAC_BITS; \ - } \ - } else \ - return 0; \ - } \ - if (flb) \ - ret++; \ - \ - /* fill exponent bits */ \ - ret |= (s + ONE_EXP(FLOAT)) << FLOAT_FRAC_BITS; \ - \ - /* fill sign bit */ \ - ret |= sign << 31; \ - \ - return ret; \ -} - -/* unsigned long long to float conversion */ -DEFINE__AEABI_XL2F(ul2f, 0) - -/* long long to float conversion */ -DEFINE__AEABI_XL2F(l2f, 1) - -/* long long to double conversion */ -#define __AEABI_XL2D(name, with_sign) \ -void __aeabi_ ## name(unsigned long long v) \ -{ \ - int s /* shift */, high_shift, sign = 0; \ - unsigned tmp, p = 0; \ - double_unsigned_struct val, ret; \ - \ - /* fraction in negative float is encoded in 1's complement */ \ - if (with_sign && (v & (1ULL << 63))) { \ - sign = 1; \ - v = ~v + 1; \ - } \ - val.low = v; \ - val.high = v >> 32; \ - \ - /* fill fraction bits */ \ - for (s = 31, p = 1 << 31; p && !(val.high & p); s--, p >>= 1); \ - if (p) { \ - tmp = val.high & (p - 1); \ - if (s < DOUBLE_FRAC_BITS - 32) { \ - high_shift = DOUBLE_FRAC_BITS - 32 - s; \ - ret.high = tmp << high_shift; \ - ret.high |= val.low >> (32 - high_shift); \ - ret.low = val.low << high_shift; \ - } else { \ - high_shift = s - (DOUBLE_FRAC_BITS - 32); \ - ret.high = tmp >> high_shift; \ - ret.low = tmp << (32 - high_shift); \ - ret.low |= val.low >> high_shift; \ - if ((val.low >> (high_shift - 1)) & 1) { \ - if (ret.low == UINT_MAX) { \ - ret.high++; \ - ret.low = 0; \ - } else \ - ret.low++; \ - } \ - } \ - s += 32; \ - } else { \ - for (s = 31, p = 1 << 31; p && !(val.low & p); s--, p >>= 1); \ - if (p) { \ - tmp = val.low & (p - 1); \ - if (s <= DOUBLE_FRAC_BITS - 32) { \ - high_shift = DOUBLE_FRAC_BITS - 32 - s; \ - ret.high = tmp << high_shift; \ - ret.low = 0; \ - } else { \ - high_shift = s - (DOUBLE_FRAC_BITS - 32); \ - ret.high = tmp >> high_shift; \ - ret.low = tmp << (32 - high_shift); \ - } \ - } else { \ - ret.high = ret.low = 0; \ - double_unsigned_struct_return(ret); \ - } \ - } \ - \ - /* fill exponent bits */ \ - ret.high |= (s + ONE_EXP(DOUBLE)) << (DOUBLE_FRAC_BITS - 32); \ - \ - /* fill sign bit */ \ - ret.high |= sign << 31; \ - \ - double_unsigned_struct_return(ret); \ -} - -/* unsigned long long to double conversion */ -__AEABI_XL2D(ul2d, 0) - -/* long long to double conversion */ -__AEABI_XL2D(l2d, 1) - - -/* Long long helper functions */ - -/* TODO: add error in case of den == 0 (see §4.3.1 and §4.3.2) */ - -#define define_aeabi_xdivmod_signed_type(basetype, type) \ -typedef struct type { \ - basetype quot; \ - unsigned basetype rem; \ -} type - -#define define_aeabi_xdivmod_unsigned_type(basetype, type) \ -typedef struct type { \ - basetype quot; \ - basetype rem; \ -} type - -#define AEABI_UXDIVMOD(name,type, rettype, typemacro) \ -static inline rettype aeabi_ ## name (type num, type den) \ -{ \ - rettype ret; \ - type quot = 0; \ - \ - /* Increase quotient while it is less than numerator */ \ - while (num >= den) { \ - type q = 1; \ - \ - /* Find closest power of two */ \ - while ((q << 1) * den <= num && q * den <= typemacro ## _MAX / 2) \ - q <<= 1; \ - \ - /* Compute difference between current quotient and numerator */ \ - num -= q * den; \ - quot += q; \ - } \ - ret.quot = quot; \ - ret.rem = num; \ - return ret; \ -} - -#define __AEABI_XDIVMOD(name, type, uiname, rettype, urettype, typemacro) \ -void __aeabi_ ## name(type numerator, type denominator) \ -{ \ - unsigned type num, den; \ - urettype uxdiv_ret; \ - rettype ret; \ - \ - if (numerator >= 0) \ - num = numerator; \ - else \ - num = 0 - numerator; \ - if (denominator >= 0) \ - den = denominator; \ - else \ - den = 0 - denominator; \ - uxdiv_ret = aeabi_ ## uiname(num, den); \ - /* signs differ */ \ - if ((numerator & typemacro ## _MIN) != (denominator & typemacro ## _MIN)) \ - ret.quot = 0 - uxdiv_ret.quot; \ - else \ - ret.quot = uxdiv_ret.quot; \ - if (numerator < 0) \ - ret.rem = 0 - uxdiv_ret.rem; \ - else \ - ret.rem = uxdiv_ret.rem; \ - \ - rettype ## _return(ret); \ -} - -define_aeabi_xdivmod_signed_type(long long, lldiv_t); -define_aeabi_xdivmod_unsigned_type(unsigned long long, ulldiv_t); -define_aeabi_xdivmod_signed_type(int, idiv_t); -define_aeabi_xdivmod_unsigned_type(unsigned, uidiv_t); - -REGS_RETURN(lldiv_t, lldiv_t) -REGS_RETURN(ulldiv_t, ulldiv_t) -REGS_RETURN(idiv_t, idiv_t) -REGS_RETURN(uidiv_t, uidiv_t) - -AEABI_UXDIVMOD(uldivmod, unsigned long long, ulldiv_t, ULONG) - -__AEABI_XDIVMOD(ldivmod, long long, uldivmod, lldiv_t, ulldiv_t, LLONG) - -void __aeabi_uldivmod(unsigned long long num, unsigned long long den) -{ - ulldiv_t_return(aeabi_uldivmod(num, den)); -} - -void __aeabi_llsl(double_unsigned_struct val, int shift) -{ - double_unsigned_struct ret; - - if (shift >= 32) { - val.high = val.low; - val.low = 0; - shift -= 32; - } - if (shift > 0) { - ret.low = val.low << shift; - ret.high = (val.high << shift) | (val.low >> (32 - shift)); - double_unsigned_struct_return(ret); - return; - } - double_unsigned_struct_return(val); -} - -#define aeabi_lsr(val, shift, fill, type) \ - type ## _struct ret; \ - \ - if (shift >= 32) { \ - val.low = val.high; \ - val.high = fill; \ - shift -= 32; \ - } \ - if (shift > 0) { \ - ret.high = val.high >> shift; \ - ret.low = (val.high << (32 - shift)) | (val.low >> shift); \ - type ## _struct_return(ret); \ - return; \ - } \ - type ## _struct_return(val); - -void __aeabi_llsr(double_unsigned_struct val, int shift) -{ - aeabi_lsr(val, shift, 0, double_unsigned); -} - -void __aeabi_lasr(unsigned_int_struct val, int shift) -{ - aeabi_lsr(val, shift, val.high >> 31, unsigned_int); -} - - -/* Integer division functions */ - -AEABI_UXDIVMOD(uidivmod, unsigned, uidiv_t, UINT) - -int __aeabi_idiv(int numerator, int denominator) -{ - unsigned num, den; - uidiv_t ret; - - if (numerator >= 0) - num = numerator; - else - num = 0 - numerator; - if (denominator >= 0) - den = denominator; - else - den = 0 - denominator; - ret = aeabi_uidivmod(num, den); - if ((numerator & INT_MIN) != (denominator & INT_MIN)) /* signs differ */ - ret.quot *= -1; - return ret.quot; -} - -unsigned __aeabi_uidiv(unsigned num, unsigned den) -{ - return aeabi_uidivmod(num, den).quot; -} - -__AEABI_XDIVMOD(idivmod, int, uidivmod, idiv_t, uidiv_t, INT) - -void __aeabi_uidivmod(unsigned num, unsigned den) -{ - uidiv_t_return(aeabi_uidivmod(num, den)); -} diff --git a/external/TCC/lib/bcheck.c b/external/TCC/lib/bcheck.c deleted file mode 100644 index 829e33d6..00000000 --- a/external/TCC/lib/bcheck.c +++ /dev/null @@ -1,950 +0,0 @@ -/* - * Tiny C Memory and bounds checker - * - * Copyright (c) 2002 Fabrice Bellard - * - * 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include -#include -#include -#if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) \ - && !defined(__DragonFly__) && !defined(__OpenBSD__) && !defined(__NetBSD__) -#include -#endif -#if !defined(_WIN32) -#include -#endif - -/* #define BOUND_DEBUG */ - -#ifdef BOUND_DEBUG - #define dprintf(a...) fprintf(a) -#else - #define dprintf(a...) -#endif - -/* define so that bound array is static (faster, but use memory if - bound checking not used) */ -/* #define BOUND_STATIC */ - -/* use malloc hooks. Currently the code cannot be reliable if no hooks */ -#define CONFIG_TCC_MALLOC_HOOKS -#define HAVE_MEMALIGN - -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) \ - || defined(__DragonFly__) || defined(__dietlibc__) \ - || defined(__UCLIBC__) || defined(__OpenBSD__) || defined(__NetBSD__) \ - || defined(_WIN32) || defined(TCC_UCLIBC) -#warning Bound checking does not support malloc (etc.) in this environment. -#undef CONFIG_TCC_MALLOC_HOOKS -#undef HAVE_MEMALIGN -#endif - -#define BOUND_T1_BITS 13 -#define BOUND_T2_BITS 11 -#define BOUND_T3_BITS (sizeof(size_t)*8 - BOUND_T1_BITS - BOUND_T2_BITS) -#define BOUND_E_BITS (sizeof(size_t)) - -#define BOUND_T1_SIZE (1 << BOUND_T1_BITS) -#define BOUND_T2_SIZE (1 << BOUND_T2_BITS) -#define BOUND_T3_SIZE (1 << BOUND_T3_BITS) - -#define BOUND_T23_BITS (BOUND_T2_BITS + BOUND_T3_BITS) -#define BOUND_T23_SIZE (1 << BOUND_T23_BITS) - - -/* this pointer is generated when bound check is incorrect */ -#define INVALID_POINTER ((void *)(-2)) -/* size of an empty region */ -#define EMPTY_SIZE ((size_t)(-1)) -/* size of an invalid region */ -#define INVALID_SIZE 0 - -typedef struct BoundEntry { - size_t start; - size_t size; - struct BoundEntry *next; - size_t is_invalid; /* true if pointers outside region are invalid */ -} BoundEntry; - -/* external interface */ -void __bound_init(void); -void __bound_new_region(void *p, size_t size); -int __bound_delete_region(void *p); - -#ifdef __attribute__ - /* an __attribute__ macro is defined in the system headers */ - #undef __attribute__ -#endif -#define FASTCALL __attribute__((regparm(3))) - -void *__bound_malloc(size_t size, const void *caller); -void *__bound_memalign(size_t size, size_t align, const void *caller); -void __bound_free(void *ptr, const void *caller); -void *__bound_realloc(void *ptr, size_t size, const void *caller); -static void *libc_malloc(size_t size); -static void libc_free(void *ptr); -static void install_malloc_hooks(void); -static void restore_malloc_hooks(void); - -#ifdef CONFIG_TCC_MALLOC_HOOKS -static void *saved_malloc_hook; -static void *saved_free_hook; -static void *saved_realloc_hook; -static void *saved_memalign_hook; -#endif - -/* TCC definitions */ -extern char __bounds_start; /* start of static bounds table */ -/* error message, just for TCC */ -const char *__bound_error_msg; - -/* runtime error output */ -extern void rt_error(size_t pc, const char *fmt, ...); - -#ifdef BOUND_STATIC -static BoundEntry *__bound_t1[BOUND_T1_SIZE]; /* page table */ -#else -static BoundEntry **__bound_t1; /* page table */ -#endif -static BoundEntry *__bound_empty_t2; /* empty page, for unused pages */ -static BoundEntry *__bound_invalid_t2; /* invalid page, for invalid pointers */ - -static BoundEntry *__bound_find_region(BoundEntry *e1, void *p) -{ - size_t addr, tmp; - BoundEntry *e; - - e = e1; - while (e != NULL) { - addr = (size_t)p; - addr -= e->start; - if (addr <= e->size) { - /* put region at the head */ - tmp = e1->start; - e1->start = e->start; - e->start = tmp; - tmp = e1->size; - e1->size = e->size; - e->size = tmp; - return e1; - } - e = e->next; - } - /* no entry found: return empty entry or invalid entry */ - if (e1->is_invalid) - return __bound_invalid_t2; - else - return __bound_empty_t2; -} - -/* print a bound error message */ -static void bound_error(const char *fmt, ...) -{ - __bound_error_msg = fmt; - fprintf(stderr,"%s %s: %s\n", __FILE__, __FUNCTION__, fmt); - *(int *)0 = 0; /* force a runtime error */ -} - -static void bound_alloc_error(void) -{ - bound_error("not enough memory for bound checking code"); -} - -/* return '(p + offset)' for pointer arithmetic (a pointer can reach - the end of a region in this case */ -void * FASTCALL __bound_ptr_add(void *p, size_t offset) -{ - size_t addr = (size_t)p; - BoundEntry *e; - - __bound_init(); - - dprintf(stderr, "%s %s: %p %p\n", __FILE__, __FUNCTION__, p, offset); - - e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)]; - e = (BoundEntry *)((char *)e + - ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) & - ((BOUND_T2_SIZE - 1) << BOUND_E_BITS))); - addr -= e->start; - if (addr > e->size) { - e = __bound_find_region(e, p); - addr = (size_t)p - e->start; - } - addr += offset; - if (addr >= e->size) { - fprintf(stderr,"%s %s: %p is outside of the region\n", __FILE__, __FUNCTION__, p + offset); - return INVALID_POINTER; /* return an invalid pointer */ - } - return p + offset; -} - -/* return '(p + offset)' for pointer indirection (the resulting must - be strictly inside the region */ -#define BOUND_PTR_INDIR(dsize) \ -void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset) \ -{ \ - size_t addr = (size_t)p; \ - BoundEntry *e; \ - \ - dprintf(stderr, "%s %s: %p %p start\n", __FILE__, __FUNCTION__, p, offset); \ - \ - __bound_init(); \ - e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)]; \ - e = (BoundEntry *)((char *)e + \ - ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) & \ - ((BOUND_T2_SIZE - 1) << BOUND_E_BITS))); \ - addr -= e->start; \ - if (addr > e->size) { \ - e = __bound_find_region(e, p); \ - addr = (size_t)p - e->start; \ - } \ - addr += offset + dsize; \ - if (addr > e->size) { \ - fprintf(stderr,"%s %s: %p is outside of the region\n", __FILE__, __FUNCTION__, p + offset); \ - return INVALID_POINTER; /* return an invalid pointer */ \ - } \ - dprintf(stderr, "%s %s: return p+offset = %p\n", __FILE__, __FUNCTION__, p + offset); \ - return p + offset; \ -} - -BOUND_PTR_INDIR(1) -BOUND_PTR_INDIR(2) -BOUND_PTR_INDIR(4) -BOUND_PTR_INDIR(8) -BOUND_PTR_INDIR(12) -BOUND_PTR_INDIR(16) - -/* return the frame pointer of the caller */ -#define GET_CALLER_FP(fp)\ -{\ - fp = (size_t)__builtin_frame_address(1);\ -} - -/* called when entering a function to add all the local regions */ -void FASTCALL __bound_local_new(void *p1) -{ - size_t addr, size, fp, *p = p1; - - dprintf(stderr, "%s, %s start p1=%p\n", __FILE__, __FUNCTION__, p); - GET_CALLER_FP(fp); - for(;;) { - addr = p[0]; - if (addr == 0) - break; - addr += fp; - size = p[1]; - p += 2; - __bound_new_region((void *)addr, size); - } - dprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__); -} - -/* called when leaving a function to delete all the local regions */ -void FASTCALL __bound_local_delete(void *p1) -{ - size_t addr, fp, *p = p1; - GET_CALLER_FP(fp); - for(;;) { - addr = p[0]; - if (addr == 0) - break; - addr += fp; - p += 2; - __bound_delete_region((void *)addr); - } -} - -static BoundEntry *__bound_new_page(void) -{ - BoundEntry *page; - size_t i; - - page = libc_malloc(sizeof(BoundEntry) * BOUND_T2_SIZE); - if (!page) - bound_alloc_error(); - for(i=0;i> BOUND_T3_BITS; - if (end != 0) - t2_end = end >> BOUND_T3_BITS; - else - t2_end = 1 << (BOUND_T1_BITS + BOUND_T2_BITS); - -#if 0 - dprintf(stderr, "mark_invalid: start = %x %x\n", t2_start, t2_end); -#endif - - /* first we handle full pages */ - t1_start = (t2_start + BOUND_T2_SIZE - 1) >> BOUND_T2_BITS; - t1_end = t2_end >> BOUND_T2_BITS; - - i = t2_start & (BOUND_T2_SIZE - 1); - j = t2_end & (BOUND_T2_SIZE - 1); - - if (t1_start == t1_end) { - page = get_page(t2_start >> BOUND_T2_BITS); - for(; i < j; i++) { - page[i].size = INVALID_SIZE; - page[i].is_invalid = 1; - } - } else { - if (i > 0) { - page = get_page(t2_start >> BOUND_T2_BITS); - for(; i < BOUND_T2_SIZE; i++) { - page[i].size = INVALID_SIZE; - page[i].is_invalid = 1; - } - } - for(i = t1_start; i < t1_end; i++) { - __bound_t1[i] = __bound_invalid_t2; - } - if (j != 0) { - page = get_page(t1_end); - for(i = 0; i < j; i++) { - page[i].size = INVALID_SIZE; - page[i].is_invalid = 1; - } - } - } -} - -void __bound_init(void) -{ - size_t i; - BoundEntry *page; - size_t start, size; - size_t *p; - - static int inited; - if (inited) - return; - - inited = 1; - - dprintf(stderr, "%s, %s() start\n", __FILE__, __FUNCTION__); - - /* save malloc hooks and install bound check hooks */ - install_malloc_hooks(); - -#ifndef BOUND_STATIC - __bound_t1 = libc_malloc(BOUND_T1_SIZE * sizeof(BoundEntry *)); - if (!__bound_t1) - bound_alloc_error(); -#endif - __bound_empty_t2 = __bound_new_page(); - for(i=0;i= v3.3, the alternative is to read - * start_brk from /proc/self/stat - */ - start = (size_t)sbrk(0); - size = 128 * 0x100000; - mark_invalid(start, size); -#endif - - /* add all static bound check values */ - p = (size_t *)&__bounds_start; - while (p[0] != 0) { - __bound_new_region((void *)p[0], p[1]); - p += 2; - } - - dprintf(stderr, "%s, %s() end\n\n", __FILE__, __FUNCTION__); -} - -void __bound_main_arg(void **p) -{ - void *start = p; - while (*p++); - - dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n", - __FILE__, __FUNCTION__, (void *) p - start); - - __bound_new_region(start, (void *) p - start); -} - -void __bound_exit(void) -{ - restore_malloc_hooks(); -} - -static inline void add_region(BoundEntry *e, - size_t start, size_t size) -{ - BoundEntry *e1; - if (e->start == 0) { - /* no region : add it */ - e->start = start; - e->size = size; - } else { - /* already regions in the list: add it at the head */ - e1 = bound_new_entry(); - e1->start = e->start; - e1->size = e->size; - e1->next = e->next; - e->start = start; - e->size = size; - e->next = e1; - } -} - -/* create a new region. It should not already exist in the region list */ -void __bound_new_region(void *p, size_t size) -{ - size_t start, end; - BoundEntry *page, *e, *e2; - size_t t1_start, t1_end, i, t2_start, t2_end; - - __bound_init(); - - dprintf(stderr, "%s, %s(%p, %p) start\n", - __FILE__, __FUNCTION__, p, size); - - start = (size_t)p; - end = start + size; - t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS); - t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS); - - /* start */ - page = get_page(t1_start); - t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) & - ((BOUND_T2_SIZE - 1) << BOUND_E_BITS); - t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) & - ((BOUND_T2_SIZE - 1) << BOUND_E_BITS); - - - e = (BoundEntry *)((char *)page + t2_start); - add_region(e, start, size); - - if (t1_end == t1_start) { - /* same ending page */ - e2 = (BoundEntry *)((char *)page + t2_end); - if (e2 > e) { - e++; - for(;estart = start; - e->size = size; - } - add_region(e, start, size); - } - } else { - /* mark until end of page */ - e2 = page + BOUND_T2_SIZE; - e++; - for(;estart = start; - e->size = size; - } - /* mark intermediate pages, if any */ - for(i=t1_start+1;istart = start; - e->size = size; - } - } - /* last page */ - page = get_page(t1_end); - e2 = (BoundEntry *)((char *)page + t2_end); - for(e=page;estart = start; - e->size = size; - } - add_region(e, start, size); - } - - dprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__); -} - -/* delete a region */ -static inline void delete_region(BoundEntry *e, - void *p, size_t empty_size) -{ - size_t addr; - BoundEntry *e1; - - addr = (size_t)p; - addr -= e->start; - if (addr <= e->size) { - /* region found is first one */ - e1 = e->next; - if (e1 == NULL) { - /* no more region: mark it empty */ - e->start = 0; - e->size = empty_size; - } else { - /* copy next region in head */ - e->start = e1->start; - e->size = e1->size; - e->next = e1->next; - bound_free_entry(e1); - } - } else { - /* find the matching region */ - for(;;) { - e1 = e; - e = e->next; - /* region not found: do nothing */ - if (e == NULL) - break; - addr = (size_t)p - e->start; - if (addr <= e->size) { - /* found: remove entry */ - e1->next = e->next; - bound_free_entry(e); - break; - } - } - } -} - -/* WARNING: 'p' must be the starting point of the region. */ -/* return non zero if error */ -int __bound_delete_region(void *p) -{ - size_t start, end, addr, size, empty_size; - BoundEntry *page, *e, *e2; - size_t t1_start, t1_end, t2_start, t2_end, i; - - __bound_init(); - - dprintf(stderr, "%s %s() start\n", __FILE__, __FUNCTION__); - - start = (size_t)p; - t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS); - t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) & - ((BOUND_T2_SIZE - 1) << BOUND_E_BITS); - - /* find region size */ - page = __bound_t1[t1_start]; - e = (BoundEntry *)((char *)page + t2_start); - addr = start - e->start; - if (addr > e->size) - e = __bound_find_region(e, p); - /* test if invalid region */ - if (e->size == EMPTY_SIZE || (size_t)p != e->start) - return -1; - /* compute the size we put in invalid regions */ - if (e->is_invalid) - empty_size = INVALID_SIZE; - else - empty_size = EMPTY_SIZE; - size = e->size; - end = start + size; - - /* now we can free each entry */ - t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS); - t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) & - ((BOUND_T2_SIZE - 1) << BOUND_E_BITS); - - delete_region(e, p, empty_size); - if (t1_end == t1_start) { - /* same ending page */ - e2 = (BoundEntry *)((char *)page + t2_end); - if (e2 > e) { - e++; - for(;estart = 0; - e->size = empty_size; - } - delete_region(e, p, empty_size); - } - } else { - /* mark until end of page */ - e2 = page + BOUND_T2_SIZE; - e++; - for(;estart = 0; - e->size = empty_size; - } - /* mark intermediate pages, if any */ - /* XXX: should free them */ - for(i=t1_start+1;istart = 0; - e->size = empty_size; - } - } - /* last page */ - page = get_page(t1_end); - e2 = (BoundEntry *)((char *)page + t2_end); - for(e=page;estart = 0; - e->size = empty_size; - } - delete_region(e, p, empty_size); - } - - dprintf(stderr, "%s %s() end\n", __FILE__, __FUNCTION__); - - return 0; -} - -/* return the size of the region starting at p, or EMPTY_SIZE if non - existent region. */ -static size_t get_region_size(void *p) -{ - size_t addr = (size_t)p; - BoundEntry *e; - - e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)]; - e = (BoundEntry *)((char *)e + - ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) & - ((BOUND_T2_SIZE - 1) << BOUND_E_BITS))); - addr -= e->start; - if (addr > e->size) - e = __bound_find_region(e, p); - if (e->start != (size_t)p) - return EMPTY_SIZE; - return e->size; -} - -/* patched memory functions */ - -/* force compiler to perform stores coded up to this point */ -#define barrier() __asm__ __volatile__ ("": : : "memory") - -static void install_malloc_hooks(void) -{ -#ifdef CONFIG_TCC_MALLOC_HOOKS - saved_malloc_hook = __malloc_hook; - saved_free_hook = __free_hook; - saved_realloc_hook = __realloc_hook; - saved_memalign_hook = __memalign_hook; - __malloc_hook = __bound_malloc; - __free_hook = __bound_free; - __realloc_hook = __bound_realloc; - __memalign_hook = __bound_memalign; - - barrier(); -#endif -} - -static void restore_malloc_hooks(void) -{ -#ifdef CONFIG_TCC_MALLOC_HOOKS - __malloc_hook = saved_malloc_hook; - __free_hook = saved_free_hook; - __realloc_hook = saved_realloc_hook; - __memalign_hook = saved_memalign_hook; - - barrier(); -#endif -} - -static void *libc_malloc(size_t size) -{ - void *ptr; - restore_malloc_hooks(); - ptr = malloc(size); - install_malloc_hooks(); - return ptr; -} - -static void libc_free(void *ptr) -{ - restore_malloc_hooks(); - free(ptr); - install_malloc_hooks(); -} - -/* XXX: we should use a malloc which ensure that it is unlikely that - two malloc'ed data have the same address if 'free' are made in - between. */ -void *__bound_malloc(size_t size, const void *caller) -{ - void *ptr; - - /* we allocate one more byte to ensure the regions will be - separated by at least one byte. With the glibc malloc, it may - be in fact not necessary */ - ptr = libc_malloc(size + 1); - - if (!ptr) - return NULL; - - dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n", - __FILE__, __FUNCTION__, ptr, size); - - __bound_new_region(ptr, size); - return ptr; -} - -void *__bound_memalign(size_t size, size_t align, const void *caller) -{ - void *ptr; - - restore_malloc_hooks(); - -#ifndef HAVE_MEMALIGN - if (align > 4) { - /* XXX: handle it ? */ - ptr = NULL; - } else { - /* we suppose that malloc aligns to at least four bytes */ - ptr = malloc(size + 1); - } -#else - /* we allocate one more byte to ensure the regions will be - separated by at least one byte. With the glibc malloc, it may - be in fact not necessary */ - ptr = memalign(size + 1, align); -#endif - - install_malloc_hooks(); - - if (!ptr) - return NULL; - - dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n", - __FILE__, __FUNCTION__, ptr, size); - - __bound_new_region(ptr, size); - return ptr; -} - -void __bound_free(void *ptr, const void *caller) -{ - if (ptr == NULL) - return; - if (__bound_delete_region(ptr) != 0) - bound_error("freeing invalid region"); - - libc_free(ptr); -} - -void *__bound_realloc(void *ptr, size_t size, const void *caller) -{ - void *ptr1; - size_t old_size; - - if (size == 0) { - __bound_free(ptr, caller); - return NULL; - } else { - ptr1 = __bound_malloc(size, caller); - if (ptr == NULL || ptr1 == NULL) - return ptr1; - old_size = get_region_size(ptr); - if (old_size == EMPTY_SIZE) - bound_error("realloc'ing invalid pointer"); - memcpy(ptr1, ptr, old_size); - __bound_free(ptr, caller); - return ptr1; - } -} - -#ifndef CONFIG_TCC_MALLOC_HOOKS -void *__bound_calloc(size_t nmemb, size_t size) -{ - void *ptr; - size = size * nmemb; - ptr = __bound_malloc(size, NULL); - if (!ptr) - return NULL; - memset(ptr, 0, size); - return ptr; -} -#endif - -#if 0 -static void bound_dump(void) -{ - BoundEntry *page, *e; - size_t i, j; - - fprintf(stderr, "region dump:\n"); - for(i=0;isize != EMPTY_SIZE && e->start != 0) { - fprintf(stderr, "%08x:", - (i << (BOUND_T2_BITS + BOUND_T3_BITS)) + - (j << BOUND_T3_BITS)); - do { - fprintf(stderr, " %08lx:%08lx", e->start, e->start + e->size); - e = e->next; - } while (e != NULL); - fprintf(stderr, "\n"); - } - } - } -} -#endif - -/* some useful checked functions */ - -/* check that (p ... p + size - 1) lies inside 'p' region, if any */ -static void __bound_check(const void *p, size_t size) -{ - if (size == 0) - return; - p = __bound_ptr_add((void *)p, size - 1); - if (p == INVALID_POINTER) - bound_error("invalid pointer"); -} - -void *__bound_memcpy(void *dst, const void *src, size_t size) -{ - void* p; - - dprintf(stderr, "%s %s: start, dst=%p src=%p size=%p\n", __FILE__, __FUNCTION__, dst, src, size); - - __bound_check(dst, size); - __bound_check(src, size); - /* check also region overlap */ - if (src >= dst && src < dst + size) - bound_error("overlapping regions in memcpy()"); - - p = memcpy(dst, src, size); - - dprintf(stderr, "%s %s: end, p=%p\n", __FILE__, __FUNCTION__, p); - return p; -} - -void *__bound_memmove(void *dst, const void *src, size_t size) -{ - __bound_check(dst, size); - __bound_check(src, size); - return memmove(dst, src, size); -} - -void *__bound_memset(void *dst, int c, size_t size) -{ - __bound_check(dst, size); - return memset(dst, c, size); -} - -/* XXX: could be optimized */ -int __bound_strlen(const char *s) -{ - const char *p; - size_t len; - - len = 0; - for(;;) { - p = __bound_ptr_indir1((char *)s, len); - if (p == INVALID_POINTER) - bound_error("bad pointer in strlen()"); - if (*p == '\0') - break; - len++; - } - return len; -} - -char *__bound_strcpy(char *dst, const char *src) -{ - size_t len; - void *p; - - dprintf(stderr, "%s %s: strcpy start, dst=%p src=%p\n", __FILE__, __FUNCTION__, dst, src); - len = __bound_strlen(src); - p = __bound_memcpy(dst, src, len + 1); - dprintf(stderr, "%s %s: strcpy end, p=%p\n", __FILE__, __FUNCTION__, dst, src, p); - return p; -} diff --git a/external/TCC/lib/lib-arm64.c b/external/TCC/lib/lib-arm64.c deleted file mode 100644 index 42d5936d..00000000 --- a/external/TCC/lib/lib-arm64.c +++ /dev/null @@ -1,652 +0,0 @@ -/* - * TCC runtime library for arm64. - * - * Copyright (c) 2015 Edmund Grimley Evans - * - * Copying and distribution of this file, with or without modification, - * are permitted in any medium without royalty provided the copyright - * notice and this notice are preserved. This file is offered as-is, - * without any warranty. - */ - -#include -#include - -void __clear_cache(void *beg, void *end) -{ - __arm64_clear_cache(beg, end); -} - -typedef struct { - uint64_t x0, x1; -} u128_t; - -static long double f3_zero(int sgn) -{ - long double f; - u128_t x = { 0, (uint64_t)sgn << 63 }; - memcpy(&f, &x, 16); - return f; -} - -static long double f3_infinity(int sgn) -{ - long double f; - u128_t x = { 0, (uint64_t)sgn << 63 | 0x7fff000000000000 }; - memcpy(&f, &x, 16); - return f; -} - -static long double f3_NaN(void) -{ - long double f; -#if 0 - // ARM's default NaN usually has just the top fraction bit set: - u128_t x = { 0, 0x7fff800000000000 }; -#else - // GCC's library sets all fraction bits: - u128_t x = { -1, 0x7fffffffffffffff }; -#endif - memcpy(&f, &x, 16); - return f; -} - -static int fp3_convert_NaN(long double *f, int sgn, u128_t mnt) -{ - u128_t x = { mnt.x0, - mnt.x1 | 0x7fff800000000000 | (uint64_t)sgn << 63 }; - memcpy(f, &x, 16); - return 1; -} - -static int fp3_detect_NaNs(long double *f, - int a_sgn, int a_exp, u128_t a, - int b_sgn, int b_exp, u128_t b) -{ - // Detect signalling NaNs: - if (a_exp == 32767 && (a.x0 | a.x1 << 16) && !(a.x1 >> 47 & 1)) - return fp3_convert_NaN(f, a_sgn, a); - if (b_exp == 32767 && (b.x0 | b.x1 << 16) && !(b.x1 >> 47 & 1)) - return fp3_convert_NaN(f, b_sgn, b); - - // Detect quiet NaNs: - if (a_exp == 32767 && (a.x0 | a.x1 << 16)) - return fp3_convert_NaN(f, a_sgn, a); - if (b_exp == 32767 && (b.x0 | b.x1 << 16)) - return fp3_convert_NaN(f, b_sgn, b); - - return 0; -} - -static void f3_unpack(int *sgn, int32_t *exp, u128_t *mnt, long double f) -{ - u128_t x; - memcpy(&x, &f, 16); - *sgn = x.x1 >> 63; - *exp = x.x1 >> 48 & 32767; - x.x1 = x.x1 << 16 >> 16; - if (*exp) - x.x1 |= (uint64_t)1 << 48; - else - *exp = 1; - *mnt = x; -} - -static u128_t f3_normalise(int32_t *exp, u128_t mnt) -{ - int sh; - if (!(mnt.x0 | mnt.x1)) - return mnt; - if (!mnt.x1) { - mnt.x1 = mnt.x0; - mnt.x0 = 0; - *exp -= 64; - } - for (sh = 32; sh; sh >>= 1) { - if (!(mnt.x1 >> (64 - sh))) { - mnt.x1 = mnt.x1 << sh | mnt.x0 >> (64 - sh); - mnt.x0 = mnt.x0 << sh; - *exp -= sh; - } - } - return mnt; -} - -static u128_t f3_sticky_shift(int32_t sh, u128_t x) -{ - if (sh >= 128) { - x.x0 = !!(x.x0 | x.x1); - x.x1 = 0; - return x; - } - if (sh >= 64) { - x.x0 = x.x1 | !!x.x0; - x.x1 = 0; - sh -= 64; - } - if (sh > 0) { - x.x0 = x.x0 >> sh | x.x1 << (64 - sh) | !!(x.x0 << (64 - sh)); - x.x1 = x.x1 >> sh; - } - return x; -} - -static long double f3_round(int sgn, int32_t exp, u128_t x) -{ - long double f; - int error; - - if (exp > 0) { - x = f3_sticky_shift(13, x); - } - else { - x = f3_sticky_shift(14 - exp, x); - exp = 0; - } - - error = x.x0 & 3; - x.x0 = x.x0 >> 2 | x.x1 << 62; - x.x1 = x.x1 >> 2; - - if (error == 3 || ((error == 2) & (x.x0 & 1))) { - if (!++x.x0) { - ++x.x1; - if (x.x1 == (uint64_t)1 << 48) - exp = 1; - else if (x.x1 == (uint64_t)1 << 49) { - ++exp; - x.x0 = x.x0 >> 1 | x.x1 << 63; - x.x1 = x.x1 >> 1; - } - } - } - - if (exp >= 32767) - return f3_infinity(sgn); - - x.x1 = x.x1 << 16 >> 16 | (uint64_t)exp << 48 | (uint64_t)sgn << 63; - memcpy(&f, &x, 16); - return f; -} - -static long double f3_add(long double fa, long double fb, int neg) -{ - u128_t a, b, x; - int32_t a_exp, b_exp, x_exp; - int a_sgn, b_sgn, x_sgn; - long double fx; - - f3_unpack(&a_sgn, &a_exp, &a, fa); - f3_unpack(&b_sgn, &b_exp, &b, fb); - - if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b)) - return fx; - - b_sgn ^= neg; - - // Handle infinities and zeroes: - if (a_exp == 32767 && b_exp == 32767 && a_sgn != b_sgn) - return f3_NaN(); - if (a_exp == 32767) - return f3_infinity(a_sgn); - if (b_exp == 32767) - return f3_infinity(b_sgn); - if (!(a.x0 | a.x1 | b.x0 | b.x1)) - return f3_zero(a_sgn & b_sgn); - - a.x1 = a.x1 << 3 | a.x0 >> 61; - a.x0 = a.x0 << 3; - b.x1 = b.x1 << 3 | b.x0 >> 61; - b.x0 = b.x0 << 3; - - if (a_exp <= b_exp) { - a = f3_sticky_shift(b_exp - a_exp, a); - a_exp = b_exp; - } - else { - b = f3_sticky_shift(a_exp - b_exp, b); - b_exp = a_exp; - } - - x_sgn = a_sgn; - x_exp = a_exp; - if (a_sgn == b_sgn) { - x.x0 = a.x0 + b.x0; - x.x1 = a.x1 + b.x1 + (x.x0 < a.x0); - } - else { - x.x0 = a.x0 - b.x0; - x.x1 = a.x1 - b.x1 - (x.x0 > a.x0); - if (x.x1 >> 63) { - x_sgn ^= 1; - x.x0 = -x.x0; - x.x1 = -x.x1 - !!x.x0; - } - } - - if (!(x.x0 | x.x1)) - return f3_zero(0); - - x = f3_normalise(&x_exp, x); - - return f3_round(x_sgn, x_exp + 12, x); -} - -long double __addtf3(long double a, long double b) -{ - return f3_add(a, b, 0); -} - -long double __subtf3(long double a, long double b) -{ - return f3_add(a, b, 1); -} - -long double __multf3(long double fa, long double fb) -{ - u128_t a, b, x; - int32_t a_exp, b_exp, x_exp; - int a_sgn, b_sgn, x_sgn; - long double fx; - - f3_unpack(&a_sgn, &a_exp, &a, fa); - f3_unpack(&b_sgn, &b_exp, &b, fb); - - if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b)) - return fx; - - // Handle infinities and zeroes: - if ((a_exp == 32767 && !(b.x0 | b.x1)) || - (b_exp == 32767 && !(a.x0 | a.x1))) - return f3_NaN(); - if (a_exp == 32767 || b_exp == 32767) - return f3_infinity(a_sgn ^ b_sgn); - if (!(a.x0 | a.x1) || !(b.x0 | b.x1)) - return f3_zero(a_sgn ^ b_sgn); - - a = f3_normalise(&a_exp, a); - b = f3_normalise(&b_exp, b); - - x_sgn = a_sgn ^ b_sgn; - x_exp = a_exp + b_exp - 16352; - - { - // Convert to base (1 << 30), discarding bottom 6 bits, which are zero, - // so there are (32, 30, 30, 30) bits in (a3, a2, a1, a0): - uint64_t a0 = a.x0 << 28 >> 34; - uint64_t b0 = b.x0 << 28 >> 34; - uint64_t a1 = a.x0 >> 36 | a.x1 << 62 >> 34; - uint64_t b1 = b.x0 >> 36 | b.x1 << 62 >> 34; - uint64_t a2 = a.x1 << 32 >> 34; - uint64_t b2 = b.x1 << 32 >> 34; - uint64_t a3 = a.x1 >> 32; - uint64_t b3 = b.x1 >> 32; - // Use 16 small multiplications and additions that do not overflow: - uint64_t x0 = a0 * b0; - uint64_t x1 = (x0 >> 30) + a0 * b1 + a1 * b0; - uint64_t x2 = (x1 >> 30) + a0 * b2 + a1 * b1 + a2 * b0; - uint64_t x3 = (x2 >> 30) + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; - uint64_t x4 = (x3 >> 30) + a1 * b3 + a2 * b2 + a3 * b1; - uint64_t x5 = (x4 >> 30) + a2 * b3 + a3 * b2; - uint64_t x6 = (x5 >> 30) + a3 * b3; - // We now have (64, 30, 30, ...) bits in (x6, x5, x4, ...). - // Take the top 128 bits, setting bottom bit if any lower bits were set: - uint64_t y0 = (x5 << 34 | x4 << 34 >> 30 | x3 << 34 >> 60 | - !!(x3 << 38 | (x2 | x1 | x0) << 34)); - uint64_t y1 = x6; - // Top bit may be zero. Renormalise: - if (!(y1 >> 63)) { - y1 = y1 << 1 | y0 >> 63; - y0 = y0 << 1; - --x_exp; - } - x.x0 = y0; - x.x1 = y1; - } - - return f3_round(x_sgn, x_exp, x); -} - -long double __divtf3(long double fa, long double fb) -{ - u128_t a, b, x; - int32_t a_exp, b_exp, x_exp; - int a_sgn, b_sgn, x_sgn, i; - long double fx; - - f3_unpack(&a_sgn, &a_exp, &a, fa); - f3_unpack(&b_sgn, &b_exp, &b, fb); - - if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b)) - return fx; - - // Handle infinities and zeroes: - if ((a_exp == 32767 && b_exp == 32767) || - (!(a.x0 | a.x1) && !(b.x0 | b.x1))) - return f3_NaN(); - if (a_exp == 32767 || !(b.x0 | b.x1)) - return f3_infinity(a_sgn ^ b_sgn); - if (!(a.x0 | a.x1) || b_exp == 32767) - return f3_zero(a_sgn ^ b_sgn); - - a = f3_normalise(&a_exp, a); - b = f3_normalise(&b_exp, b); - - x_sgn = a_sgn ^ b_sgn; - x_exp = a_exp - b_exp + 16395; - - a.x0 = a.x0 >> 1 | a.x1 << 63; - a.x1 = a.x1 >> 1; - b.x0 = b.x0 >> 1 | b.x1 << 63; - b.x1 = b.x1 >> 1; - x.x0 = 0; - x.x1 = 0; - for (i = 0; i < 116; i++) { - x.x1 = x.x1 << 1 | x.x0 >> 63; - x.x0 = x.x0 << 1; - if (a.x1 > b.x1 || (a.x1 == b.x1 && a.x0 >= b.x0)) { - a.x1 = a.x1 - b.x1 - (a.x0 < b.x0); - a.x0 = a.x0 - b.x0; - x.x0 |= 1; - } - a.x1 = a.x1 << 1 | a.x0 >> 63; - a.x0 = a.x0 << 1; - } - x.x0 |= !!(a.x0 | a.x1); - - x = f3_normalise(&x_exp, x); - - return f3_round(x_sgn, x_exp, x); -} - -long double __extendsftf2(float f) -{ - long double fx; - u128_t x; - uint32_t a; - uint64_t aa; - memcpy(&a, &f, 4); - aa = a; - x.x0 = 0; - if (!(a << 1)) - x.x1 = aa << 32; - else if (a << 1 >> 24 == 255) - x.x1 = (0x7fff000000000000 | aa >> 31 << 63 | aa << 41 >> 16 | - (uint64_t)!!(a << 9) << 47); - else - x.x1 = (aa >> 31 << 63 | ((aa >> 23 & 255) + 16256) << 48 | - aa << 41 >> 16); - memcpy(&fx, &x, 16); - return fx; -} - -long double __extenddftf2(double f) -{ - long double fx; - u128_t x; - uint64_t a; - memcpy(&a, &f, 8); - x.x0 = a << 60; - if (!(a << 1)) - x.x1 = a; - else if (a << 1 >> 53 == 2047) - x.x1 = (0x7fff000000000000 | a >> 63 << 63 | a << 12 >> 16 | - (uint64_t)!!(a << 12) << 47); - else - x.x1 = a >> 63 << 63 | ((a >> 52 & 2047) + 15360) << 48 | a << 12 >> 16; - memcpy(&fx, &x, 16); - return fx; -} - -float __trunctfsf2(long double f) -{ - u128_t mnt; - int32_t exp; - int sgn; - uint32_t x; - float fx; - - f3_unpack(&sgn, &exp, &mnt, f); - - if (exp == 32767 && (mnt.x0 | mnt.x1 << 16)) - x = 0x7fc00000 | (uint32_t)sgn << 31 | (mnt.x1 >> 25 & 0x007fffff); - else if (exp > 16510) - x = 0x7f800000 | (uint32_t)sgn << 31; - else if (exp < 16233) - x = (uint32_t)sgn << 31; - else { - exp -= 16257; - x = mnt.x1 >> 23 | !!(mnt.x0 | mnt.x1 << 41); - if (exp < 0) { - x = x >> -exp | !!(x << (32 + exp)); - exp = 0; - } - if ((x & 3) == 3 || (x & 7) == 6) - x += 4; - x = ((x >> 2) + (exp << 23)) | (uint32_t)sgn << 31; - } - memcpy(&fx, &x, 4); - return fx; -} - -double __trunctfdf2(long double f) -{ - u128_t mnt; - int32_t exp; - int sgn; - uint64_t x; - double fx; - - f3_unpack(&sgn, &exp, &mnt, f); - - if (exp == 32767 && (mnt.x0 | mnt.x1 << 16)) - x = (0x7ff8000000000000 | (uint64_t)sgn << 63 | - mnt.x1 << 16 >> 12 | mnt.x0 >> 60); - else if (exp > 17406) - x = 0x7ff0000000000000 | (uint64_t)sgn << 63; - else if (exp < 15308) - x = (uint64_t)sgn << 63; - else { - exp -= 15361; - x = mnt.x1 << 6 | mnt.x0 >> 58 | !!(mnt.x0 << 6); - if (exp < 0) { - x = x >> -exp | !!(x << (64 + exp)); - exp = 0; - } - if ((x & 3) == 3 || (x & 7) == 6) - x += 4; - x = ((x >> 2) + ((uint64_t)exp << 52)) | (uint64_t)sgn << 63; - } - memcpy(&fx, &x, 8); - return fx; -} - -int32_t __fixtfsi(long double fa) -{ - u128_t a; - int32_t a_exp; - int a_sgn; - int32_t x; - f3_unpack(&a_sgn, &a_exp, &a, fa); - if (a_exp < 16369) - return 0; - if (a_exp > 16413) - return a_sgn ? -0x80000000 : 0x7fffffff; - x = a.x1 >> (16431 - a_exp); - return a_sgn ? -x : x; -} - -int64_t __fixtfdi(long double fa) -{ - u128_t a; - int32_t a_exp; - int a_sgn; - int64_t x; - f3_unpack(&a_sgn, &a_exp, &a, fa); - if (a_exp < 16383) - return 0; - if (a_exp > 16445) - return a_sgn ? -0x8000000000000000 : 0x7fffffffffffffff; - x = (a.x1 << 15 | a.x0 >> 49) >> (16446 - a_exp); - return a_sgn ? -x : x; -} - -uint32_t __fixunstfsi(long double fa) -{ - u128_t a; - int32_t a_exp; - int a_sgn; - f3_unpack(&a_sgn, &a_exp, &a, fa); - if (a_sgn || a_exp < 16369) - return 0; - if (a_exp > 16414) - return -1; - return a.x1 >> (16431 - a_exp); -} - -uint64_t __fixunstfdi(long double fa) -{ - u128_t a; - int32_t a_exp; - int a_sgn; - f3_unpack(&a_sgn, &a_exp, &a, fa); - if (a_sgn || a_exp < 16383) - return 0; - if (a_exp > 16446) - return -1; - return (a.x1 << 15 | a.x0 >> 49) >> (16446 - a_exp); -} - -long double __floatsitf(int32_t a) -{ - int sgn = 0; - int exp = 16414; - uint32_t mnt = a; - u128_t x = { 0, 0 }; - long double f; - int i; - if (a) { - if (a < 0) { - sgn = 1; - mnt = -mnt; - } - for (i = 16; i; i >>= 1) - if (!(mnt >> (32 - i))) { - mnt <<= i; - exp -= i; - } - x.x1 = ((uint64_t)sgn << 63 | (uint64_t)exp << 48 | - (uint64_t)(mnt << 1) << 16); - } - memcpy(&f, &x, 16); - return f; -} - -long double __floatditf(int64_t a) -{ - int sgn = 0; - int exp = 16446; - uint64_t mnt = a; - u128_t x = { 0, 0 }; - long double f; - int i; - if (a) { - if (a < 0) { - sgn = 1; - mnt = -mnt; - } - for (i = 32; i; i >>= 1) - if (!(mnt >> (64 - i))) { - mnt <<= i; - exp -= i; - } - x.x0 = mnt << 49; - x.x1 = (uint64_t)sgn << 63 | (uint64_t)exp << 48 | mnt << 1 >> 16; - } - memcpy(&f, &x, 16); - return f; -} - -long double __floatunsitf(uint32_t a) -{ - int exp = 16414; - uint32_t mnt = a; - u128_t x = { 0, 0 }; - long double f; - int i; - if (a) { - for (i = 16; i; i >>= 1) - if (!(mnt >> (32 - i))) { - mnt <<= i; - exp -= i; - } - x.x1 = (uint64_t)exp << 48 | (uint64_t)(mnt << 1) << 16; - } - memcpy(&f, &x, 16); - return f; -} - -long double __floatunditf(uint64_t a) -{ - int exp = 16446; - uint64_t mnt = a; - u128_t x = { 0, 0 }; - long double f; - int i; - if (a) { - for (i = 32; i; i >>= 1) - if (!(mnt >> (64 - i))) { - mnt <<= i; - exp -= i; - } - x.x0 = mnt << 49; - x.x1 = (uint64_t)exp << 48 | mnt << 1 >> 16; - } - memcpy(&f, &x, 16); - return f; -} - -static int f3_cmp(long double fa, long double fb) -{ - u128_t a, b; - memcpy(&a, &fa, 16); - memcpy(&b, &fb, 16); - return (!(a.x0 | a.x1 << 1 | b.x0 | b.x1 << 1) ? 0 : - ((a.x1 << 1 >> 49 == 0x7fff && (a.x0 | a.x1 << 16)) || - (b.x1 << 1 >> 49 == 0x7fff && (b.x0 | b.x1 << 16))) ? 2 : - a.x1 >> 63 != b.x1 >> 63 ? (int)(b.x1 >> 63) - (int)(a.x1 >> 63) : - a.x1 < b.x1 ? (int)(a.x1 >> 63 << 1) - 1 : - a.x1 > b.x1 ? 1 - (int)(a.x1 >> 63 << 1) : - a.x0 < b.x0 ? (int)(a.x1 >> 63 << 1) - 1 : - b.x0 < a.x0 ? 1 - (int)(a.x1 >> 63 << 1) : 0); -} - -int __eqtf2(long double a, long double b) -{ - return !!f3_cmp(a, b); -} - -int __netf2(long double a, long double b) -{ - return !!f3_cmp(a, b); -} - -int __lttf2(long double a, long double b) -{ - return f3_cmp(a, b); -} - -int __letf2(long double a, long double b) -{ - return f3_cmp(a, b); -} - -int __gttf2(long double a, long double b) -{ - return -f3_cmp(b, a); -} - -int __getf2(long double a, long double b) -{ - return -f3_cmp(b, a); -} diff --git a/external/TCC/lib/libtcc1.c b/external/TCC/lib/libtcc1.c deleted file mode 100644 index a5fee7b9..00000000 --- a/external/TCC/lib/libtcc1.c +++ /dev/null @@ -1,753 +0,0 @@ -/* TCC runtime library. - Parts of this code are (c) 2002 Fabrice Bellard - - Copyright (C) 1987, 1988, 1992, 1994, 1995 Free Software Foundation, Inc. - -This file is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -In addition to the permissions in the GNU General Public License, the -Free Software Foundation gives you unlimited permission to link the -compiled version of this file into combinations with other programs, -and to distribute those combinations without any restriction coming -from the use of this file. (The General Public License restrictions -do apply in other respects; for example, they cover modification of -the file, and distribution when not linked into a combine -executable.) - -This file 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 -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. -*/ - -#include - -#define W_TYPE_SIZE 32 -#define BITS_PER_UNIT 8 - -typedef int Wtype; -typedef unsigned int UWtype; -typedef unsigned int USItype; -typedef long long DWtype; -typedef unsigned long long UDWtype; - -struct DWstruct { - Wtype low, high; -}; - -typedef union -{ - struct DWstruct s; - DWtype ll; -} DWunion; - -typedef long double XFtype; -#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) -#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) - -/* the following deal with IEEE single-precision numbers */ -#define EXCESS 126 -#define SIGNBIT 0x80000000 -#define HIDDEN (1 << 23) -#define SIGN(fp) ((fp) & SIGNBIT) -#define EXP(fp) (((fp) >> 23) & 0xFF) -#define MANT(fp) (((fp) & 0x7FFFFF) | HIDDEN) -#define PACK(s,e,m) ((s) | ((e) << 23) | (m)) - -/* the following deal with IEEE double-precision numbers */ -#define EXCESSD 1022 -#define HIDDEND (1 << 20) -#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) -#define SIGND(fp) ((fp.l.upper) & SIGNBIT) -#define MANTD(fp) (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \ - (fp.l.lower >> 22)) -#define HIDDEND_LL ((long long)1 << 52) -#define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL) -#define PACKD_LL(s,e,m) (((long long)((s)+((e)<<20))<<32)|(m)) - -/* the following deal with x86 long double-precision numbers */ -#define EXCESSLD 16382 -#define EXPLD(fp) (fp.l.upper & 0x7fff) -#define SIGNLD(fp) ((fp.l.upper) & 0x8000) - -/* only for x86 */ -union ldouble_long { - long double ld; - struct { - unsigned long long lower; - unsigned short upper; - } l; -}; - -union double_long { - double d; -#if 1 - struct { - unsigned int lower; - int upper; - } l; -#else - struct { - int upper; - unsigned int lower; - } l; -#endif - long long ll; -}; - -union float_long { - float f; - unsigned int l; -}; - -/* XXX: we don't support several builtin supports for now */ -#if !defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_ARM) - -/* XXX: use gcc/tcc intrinsic ? */ -#if defined(TCC_TARGET_I386) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("subl %5,%1\n\tsbbl %3,%0" \ - : "=r" ((USItype) (sh)), \ - "=&r" ((USItype) (sl)) \ - : "0" ((USItype) (ah)), \ - "g" ((USItype) (bh)), \ - "1" ((USItype) (al)), \ - "g" ((USItype) (bl))) -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("mull %3" \ - : "=a" ((USItype) (w0)), \ - "=d" ((USItype) (w1)) \ - : "%0" ((USItype) (u)), \ - "rm" ((USItype) (v))) -#define udiv_qrnnd(q, r, n1, n0, dv) \ - __asm__ ("divl %4" \ - : "=a" ((USItype) (q)), \ - "=d" ((USItype) (r)) \ - : "0" ((USItype) (n0)), \ - "1" ((USItype) (n1)), \ - "rm" ((USItype) (dv))) -#define count_leading_zeros(count, x) \ - do { \ - USItype __cbtmp; \ - __asm__ ("bsrl %1,%0" \ - : "=r" (__cbtmp) : "rm" ((USItype) (x))); \ - (count) = __cbtmp ^ 31; \ - } while (0) -#else -#error unsupported CPU type -#endif - -/* most of this code is taken from libgcc2.c from gcc */ - -static UDWtype __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) -{ - DWunion ww; - DWunion nn, dd; - DWunion rr; - UWtype d0, d1, n0, n1, n2; - UWtype q0, q1; - UWtype b, bm; - - nn.ll = n; - dd.ll = d; - - d0 = dd.s.low; - d1 = dd.s.high; - n0 = nn.s.low; - n1 = nn.s.high; - -#if !defined(UDIV_NEEDS_NORMALIZATION) - if (d1 == 0) - { - if (d0 > n1) - { - /* 0q = nn / 0D */ - - udiv_qrnnd (q0, n0, n1, n0, d0); - q1 = 0; - - /* Remainder in n0. */ - } - else - { - /* qq = NN / 0d */ - - if (d0 == 0) - d0 = 1 / d0; /* Divide intentionally by zero. */ - - udiv_qrnnd (q1, n1, 0, n1, d0); - udiv_qrnnd (q0, n0, n1, n0, d0); - - /* Remainder in n0. */ - } - - if (rp != 0) - { - rr.s.low = n0; - rr.s.high = 0; - *rp = rr.ll; - } - } - -#else /* UDIV_NEEDS_NORMALIZATION */ - - if (d1 == 0) - { - if (d0 > n1) - { - /* 0q = nn / 0D */ - - count_leading_zeros (bm, d0); - - if (bm != 0) - { - /* Normalize, i.e. make the most significant bit of the - denominator set. */ - - d0 = d0 << bm; - n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm)); - n0 = n0 << bm; - } - - udiv_qrnnd (q0, n0, n1, n0, d0); - q1 = 0; - - /* Remainder in n0 >> bm. */ - } - else - { - /* qq = NN / 0d */ - - if (d0 == 0) - d0 = 1 / d0; /* Divide intentionally by zero. */ - - count_leading_zeros (bm, d0); - - if (bm == 0) - { - /* From (n1 >= d0) /\ (the most significant bit of d0 is set), - conclude (the most significant bit of n1 is set) /\ (the - leading quotient digit q1 = 1). - - This special case is necessary, not an optimization. - (Shifts counts of W_TYPE_SIZE are undefined.) */ - - n1 -= d0; - q1 = 1; - } - else - { - /* Normalize. */ - - b = W_TYPE_SIZE - bm; - - d0 = d0 << bm; - n2 = n1 >> b; - n1 = (n1 << bm) | (n0 >> b); - n0 = n0 << bm; - - udiv_qrnnd (q1, n1, n2, n1, d0); - } - - /* n1 != d0... */ - - udiv_qrnnd (q0, n0, n1, n0, d0); - - /* Remainder in n0 >> bm. */ - } - - if (rp != 0) - { - rr.s.low = n0 >> bm; - rr.s.high = 0; - *rp = rr.ll; - } - } -#endif /* UDIV_NEEDS_NORMALIZATION */ - - else - { - if (d1 > n1) - { - /* 00 = nn / DD */ - - q0 = 0; - q1 = 0; - - /* Remainder in n1n0. */ - if (rp != 0) - { - rr.s.low = n0; - rr.s.high = n1; - *rp = rr.ll; - } - } - else - { - /* 0q = NN / dd */ - - count_leading_zeros (bm, d1); - if (bm == 0) - { - /* From (n1 >= d1) /\ (the most significant bit of d1 is set), - conclude (the most significant bit of n1 is set) /\ (the - quotient digit q0 = 0 or 1). - - This special case is necessary, not an optimization. */ - - /* The condition on the next line takes advantage of that - n1 >= d1 (true due to program flow). */ - if (n1 > d1 || n0 >= d0) - { - q0 = 1; - sub_ddmmss (n1, n0, n1, n0, d1, d0); - } - else - q0 = 0; - - q1 = 0; - - if (rp != 0) - { - rr.s.low = n0; - rr.s.high = n1; - *rp = rr.ll; - } - } - else - { - UWtype m1, m0; - /* Normalize. */ - - b = W_TYPE_SIZE - bm; - - d1 = (d1 << bm) | (d0 >> b); - d0 = d0 << bm; - n2 = n1 >> b; - n1 = (n1 << bm) | (n0 >> b); - n0 = n0 << bm; - - udiv_qrnnd (q0, n1, n2, n1, d1); - umul_ppmm (m1, m0, q0, d0); - - if (m1 > n1 || (m1 == n1 && m0 > n0)) - { - q0--; - sub_ddmmss (m1, m0, m1, m0, d1, d0); - } - - q1 = 0; - - /* Remainder in (n1n0 - m1m0) >> bm. */ - if (rp != 0) - { - sub_ddmmss (n1, n0, n1, n0, m1, m0); - rr.s.low = (n1 << b) | (n0 >> bm); - rr.s.high = n1 >> bm; - *rp = rr.ll; - } - } - } - } - - ww.s.low = q0; - ww.s.high = q1; - return ww.ll; -} - -#define __negdi2(a) (-(a)) - -long long __divdi3(long long u, long long v) -{ - int c = 0; - DWunion uu, vv; - DWtype w; - - uu.ll = u; - vv.ll = v; - - if (uu.s.high < 0) { - c = ~c; - uu.ll = __negdi2 (uu.ll); - } - if (vv.s.high < 0) { - c = ~c; - vv.ll = __negdi2 (vv.ll); - } - w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0); - if (c) - w = __negdi2 (w); - return w; -} - -long long __moddi3(long long u, long long v) -{ - int c = 0; - DWunion uu, vv; - DWtype w; - - uu.ll = u; - vv.ll = v; - - if (uu.s.high < 0) { - c = ~c; - uu.ll = __negdi2 (uu.ll); - } - if (vv.s.high < 0) - vv.ll = __negdi2 (vv.ll); - - __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) &w); - if (c) - w = __negdi2 (w); - return w; -} - -unsigned long long __udivdi3(unsigned long long u, unsigned long long v) -{ - return __udivmoddi4 (u, v, (UDWtype *) 0); -} - -unsigned long long __umoddi3(unsigned long long u, unsigned long long v) -{ - UDWtype w; - - __udivmoddi4 (u, v, &w); - return w; -} - -/* XXX: fix tcc's code generator to do this instead */ -long long __ashrdi3(long long a, int b) -{ -#ifdef __TINYC__ - DWunion u; - u.ll = a; - if (b >= 32) { - u.s.low = u.s.high >> (b - 32); - u.s.high = u.s.high >> 31; - } else if (b != 0) { - u.s.low = ((unsigned)u.s.low >> b) | (u.s.high << (32 - b)); - u.s.high = u.s.high >> b; - } - return u.ll; -#else - return a >> b; -#endif -} - -/* XXX: fix tcc's code generator to do this instead */ -unsigned long long __lshrdi3(unsigned long long a, int b) -{ -#ifdef __TINYC__ - DWunion u; - u.ll = a; - if (b >= 32) { - u.s.low = (unsigned)u.s.high >> (b - 32); - u.s.high = 0; - } else if (b != 0) { - u.s.low = ((unsigned)u.s.low >> b) | (u.s.high << (32 - b)); - u.s.high = (unsigned)u.s.high >> b; - } - return u.ll; -#else - return a >> b; -#endif -} - -/* XXX: fix tcc's code generator to do this instead */ -long long __ashldi3(long long a, int b) -{ -#ifdef __TINYC__ - DWunion u; - u.ll = a; - if (b >= 32) { - u.s.high = (unsigned)u.s.low << (b - 32); - u.s.low = 0; - } else if (b != 0) { - u.s.high = ((unsigned)u.s.high << b) | ((unsigned)u.s.low >> (32 - b)); - u.s.low = (unsigned)u.s.low << b; - } - return u.ll; -#else - return a << b; -#endif -} - -#ifndef COMMIT_4ad186c5ef61_IS_FIXED -long long __tcc_cvt_ftol(long double x) -{ - unsigned c0, c1; - long long ret; - __asm__ __volatile__ ("fnstcw %0" : "=m" (c0)); - c1 = c0 | 0x0C00; - __asm__ __volatile__ ("fldcw %0" : : "m" (c1)); - __asm__ __volatile__ ("fistpll %0" : "=m" (ret)); - __asm__ __volatile__ ("fldcw %0" : : "m" (c0)); - return ret; -} -#endif - -#endif /* !__x86_64__ */ - -/* XXX: fix tcc's code generator to do this instead */ -float __floatundisf(unsigned long long a) -{ - DWunion uu; - XFtype r; - - uu.ll = a; - if (uu.s.high >= 0) { - return (float)uu.ll; - } else { - r = (XFtype)uu.ll; - r += 18446744073709551616.0; - return (float)r; - } -} - -double __floatundidf(unsigned long long a) -{ - DWunion uu; - XFtype r; - - uu.ll = a; - if (uu.s.high >= 0) { - return (double)uu.ll; - } else { - r = (XFtype)uu.ll; - r += 18446744073709551616.0; - return (double)r; - } -} - -long double __floatundixf(unsigned long long a) -{ - DWunion uu; - XFtype r; - - uu.ll = a; - if (uu.s.high >= 0) { - return (long double)uu.ll; - } else { - r = (XFtype)uu.ll; - r += 18446744073709551616.0; - return (long double)r; - } -} - -unsigned long long __fixunssfdi (float a1) -{ - register union float_long fl1; - register int exp; - register unsigned long l; - - fl1.f = a1; - - if (fl1.l == 0) - return (0); - - exp = EXP (fl1.l) - EXCESS - 24; - - l = MANT(fl1.l); - if (exp >= 41) - return (unsigned long long)-1; - else if (exp >= 0) - return (unsigned long long)l << exp; - else if (exp >= -23) - return l >> -exp; - else - return 0; -} - -unsigned long long __fixunsdfdi (double a1) -{ - register union double_long dl1; - register int exp; - register unsigned long long l; - - dl1.d = a1; - - if (dl1.ll == 0) - return (0); - - exp = EXPD (dl1) - EXCESSD - 53; - - l = MANTD_LL(dl1); - - if (exp >= 12) - return (unsigned long long)-1; - else if (exp >= 0) - return l << exp; - else if (exp >= -52) - return l >> -exp; - else - return 0; -} - -unsigned long long __fixunsxfdi (long double a1) -{ - register union ldouble_long dl1; - register int exp; - register unsigned long long l; - - dl1.ld = a1; - - if (dl1.l.lower == 0 && dl1.l.upper == 0) - return (0); - - exp = EXPLD (dl1) - EXCESSLD - 64; - - l = dl1.l.lower; - - if (exp > 0) - return (unsigned long long)-1; - else if (exp >= -63) - return l >> -exp; - else - return 0; -} - -long long __fixsfdi (float a1) -{ - long long ret; int s; - ret = __fixunssfdi((s = a1 >= 0) ? a1 : -a1); - return s ? ret : -ret; -} - -long long __fixdfdi (double a1) -{ - long long ret; int s; - ret = __fixunsdfdi((s = a1 >= 0) ? a1 : -a1); - return s ? ret : -ret; -} - -long long __fixxfdi (long double a1) -{ - long long ret; int s; - ret = __fixunsxfdi((s = a1 >= 0) ? a1 : -a1); - return s ? ret : -ret; -} - -#if defined(TCC_TARGET_X86_64) && !defined(_WIN64) - -#ifndef __TINYC__ -#include -#include -#include -#else -/* Avoid including stdlib.h because it is not easily available when - cross compiling */ -#include /* size_t definition is needed for a x86_64-tcc to parse memset() */ -extern void *malloc(unsigned long long); -extern void *memset(void *s, int c, size_t n); -extern void free(void*); -extern void abort(void); -#endif - -enum __va_arg_type { - __va_gen_reg, __va_float_reg, __va_stack -}; - -//This should be in sync with the declaration on our include/stdarg.h -/* GCC compatible definition of va_list. */ -typedef struct { - unsigned int gp_offset; - unsigned int fp_offset; - union { - unsigned int overflow_offset; - char *overflow_arg_area; - }; - char *reg_save_area; -} __va_list_struct; - -#undef __va_start -#undef __va_arg -#undef __va_copy -#undef __va_end - -void __va_start(__va_list_struct *ap, void *fp) -{ - memset(ap, 0, sizeof(__va_list_struct)); - *ap = *(__va_list_struct *)((char *)fp - 16); - ap->overflow_arg_area = (char *)fp + ap->overflow_offset; - ap->reg_save_area = (char *)fp - 176 - 16; -} - -void *__va_arg(__va_list_struct *ap, - enum __va_arg_type arg_type, - int size, int align) -{ - size = (size + 7) & ~7; - align = (align + 7) & ~7; - switch (arg_type) { - case __va_gen_reg: - if (ap->gp_offset + size <= 48) { - ap->gp_offset += size; - return ap->reg_save_area + ap->gp_offset - size; - } - goto use_overflow_area; - - case __va_float_reg: - if (ap->fp_offset < 128 + 48) { - ap->fp_offset += 16; - return ap->reg_save_area + ap->fp_offset - 16; - } - size = 8; - goto use_overflow_area; - - case __va_stack: - use_overflow_area: - ap->overflow_arg_area += size; - ap->overflow_arg_area = (char*)((intptr_t)(ap->overflow_arg_area + align - 1) & -(intptr_t)align); - return ap->overflow_arg_area - size; - - default: -#ifndef __TINYC__ - fprintf(stderr, "unknown ABI type for __va_arg\n"); -#endif - abort(); - } -} - -#endif /* __x86_64__ */ - -/* Flushing for tccrun */ -#if defined(TCC_TARGET_X86_64) || defined(TCC_TARGET_I386) - -void __clear_cache(void *beginning, void *end) -{ -} - -#elif defined(TCC_TARGET_ARM) - -#define _GNU_SOURCE -#include -#include -#include - -void __clear_cache(void *beginning, void *end) -{ -/* __ARM_NR_cacheflush is kernel private and should not be used in user space. - * However, there is no ARM asm parser in tcc so we use it for now */ -#if 1 - syscall(__ARM_NR_cacheflush, beginning, end, 0); -#else - __asm__ ("push {r7}\n\t" - "mov r7, #0xf0002\n\t" - "mov r2, #0\n\t" - "swi 0\n\t" - "pop {r7}\n\t" - "ret"); -#endif -} - -#else -#warning __clear_cache not defined for this architecture, avoid using tcc -run -#endif diff --git a/external/TCC/lib/testfp.c b/external/TCC/lib/testfp.c deleted file mode 100644 index 63342b42..00000000 --- a/external/TCC/lib/testfp.c +++ /dev/null @@ -1,510 +0,0 @@ -/* - * Test 128-bit floating-point arithmetic on arm64: - * build with two different compilers and compare the output. - * - * Copyright (c) 2015 Edmund Grimley Evans - * - * Copying and distribution of this file, with or without modification, - * are permitted in any medium without royalty provided the copyright - * notice and this notice are preserved. This file is offered as-is, - * without any warranty. - */ - -#include -#include -#include -#include - -#define check(x) ((x) ? (void)0 : check_fail(#x, __FILE__, __LINE__)) - -void check_fail(const char *assertion, const char *file, unsigned int line) -{ - printf("%s:%d: Check (%s) failed.", file, line, assertion); - exit(1); -} - -typedef struct { - unsigned long long x0, x1; -} u128_t; - -float copy_fi(uint32_t x) -{ - float f; - memcpy(&f, &x, 4); - return f; -} - -double copy_di(uint64_t x) -{ - double f; - memcpy(&f, &x, 8); - return f; -} - -long double copy_ldi(u128_t x) -{ - long double f; - memcpy(&f, &x, 16); - return f; -} - -uint32_t copy_if(float f) -{ - uint32_t x; - memcpy(&x, &f, 4); - return x; -} - -uint64_t copy_id(double f) -{ - uint64_t x; - memcpy(&x, &f, 8); - return x; -} - -u128_t copy_ild(long double f) -{ - u128_t x; - memcpy(&x, &f, 16); - return x; -} - -long double make(int sgn, int exp, uint64_t high, uint64_t low) -{ - u128_t x = { low, - (0x0000ffffffffffff & high) | - (0x7fff000000000000 & (uint64_t)exp << 48) | - (0x8000000000000000 & (uint64_t)sgn << 63) }; - return copy_ldi(x); -} - -void cmp(long double a, long double b) -{ - u128_t ax = copy_ild(a); - u128_t bx = copy_ild(b); - int eq = (a == b); - int ne = (a != b); - int lt = (a < b); - int le = (a <= b); - int gt = (a > b); - int ge = (a >= b); - - check(eq == 0 || eq == 1); - check(lt == 0 || lt == 1); - check(gt == 0 || gt == 1); - check(ne == !eq && le == (lt | eq) && ge == (gt | eq)); - check(eq + lt + gt < 2); - - printf("cmp %016llx%016llx %016llx%016llx %d %d %d\n", - ax.x1, ax.x0, bx.x1, bx.x0, lt, eq, gt); -} - -void cmps(void) -{ - int i, j; - - for (i = 0; i < 2; i++) - for (j = 0; j < 2; j++) - cmp(make(i, 0, 0, 0), make(j, 0, 0, 0)); - - for (i = 0; i < 2; i++) { - for (j = 0; j < 64; j++) { - long double f1 = make(i, 32767, (uint64_t)1 << j, 0); - long double f2 = make(i, 32767, 0, (uint64_t)1 << j); - cmp(f1, 0); - cmp(f2, 0); - cmp(0, f1); - cmp(0, f2); - } - } - - for (i = 0; i < 6; i++) - for (j = 0; j < 6; j++) - cmp(make(i & 1, i >> 1, 0, 0), - make(j & 1, j >> 1, 0, 0)); - - for (i = 0; i < 2; i++) { - for (j = 0; j < 2; j++) { - int a, b; - for (a = 0; a < 2; a++) { - for (b = 0; b < 2; b++) { - cmp(make(i, j, a, b), make(i, j, 0, 0)); - cmp(make(i, j, 0, 0), make(i, j, a, b)); - } - } - } - } -} - -void xop(const char *name, long double a, long double b, long double c) -{ - u128_t ax = copy_ild(a); - u128_t bx = copy_ild(b); - u128_t cx = copy_ild(c); - printf("%s %016llx%016llx %016llx%016llx %016llx%016llx\n", - name, ax.x1, ax.x0, bx.x1, bx.x0, cx.x1, cx.x0); -} - -void fadd(long double a, long double b) -{ - xop("add", a, b, a + b); -} - -void fsub(long double a, long double b) -{ - xop("sub", a, b, a - b); -} - -void fmul(long double a, long double b) -{ - xop("mul", a, b, a * b); -} - -void fdiv(long double a, long double b) -{ - xop("div", a, b, a / b); -} - -void nanz(void) -{ - // Check NaNs: - { - long double x[7]; - int i, j, n = 0; - x[n++] = make(0, 32000, 0x95132b76effc, 0xd79035214b4f8d53); - x[n++] = make(1, 32001, 0xbe71d7a51587, 0x30601c6815d6c3ac); - x[n++] = make(0, 32767, 0, 1); - x[n++] = make(0, 32767, (uint64_t)1 << 46, 0); - x[n++] = make(1, 32767, (uint64_t)1 << 47, 0); - x[n++] = make(1, 32767, 0x7596c7099ad5, 0xe25fed2c58f73fc9); - x[n++] = make(0, 32767, 0x835d143360f9, 0x5e315efb35630666); - check(n == sizeof(x) / sizeof(*x)); - for (i = 0; i < n; i++) { - for (j = 0; j < n; j++) { - fadd(x[i], x[j]); - fsub(x[i], x[j]); - fmul(x[i], x[j]); - fdiv(x[i], x[j]); - } - } - } - - // Check infinities and zeroes: - { - long double x[6]; - int i, j, n = 0; - x[n++] = make(1, 32000, 0x62acda85f700, 0x47b6c9f35edc4044); - x[n++] = make(0, 32001, 0x94b7abf55af7, 0x9f425fe354428e19); - x[n++] = make(0, 32767, 0, 0); - x[n++] = make(1, 32767, 0, 0); - x[n++] = make(0, 0, 0, 0); - x[n++] = make(1, 0, 0, 0); - check(n == sizeof(x) / sizeof(*x)); - for (i = 0; i < n; i++) { - for (j = 0; j < n; j++) { - fadd(x[i], x[j]); - fsub(x[i], x[j]); - fmul(x[i], x[j]); - fdiv(x[i], x[j]); - } - } - } -} - -void adds(void) -{ - // Check shifting and add/sub: - { - int i; - for (i = -130; i <= 130; i++) { - int s1 = (uint32_t)i % 3 < 1; - int s2 = (uint32_t)i % 5 < 2; - fadd(make(s1, 16384 , 0x502c065e4f71a65d, 0xd2f9bdb031f4f031), - make(s2, 16384 + i, 0xae267395a9bc1033, 0xb56b5800da1ba448)); - } - } - - // Check normalisation: - { - uint64_t a0 = 0xc6bab0a6afbef5ed; - uint64_t a1 = 0x4f84136c4a2e9b52; - int ee[] = { 0, 1, 10000 }; - int e, i; - for (e = 0; e < sizeof(ee) / sizeof(*ee); e++) { - int exp = ee[e]; - fsub(make(0, exp, a1, a0), make(0, 0, 0, 0)); - for (i = 63; i >= 0; i--) - fsub(make(0, exp, a1 | (uint64_t)1 << i >> 1, a0), - make(0, exp, a1 >> i << i, 0)); - for (i = 63; i >=0; i--) - fsub(make(0, exp, a1, a0 | (uint64_t)1 << i >> 1), - make(0, exp, a1, a0 >> i << i)); - } - } - - // Carry/overflow from rounding: - { - fadd(make(0, 114, -1, -1), make(0, 1, 0, 0)); - fadd(make(0, 32766, -1, -1), make(0, 32653, 0, 0)); - fsub(make(1, 32766, -1, -1), make(0, 32653, 0, 0)); - } -} - -void muls(void) -{ - int i, j; - - { - long double max = make(0, 32766, -1, -1); - long double min = make(0, 0, 0, 1); - fmul(max, max); - fmul(max, min); - fmul(min, min); - } - - for (i = 117; i > 0; i--) - fmul(make(0, 16268, 0x643dcea76edc, 0xe0877a598403627a), - make(i & 1, i, 0, 0)); - - fmul(make(0, 16383, -1, -3), make(0, 16383, 0, 1)); - // Round to next exponent: - fmul(make(0, 16383, -1, -2), make(0, 16383, 0, 1)); - // Round from subnormal to normal: - fmul(make(0, 1, -1, -1), make(0, 16382, 0, 0)); - - for (i = 0; i < 2; i++) - for (j = 0; j < 112; j++) - fmul(make(0, 16383, (uint64_t)1 << i, 0), - make(0, 16383, - j < 64 ? 0 : (uint64_t)1 << (j - 64), - j < 64 ? (uint64_t)1 << j : 0)); -} - -void divs(void) -{ - int i; - - { - long double max = make(0, 32766, -1, -1); - long double min = make(0, 0, 0, 1); - fdiv(max, max); - fdiv(max, min); - fdiv(min, max); - fdiv(min, min); - } - - for (i = 0; i < 64; i++) - fdiv(make(0, 16383, -1, -1), make(0, 16383, -1, -(uint64_t)1 << i)); - for (i = 0; i < 48; i++) - fdiv(make(0, 16383, -1, -1), make(0, 16383, -(uint64_t)1 << i, 0)); -} - -void cvtlsw(int32_t a) -{ - long double f = a; - u128_t x = copy_ild(f); - printf("cvtlsw %08lx %016llx%016llx\n", (long)(uint32_t)a, x.x1, x.x0); -} - -void cvtlsx(int64_t a) -{ - long double f = a; - u128_t x = copy_ild(f); - printf("cvtlsx %016llx %016llx%016llx\n", - (long long)(uint64_t)a, x.x1, x.x0); -} - -void cvtluw(uint32_t a) -{ - long double f = a; - u128_t x = copy_ild(f); - printf("cvtluw %08lx %016llx%016llx\n", (long)a, x.x1, x.x0); -} - -void cvtlux(uint64_t a) -{ - long double f = a; - u128_t x = copy_ild(f); - printf("cvtlux %016llx %016llx%016llx\n", (long long)a, x.x1, x.x0); -} - -void cvtil(long double a) -{ - u128_t x = copy_ild(a); - int32_t b1 = a; - int64_t b2 = a; - uint32_t b3 = a; - uint64_t b4 = a; - printf("cvtswl %016llx%016llx %08lx\n", - x.x1, x.x0, (long)(uint32_t)b1); - printf("cvtsxl %016llx%016llx %016llx\n", - x.x1, x.x0, (long long)(uint64_t)b2); - printf("cvtuwl %016llx%016llx %08lx\n", - x.x1, x.x0, (long)b3); - printf("cvtuxl %016llx%016llx %016llx\n", - x.x1, x.x0, (long long)b4); -} - -void cvtlf(float a) -{ - uint32_t ax = copy_if(a); - long double b = a; - u128_t bx = copy_ild(b); - printf("cvtlf %08lx %016llx%016llx\n", (long)ax, bx.x1, bx.x0); -} - -void cvtld(double a) -{ - uint64_t ax = copy_id(a); - long double b = a; - u128_t bx = copy_ild(b); - printf("cvtld %016llx %016llx%016llx\n", (long long)ax, bx.x1, bx.x0); -} - -void cvtfl(long double a) -{ - u128_t ax = copy_ild(a); - float b = a; - uint32_t bx = copy_if(b); - printf("cvtfl %016llx%016llx %08lx\n", ax.x1, ax.x0, (long)bx); -} - -void cvtdl(long double a) -{ - u128_t ax = copy_ild(a); - double b = a; - uint64_t bx = copy_id(b); - printf("cvtdl %016llx%016llx %016llx\n", ax.x1, ax.x0, (long long)bx); -} - -void cvts(void) -{ - int i, j; - - { - uint32_t x = 0xad040c5b; - cvtlsw(0); - for (i = 0; i < 31; i++) - cvtlsw(x >> (31 - i)); - for (i = 0; i < 31; i++) - cvtlsw(-(x >> (31 - i))); - cvtlsw(0x80000000); - } - { - uint64_t x = 0xb630a248cad9afd2; - cvtlsx(0); - for (i = 0; i < 63; i++) - cvtlsx(x >> (63 - i)); - for (i = 0; i < 63; i++) - cvtlsx(-(x >> (63 - i))); - cvtlsx(0x8000000000000000); - } - { - uint32_t x = 0xad040c5b; - cvtluw(0); - for (i = 0; i < 32; i++) - cvtluw(x >> (31 - i)); - } - { - uint64_t x = 0xb630a248cad9afd2; - cvtlux(0); - for (i = 0; i < 64; i++) - cvtlux(x >> (63 - i)); - } - - for (i = 0; i < 2; i++) { - cvtil(make(i, 32767, 0, 1)); - cvtil(make(i, 32767, (uint64_t)1 << 47, 0)); - cvtil(make(i, 32767, 123, 456)); - cvtil(make(i, 32767, 0, 0)); - cvtil(make(i, 16382, -1, -1)); - cvtil(make(i, 16383, -1, -1)); - cvtil(make(i, 16384, 0x7fffffffffff, -1)); - cvtil(make(i, 16384, 0x800000000000, 0)); - for (j = 0; j < 68; j++) - cvtil(make(i, 16381 + j, 0xd4822c0a10ec, 0x1fe2f8b2669f5c9d)); - } - - cvtlf(copy_fi(0x00000000)); - cvtlf(copy_fi(0x456789ab)); - cvtlf(copy_fi(0x7f800000)); - cvtlf(copy_fi(0x7f923456)); - cvtlf(copy_fi(0x7fdbcdef)); - cvtlf(copy_fi(0x80000000)); - cvtlf(copy_fi(0xabcdef12)); - cvtlf(copy_fi(0xff800000)); - cvtlf(copy_fi(0xff923456)); - cvtlf(copy_fi(0xffdbcdef)); - - cvtld(copy_di(0x0000000000000000)); - cvtld(copy_di(0x456789abcdef0123)); - cvtld(copy_di(0x7ff0000000000000)); - cvtld(copy_di(0x7ff123456789abcd)); - cvtld(copy_di(0x7ffabcdef1234567)); - cvtld(copy_di(0x8000000000000000)); - cvtld(copy_di(0xcdef123456789abc)); - cvtld(copy_di(0xfff0000000000000)); - cvtld(copy_di(0xfff123456789abcd)); - cvtld(copy_di(0xfffabcdef1234567)); - - for (i = 0; i < 2; i++) { \ - cvtfl(make(i, 0, 0, 0)); - cvtfl(make(i, 16232, -1, -1)); - cvtfl(make(i, 16233, 0, 0)); - cvtfl(make(i, 16233, 0, 1)); - cvtfl(make(i, 16383, 0xab0ffd000000, 0)); - cvtfl(make(i, 16383, 0xab0ffd000001, 0)); - cvtfl(make(i, 16383, 0xab0ffeffffff, 0)); - cvtfl(make(i, 16383, 0xab0fff000000, 0)); - cvtfl(make(i, 16383, 0xab0fff000001, 0)); - cvtfl(make(i, 16510, 0xfffffeffffff, -1)); - cvtfl(make(i, 16510, 0xffffff000000, 0)); - cvtfl(make(i, 16511, 0, 0)); - cvtfl(make(i, 32767, 0, 0)); - cvtfl(make(i, 32767, 0, 1)); - cvtfl(make(i, 32767, 0x4cbe01ac5f40, 0x75cee3c6afbb00b5)); - cvtfl(make(i, 32767, 0x800000000000, 1)); - cvtfl(make(i, 32767, 0xa11caaaf6a52, 0x696033e871eab099)); - } - - for (i = 0; i < 2; i++) { - cvtdl(make(i, 0, 0, 0)); - cvtdl(make(i, 15307, -1, -1)); - cvtdl(make(i, 15308, 0, 0)); - cvtdl(make(i, 15308, 0, 1)); - cvtdl(make(i, 16383, 0xabc123abc0ff, 0xe800000000000000)); - cvtdl(make(i, 16383, 0xabc123abc0ff, 0xe800000000000001)); - cvtdl(make(i, 16383, 0xabc123abc0ff, 0xf7ffffffffffffff)); - cvtdl(make(i, 16383, 0xabc123abc0ff, 0xf800000000000000)); - cvtdl(make(i, 16383, 0xabc123abc0ff, 0xf800000000000001)); - cvtdl(make(i, 17406, 0xffffffffffff, 0xf7ffffffffffffff)); - cvtdl(make(i, 17406, 0xffffffffffff, 0xf800000000000000)); - cvtdl(make(i, 17407, 0, 0)); - cvtdl(make(i, 32767, 0, 0)); - cvtdl(make(i, 32767, 0, 1)); - cvtdl(make(i, 32767, 0x4cbe01ac5f40, 0x75cee3c6afbb00b5)); - cvtdl(make(i, 32767, 0x800000000000, 1)); - cvtdl(make(i, 32767, 0xa11caaaf6a52, 0x696033e871eab099)); - } -} - -void tests(void) -{ - cmps(); - nanz(); - adds(); - muls(); - divs(); - cvts(); -} - -int main() -{ -#ifdef __aarch64__ - tests(); -#else - printf("This test program is intended for a little-endian architecture\n" - "with an IEEE-standard 128-bit long double.\n"); -#endif - return 0; -} diff --git a/external/TCC/libtcc.c b/external/TCC/libtcc.c deleted file mode 100644 index f51774fb..00000000 --- a/external/TCC/libtcc.c +++ /dev/null @@ -1,2327 +0,0 @@ -/* - * TCC - Tiny C Compiler - * - * Copyright (c) 2001-2004 Fabrice Bellard - * - * 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "tcc.h" - -/********************************************************/ -/* global variables */ - -/* use GNU C extensions */ -ST_DATA int gnu_ext = 1; - -/* use TinyCC extensions */ -ST_DATA int tcc_ext = 1; - -/* XXX: get rid of this ASAP */ -ST_DATA struct TCCState *tcc_state; - -/********************************************************/ - -#ifdef ONE_SOURCE -#include "tccpp.c" -#include "tccgen.c" -#include "tccelf.c" -#include "tccrun.c" -#ifdef TCC_TARGET_I386 -#include "i386-gen.c" -#endif -#ifdef TCC_TARGET_ARM -#include "arm-gen.c" -#endif -#ifdef TCC_TARGET_ARM64 -#include "arm64-gen.c" -#endif -#ifdef TCC_TARGET_C67 -#include "c67-gen.c" -#endif -#ifdef TCC_TARGET_X86_64 -#include "x86_64-gen.c" -#endif -#ifdef CONFIG_TCC_ASM -#include "tccasm.c" -#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 -#include "i386-asm.c" -#endif -#endif -#ifdef TCC_TARGET_COFF -#include "tcccoff.c" -#endif -#ifdef TCC_TARGET_PE -#include "tccpe.c" -#endif -#endif /* ONE_SOURCE */ - -/********************************************************/ -#ifndef CONFIG_TCC_ASM -ST_FUNC void asm_instr(void) -{ - tcc_error("inline asm() not supported"); -} -ST_FUNC void asm_global_instr(void) -{ - tcc_error("inline asm() not supported"); -} -#endif - -/********************************************************/ -#ifdef _WIN32 -static char *normalize_slashes(char *path) -{ - char *p; - for (p = path; *p; ++p) - if (*p == '\\') - *p = '/'; - return path; -} - -static HMODULE tcc_module; - -/* on win32, we suppose the lib and includes are at the location of 'tcc.exe' */ -static void tcc_set_lib_path_w32(TCCState *s) -{ - char path[1024], *p; - GetModuleFileNameA(tcc_module, path, sizeof path); - p = tcc_basename(normalize_slashes(strlwr(path))); - if (p - 5 > path && 0 == strncmp(p - 5, "/bin/", 5)) - p -= 5; - else if (p > path) - p--; - *p = 0; - tcc_set_lib_path(s, path); -} - -#ifdef TCC_TARGET_PE -static void tcc_add_systemdir(TCCState *s) -{ - char buf[1000]; - GetSystemDirectory(buf, sizeof buf); - tcc_add_library_path(s, normalize_slashes(buf)); -} -#endif - -#ifndef CONFIG_TCC_STATIC -void dlclose(void *p) -{ - FreeLibrary((HMODULE)p); -} -#endif - -#ifdef LIBTCC_AS_DLL -BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved) -{ - if (DLL_PROCESS_ATTACH == dwReason) - tcc_module = hDll; - return TRUE; -} -#endif -#endif - -/********************************************************/ -/* copy a string and truncate it. */ -PUB_FUNC char *pstrcpy(char *buf, int buf_size, const char *s) -{ - char *q, *q_end; - int c; - - if (buf_size > 0) { - q = buf; - q_end = buf + buf_size - 1; - while (q < q_end) { - c = *s++; - if (c == '\0') - break; - *q++ = c; - } - *q = '\0'; - } - return buf; -} - -/* strcat and truncate. */ -PUB_FUNC char *pstrcat(char *buf, int buf_size, const char *s) -{ - int len; - len = strlen(buf); - if (len < buf_size) - pstrcpy(buf + len, buf_size - len, s); - return buf; -} - -PUB_FUNC char *pstrncpy(char *out, const char *in, size_t num) -{ - memcpy(out, in, num); - out[num] = '\0'; - return out; -} - -/* extract the basename of a file */ -PUB_FUNC char *tcc_basename(const char *name) -{ - char *p = strchr(name, 0); - while (p > name && !IS_DIRSEP(p[-1])) - --p; - return p; -} - -/* extract extension part of a file - * - * (if no extension, return pointer to end-of-string) - */ -PUB_FUNC char *tcc_fileextension (const char *name) -{ - char *b = tcc_basename(name); - char *e = strrchr(b, '.'); - return e ? e : strchr(b, 0); -} - -/********************************************************/ -/* memory management */ - -#undef free -#undef malloc -#undef realloc - -#ifndef MEM_DEBUG - -PUB_FUNC void tcc_free(void *ptr) -{ - free(ptr); -} - -PUB_FUNC void *tcc_malloc(unsigned long size) -{ - void *ptr; - ptr = malloc(size); - if (!ptr && size) - tcc_error("memory full (malloc)"); - return ptr; -} - -PUB_FUNC void *tcc_mallocz(unsigned long size) -{ - void *ptr; - ptr = tcc_malloc(size); - memset(ptr, 0, size); - return ptr; -} - -PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size) -{ - void *ptr1; - ptr1 = realloc(ptr, size); - if (!ptr1 && size) - tcc_error("memory full (realloc)"); - return ptr1; -} - -PUB_FUNC char *tcc_strdup(const char *str) -{ - char *ptr; - ptr = tcc_malloc(strlen(str) + 1); - strcpy(ptr, str); - return ptr; -} - -PUB_FUNC void tcc_memstats(int bench) -{ -} - -#else - -#define MEM_DEBUG_MAGIC1 0xFEEDDEB1 -#define MEM_DEBUG_MAGIC2 0xFEEDDEB2 -#define MEM_DEBUG_FILE_LEN 15 - -struct mem_debug_header { - size_t magic1; - size_t size; - struct mem_debug_header *prev; - struct mem_debug_header *next; - size_t line_num; - char file_name[MEM_DEBUG_FILE_LEN + 1]; - size_t magic2; -}; - -typedef struct mem_debug_header mem_debug_header_t; - -static mem_debug_header_t *mem_debug_chain; -static size_t mem_cur_size; -static size_t mem_max_size; - -PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line) -{ - void *ptr; - mem_debug_header_t *header; - - ptr = malloc(sizeof(mem_debug_header_t) + size); - if (!ptr) - tcc_error("memory full (malloc)"); - - mem_cur_size += size; - if (mem_cur_size > mem_max_size) - mem_max_size = mem_cur_size; - - header = (mem_debug_header_t *)ptr; - - header->magic1 = MEM_DEBUG_MAGIC1; - header->magic2 = MEM_DEBUG_MAGIC2; - header->size = size; - header->line_num = line; - - strncpy(header->file_name, file, MEM_DEBUG_FILE_LEN); - header->file_name[MEM_DEBUG_FILE_LEN] = 0; - - header->next = mem_debug_chain; - header->prev = NULL; - - if (header->next) - header->next->prev = header; - - mem_debug_chain = header; - - ptr = (char *)ptr + sizeof(mem_debug_header_t); - return ptr; -} - -PUB_FUNC void tcc_free_debug(void *ptr) -{ - mem_debug_header_t *header; - - if (!ptr) - return; - - ptr = (char *)ptr - sizeof(mem_debug_header_t); - header = (mem_debug_header_t *)ptr; - if (header->magic1 != MEM_DEBUG_MAGIC1 || - header->magic2 != MEM_DEBUG_MAGIC2 || - header->size == (size_t)-1 ) - { - tcc_error("tcc_free check failed"); - } - - mem_cur_size -= header->size; - header->size = (size_t)-1; - - if (header->next) - header->next->prev = header->prev; - - if (header->prev) - header->prev->next = header->next; - - if (header == mem_debug_chain) - mem_debug_chain = header->next; - - free(ptr); -} - - -PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line) -{ - void *ptr; - ptr = tcc_malloc_debug(size,file,line); - memset(ptr, 0, size); - return ptr; -} - -PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line) -{ - mem_debug_header_t *header; - int mem_debug_chain_update = 0; - - if (!ptr) { - ptr = tcc_malloc_debug(size, file, line); - return ptr; - } - - ptr = (char *)ptr - sizeof(mem_debug_header_t); - header = (mem_debug_header_t *)ptr; - if (header->magic1 != MEM_DEBUG_MAGIC1 || - header->magic2 != MEM_DEBUG_MAGIC2 || - header->size == (size_t)-1 ) - { - check_error: - tcc_error("tcc_realloc check failed"); - } - - mem_debug_chain_update = (header == mem_debug_chain); - - mem_cur_size -= header->size; - ptr = realloc(ptr, sizeof(mem_debug_header_t) + size); - if (!ptr) - tcc_error("memory full (realloc)"); - - header = (mem_debug_header_t *)ptr; - if (header->magic1 != MEM_DEBUG_MAGIC1 || - header->magic2 != MEM_DEBUG_MAGIC2) - { - goto check_error; - } - - mem_cur_size += size; - if (mem_cur_size > mem_max_size) - mem_max_size = mem_cur_size; - - header->size = size; - if (header->next) - header->next->prev = header; - - if (header->prev) - header->prev->next = header; - - if (mem_debug_chain_update) - mem_debug_chain = header; - - ptr = (char *)ptr + sizeof(mem_debug_header_t); - return ptr; -} - -PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line) -{ - char *ptr; - ptr = tcc_malloc_debug(strlen(str) + 1, file, line); - strcpy(ptr, str); - return ptr; -} - -PUB_FUNC void tcc_memstats(int bench) -{ - if (mem_cur_size) { - mem_debug_header_t *header = mem_debug_chain; - - fprintf(stderr, "MEM_DEBUG: mem_leak= %d bytes, mem_max_size= %d bytes\n", - mem_cur_size, mem_max_size); - - while (header) { - fprintf(stderr, " file %s, line %u: %u bytes\n", - header->file_name, header->line_num, header->size); - header = header->next; - } - } - else if (bench) - fprintf(stderr, "mem_max_size= %d bytes\n", mem_max_size); -} - -#undef MEM_DEBUG_MAGIC1 -#undef MEM_DEBUG_MAGIC2 -#undef MEM_DEBUG_FILE_LEN - -#endif - -#define free(p) use_tcc_free(p) -#define malloc(s) use_tcc_malloc(s) -#define realloc(p, s) use_tcc_realloc(p, s) - -/********************************************************/ -/* dynarrays */ - -ST_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data) -{ - int nb, nb_alloc; - void **pp; - - nb = *nb_ptr; - pp = *ptab; - /* every power of two we double array size */ - if ((nb & (nb - 1)) == 0) { - if (!nb) - nb_alloc = 1; - else - nb_alloc = nb * 2; - pp = tcc_realloc(pp, nb_alloc * sizeof(void *)); - *ptab = pp; - } - pp[nb++] = data; - *nb_ptr = nb; -} - -ST_FUNC void dynarray_reset(void *pp, int *n) -{ - void **p; - for (p = *(void***)pp; *n; ++p, --*n) - if (*p) - tcc_free(*p); - tcc_free(*(void**)pp); - *(void**)pp = NULL; -} - -static void tcc_split_path(TCCState *s, void ***p_ary, int *p_nb_ary, const char *in) -{ - const char *p; - do { - int c; - CString str; - - cstr_new(&str); - for (p = in; c = *p, c != '\0' && c != PATHSEP; ++p) { - if (c == '{' && p[1] && p[2] == '}') { - c = p[1], p += 2; - if (c == 'B') - cstr_cat(&str, s->tcc_lib_path); - } else { - cstr_ccat(&str, c); - } - } - cstr_ccat(&str, '\0'); - dynarray_add(p_ary, p_nb_ary, str.data); - in = p+1; - } while (*p); -} - -/********************************************************/ - -ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags) -{ - Section *sec; - - sec = tcc_mallocz(sizeof(Section) + strlen(name)); - strcpy(sec->name, name); - sec->sh_type = sh_type; - sec->sh_flags = sh_flags; - switch(sh_type) { - case SHT_HASH: - case SHT_REL: - case SHT_RELA: - case SHT_DYNSYM: - case SHT_SYMTAB: - case SHT_DYNAMIC: - sec->sh_addralign = 4; - break; - case SHT_STRTAB: - sec->sh_addralign = 1; - break; - default: - sec->sh_addralign = 32; /* default conservative alignment */ - break; - } - - if (sh_flags & SHF_PRIVATE) { - dynarray_add((void ***)&s1->priv_sections, &s1->nb_priv_sections, sec); - } else { - sec->sh_num = s1->nb_sections; - dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec); - } - - return sec; -} - -static void free_section(Section *s) -{ - tcc_free(s->data); -} - -/* realloc section and set its content to zero */ -ST_FUNC void section_realloc(Section *sec, unsigned long new_size) -{ - unsigned long size; - unsigned char *data; - - size = sec->data_allocated; - if (size == 0) - size = 1; - while (size < new_size) - size = size * 2; - data = tcc_realloc(sec->data, size); - memset(data + sec->data_allocated, 0, size - sec->data_allocated); - sec->data = data; - sec->data_allocated = size; -} - -/* reserve at least 'size' bytes in section 'sec' from - sec->data_offset. */ -ST_FUNC void *section_ptr_add(Section *sec, addr_t size) -{ - size_t offset, offset1; - - offset = sec->data_offset; - offset1 = offset + size; - if (offset1 > sec->data_allocated) - section_realloc(sec, offset1); - sec->data_offset = offset1; - return sec->data + offset; -} - -/* reserve at least 'size' bytes from section start */ -ST_FUNC void section_reserve(Section *sec, unsigned long size) -{ - if (size > sec->data_allocated) - section_realloc(sec, size); - if (size > sec->data_offset) - sec->data_offset = size; -} - -/* return a reference to a section, and create it if it does not - exists */ -ST_FUNC Section *find_section(TCCState *s1, const char *name) -{ - Section *sec; - int i; - for(i = 1; i < s1->nb_sections; i++) { - sec = s1->sections[i]; - if (!strcmp(name, sec->name)) - return sec; - } - /* sections are created as PROGBITS */ - return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC); -} - -/* update sym->c so that it points to an external symbol in section - 'section' with value 'value' */ -ST_FUNC void put_extern_sym2(Sym *sym, Section *section, - addr_t value, unsigned long size, - int can_add_underscore) -{ - int sym_type, sym_bind, sh_num, info, other; - ElfW(Sym) *esym; - const char *name; - char buf1[256]; - -#ifdef CONFIG_TCC_BCHECK - char buf[32]; -#endif - - if (section == NULL) - sh_num = SHN_UNDEF; - else if (section == SECTION_ABS) - sh_num = SHN_ABS; - else - sh_num = section->sh_num; - - if ((sym->type.t & VT_BTYPE) == VT_FUNC) { - sym_type = STT_FUNC; - } else if ((sym->type.t & VT_BTYPE) == VT_VOID) { - sym_type = STT_NOTYPE; - } else { - sym_type = STT_OBJECT; - } - - if (sym->type.t & VT_STATIC) - sym_bind = STB_LOCAL; - else { - if (sym->type.t & VT_WEAK) - sym_bind = STB_WEAK; - else - sym_bind = STB_GLOBAL; - } - - if (!sym->c) { - name = get_tok_str(sym->v, NULL); -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check) { - /* XXX: avoid doing that for statics ? */ - /* if bound checking is activated, we change some function - names by adding the "__bound" prefix */ - switch(sym->v) { -#ifdef TCC_TARGET_PE - /* XXX: we rely only on malloc hooks */ - case TOK_malloc: - case TOK_free: - case TOK_realloc: - case TOK_memalign: - case TOK_calloc: -#endif - case TOK_memcpy: - case TOK_memmove: - case TOK_memset: - case TOK_strlen: - case TOK_strcpy: - case TOK_alloca: - strcpy(buf, "__bound_"); - strcat(buf, name); - name = buf; - break; - } - } -#endif - other = 0; - -#ifdef TCC_TARGET_PE - if (sym->type.t & VT_EXPORT) - other |= ST_PE_EXPORT; - if (sym_type == STT_FUNC && sym->type.ref) { - Sym *ref = sym->type.ref; - if (ref->a.func_export) - other |= ST_PE_EXPORT; - if (ref->a.func_call == FUNC_STDCALL && can_add_underscore) { - sprintf(buf1, "_%s@%d", name, ref->a.func_args * PTR_SIZE); - name = buf1; - other |= ST_PE_STDCALL; - can_add_underscore = 0; - } - } else { - if (find_elf_sym(tcc_state->dynsymtab_section, name)) - other |= ST_PE_IMPORT; - if (sym->type.t & VT_IMPORT) - other |= ST_PE_IMPORT; - } -#else - if (! (sym->type.t & VT_STATIC)) - other = (sym->type.t & VT_VIS_MASK) >> VT_VIS_SHIFT; -#endif - if (tcc_state->leading_underscore && can_add_underscore) { - buf1[0] = '_'; - pstrcpy(buf1 + 1, sizeof(buf1) - 1, name); - name = buf1; - } - if (sym->asm_label) { - name = get_tok_str(sym->asm_label, NULL); - } - info = ELFW(ST_INFO)(sym_bind, sym_type); - sym->c = add_elf_sym(symtab_section, value, size, info, other, sh_num, name); - } else { - esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; - esym->st_value = value; - esym->st_size = size; - esym->st_shndx = sh_num; - } -} - -ST_FUNC void put_extern_sym(Sym *sym, Section *section, - addr_t value, unsigned long size) -{ - put_extern_sym2(sym, section, value, size, 1); -} - -/* add a new relocation entry to symbol 'sym' in section 's' */ -ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, - addr_t addend) -{ - int c = 0; - if (sym) { - if (0 == sym->c) - put_extern_sym(sym, NULL, 0, 0); - c = sym->c; - } - /* now we can add ELF relocation info */ - put_elf_reloca(symtab_section, s, offset, type, c, addend); -} - -ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type) -{ - greloca(s, sym, offset, type, 0); -} - -/********************************************************/ - -static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap) -{ - int len; - len = strlen(buf); - vsnprintf(buf + len, buf_size - len, fmt, ap); -} - -static void strcat_printf(char *buf, int buf_size, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - strcat_vprintf(buf, buf_size, fmt, ap); - va_end(ap); -} - -static void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap) -{ - char buf[2048]; - BufferedFile **pf, *f; - - buf[0] = '\0'; - /* use upper file if inline ":asm:" or token ":paste:" */ - for (f = file; f && f->filename[0] == ':'; f = f->prev) - ; - if (f) { - for(pf = s1->include_stack; pf < s1->include_stack_ptr; pf++) - strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n", - (*pf)->filename, (*pf)->line_num); - if (f->line_num > 0) { - strcat_printf(buf, sizeof(buf), "%s:%d: ", - f->filename, f->line_num); - } else { - strcat_printf(buf, sizeof(buf), "%s: ", - f->filename); - } - } else { - strcat_printf(buf, sizeof(buf), "tcc: "); - } - if (is_warning) - strcat_printf(buf, sizeof(buf), "warning: "); - else - strcat_printf(buf, sizeof(buf), "error: "); - strcat_vprintf(buf, sizeof(buf), fmt, ap); - - if (!s1->error_func) { - /* default case: stderr */ - if (s1->ppfp) /* print a newline during tcc -E */ - fprintf(s1->ppfp, "\n"), fflush(s1->ppfp); - fprintf(stderr, "%s\n", buf); - fflush(stderr); /* print error/warning now (win32) */ - } else { - s1->error_func(s1->error_opaque, buf); - } - if (!is_warning || s1->warn_error) - s1->nb_errors++; -} - -LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, - void (*error_func)(void *opaque, const char *msg)) -{ - s->error_opaque = error_opaque; - s->error_func = error_func; -} - -/* error without aborting current compilation */ -PUB_FUNC void tcc_error_noabort(const char *fmt, ...) -{ - TCCState *s1 = tcc_state; - va_list ap; - - va_start(ap, fmt); - error1(s1, 0, fmt, ap); - va_end(ap); -} - -PUB_FUNC void tcc_error(const char *fmt, ...) -{ - TCCState *s1 = tcc_state; - va_list ap; - - va_start(ap, fmt); - error1(s1, 0, fmt, ap); - va_end(ap); - /* better than nothing: in some cases, we accept to handle errors */ - if (s1->error_set_jmp_enabled) { - longjmp(s1->error_jmp_buf, 1); - } else { - /* XXX: eliminate this someday */ - exit(1); - } -} - -PUB_FUNC void tcc_warning(const char *fmt, ...) -{ - TCCState *s1 = tcc_state; - va_list ap; - - if (s1->warn_none) - return; - - va_start(ap, fmt); - error1(s1, 1, fmt, ap); - va_end(ap); -} - -/********************************************************/ -/* I/O layer */ - -ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen) -{ - BufferedFile *bf; - int buflen = initlen ? initlen : IO_BUF_SIZE; - - bf = tcc_mallocz(sizeof(BufferedFile) + buflen); - bf->buf_ptr = bf->buffer; - bf->buf_end = bf->buffer + initlen; - bf->buf_end[0] = CH_EOB; /* put eob symbol */ - pstrcpy(bf->filename, sizeof(bf->filename), filename); -#ifdef _WIN32 - normalize_slashes(bf->filename); -#endif - bf->line_num = 1; - bf->ifdef_stack_ptr = s1->ifdef_stack_ptr; - bf->fd = -1; - bf->prev = file; - file = bf; -} - -ST_FUNC void tcc_close(void) -{ - BufferedFile *bf = file; - if (bf->fd > 0) { - close(bf->fd); - total_lines += bf->line_num; - } - file = bf->prev; - tcc_free(bf); -} - -ST_FUNC int tcc_open(TCCState *s1, const char *filename) -{ - int fd; - if (strcmp(filename, "-") == 0) - fd = 0, filename = ""; - else - fd = open(filename, O_RDONLY | O_BINARY); - if ((s1->verbose == 2 && fd >= 0) || s1->verbose == 3) - printf("%s %*s%s\n", fd < 0 ? "nf":"->", - (int)(s1->include_stack_ptr - s1->include_stack), "", filename); - if (fd < 0) - return -1; - - tcc_open_bf(s1, filename, 0); - file->fd = fd; - return fd; -} - -/* compile the C file opened in 'file'. Return non zero if errors. */ -static int tcc_compile(TCCState *s1) -{ - Sym *define_start; - char buf[512]; - volatile int section_sym; - -#ifdef INC_DEBUG - printf("%s: **** new file\n", file->filename); -#endif - preprocess_init(s1); - - cur_text_section = NULL; - funcname = ""; - anon_sym = SYM_FIRST_ANOM; - - /* file info: full path + filename */ - section_sym = 0; /* avoid warning */ - if (s1->do_debug) { - section_sym = put_elf_sym(symtab_section, 0, 0, - ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0, - text_section->sh_num, NULL); - getcwd(buf, sizeof(buf)); -#ifdef _WIN32 - normalize_slashes(buf); -#endif - pstrcat(buf, sizeof(buf), "/"); - put_stabs_r(buf, N_SO, 0, 0, - text_section->data_offset, text_section, section_sym); - put_stabs_r(file->filename, N_SO, 0, 0, - text_section->data_offset, text_section, section_sym); - } - /* an elf symbol of type STT_FILE must be put so that STB_LOCAL - symbols can be safely used */ - put_elf_sym(symtab_section, 0, 0, - ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0, - SHN_ABS, file->filename); - - /* define some often used types */ - int_type.t = VT_INT; - - char_pointer_type.t = VT_BYTE; - mk_pointer(&char_pointer_type); - -#if PTR_SIZE == 4 - size_type.t = VT_INT; -#else - size_type.t = VT_LLONG; -#endif - - func_old_type.t = VT_FUNC; - func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD); -#ifdef TCC_TARGET_ARM - arm_init(s1); -#endif - -#if 0 - /* define 'void *alloca(unsigned int)' builtin function */ - { - Sym *s1; - - p = anon_sym++; - sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW); - s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0); - s1->next = NULL; - sym->next = s1; - sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0); - } -#endif - - define_start = define_stack; - nocode_wanted = 1; - - if (setjmp(s1->error_jmp_buf) == 0) { - s1->nb_errors = 0; - s1->error_set_jmp_enabled = 1; - - ch = file->buf_ptr[0]; - tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; - parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR; - next(); - decl(VT_CONST); - if (tok != TOK_EOF) - expect("declaration"); - check_vstack(); - - /* end of translation unit info */ - if (s1->do_debug) { - put_stabs_r(NULL, N_SO, 0, 0, - text_section->data_offset, text_section, section_sym); - } - } - - s1->error_set_jmp_enabled = 0; - - /* reset define stack, but leave -Dsymbols (may be incorrect if - they are undefined) */ - free_defines(define_start); - - gen_inline_functions(); - - sym_pop(&global_stack, NULL); - sym_pop(&local_stack, NULL); - - return s1->nb_errors != 0 ? -1 : 0; -} - -LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str) -{ - int len, ret; - - len = strlen(str); - tcc_open_bf(s, "", len); - memcpy(file->buffer, str, len); - ret = tcc_compile(s); - tcc_close(); - return ret; -} - -/* define a preprocessor symbol. A value can also be provided with the '=' operator */ -LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *value) -{ - int len1, len2; - /* default value */ - if (!value) - value = "1"; - len1 = strlen(sym); - len2 = strlen(value); - - /* init file structure */ - tcc_open_bf(s1, "", len1 + len2 + 1); - memcpy(file->buffer, sym, len1); - file->buffer[len1] = ' '; - memcpy(file->buffer + len1 + 1, value, len2); - - /* parse with define parser */ - ch = file->buf_ptr[0]; - next_nomacro(); - parse_define(); - - tcc_close(); -} - -/* undefine a preprocessor symbol */ -LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym) -{ - TokenSym *ts; - Sym *s; - ts = tok_alloc(sym, strlen(sym)); - s = define_find(ts->tok); - /* undefine symbol by putting an invalid name */ - if (s) - define_undef(s); -} - -/* cleanup all static data used during compilation */ -static void tcc_cleanup(void) -{ - if (NULL == tcc_state) - return; - tcc_state = NULL; - - preprocess_delete(); - - /* free sym_pools */ - dynarray_reset(&sym_pools, &nb_sym_pools); - /* string buffer */ - cstr_free(&tokcstr); - /* reset symbol stack */ - sym_free_first = NULL; -} - -LIBTCCAPI TCCState *tcc_new(void) -{ - TCCState *s; - char buffer[100]; - int a,b,c; - - tcc_cleanup(); - - s = tcc_mallocz(sizeof(TCCState)); - if (!s) - return NULL; - tcc_state = s; -#ifdef _WIN32 - tcc_set_lib_path_w32(s); -#else - tcc_set_lib_path(s, CONFIG_TCCDIR); -#endif - s->output_type = 0; - preprocess_new(); - s->include_stack_ptr = s->include_stack; - - /* we add dummy defines for some special macros to speed up tests - and to have working defined() */ - define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL); - define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL); - define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL); - define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL); - - /* define __TINYC__ 92X */ - sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c); - sprintf(buffer, "%d", a*10000 + b*100 + c); - tcc_define_symbol(s, "__TINYC__", buffer); - - /* standard defines */ - tcc_define_symbol(s, "__STDC__", NULL); - tcc_define_symbol(s, "__STDC_VERSION__", "199901L"); - tcc_define_symbol(s, "__STDC_HOSTED__", NULL); - - /* target defines */ -#if defined(TCC_TARGET_I386) - tcc_define_symbol(s, "__i386__", NULL); - tcc_define_symbol(s, "__i386", NULL); - tcc_define_symbol(s, "i386", NULL); -#elif defined(TCC_TARGET_X86_64) - tcc_define_symbol(s, "__x86_64__", NULL); -#elif defined(TCC_TARGET_ARM) - tcc_define_symbol(s, "__ARM_ARCH_4__", NULL); - tcc_define_symbol(s, "__arm_elf__", NULL); - tcc_define_symbol(s, "__arm_elf", NULL); - tcc_define_symbol(s, "arm_elf", NULL); - tcc_define_symbol(s, "__arm__", NULL); - tcc_define_symbol(s, "__arm", NULL); - tcc_define_symbol(s, "arm", NULL); - tcc_define_symbol(s, "__APCS_32__", NULL); - tcc_define_symbol(s, "__ARMEL__", NULL); -#if defined(TCC_ARM_EABI) - tcc_define_symbol(s, "__ARM_EABI__", NULL); -#endif -#if defined(TCC_ARM_HARDFLOAT) - s->float_abi = ARM_HARD_FLOAT; - tcc_define_symbol(s, "__ARM_PCS_VFP", NULL); -#else - s->float_abi = ARM_SOFTFP_FLOAT; -#endif -#elif defined(TCC_TARGET_ARM64) - tcc_define_symbol(s, "__aarch64__", NULL); -#endif - -#ifdef TCC_TARGET_PE - tcc_define_symbol(s, "_WIN32", NULL); -# ifdef TCC_TARGET_X86_64 - tcc_define_symbol(s, "_WIN64", NULL); -# endif -#else - tcc_define_symbol(s, "__unix__", NULL); - tcc_define_symbol(s, "__unix", NULL); - tcc_define_symbol(s, "unix", NULL); -# if defined(__linux) - tcc_define_symbol(s, "__linux__", NULL); - tcc_define_symbol(s, "__linux", NULL); -# endif -# if defined(__FreeBSD__) -# define str(s) #s - tcc_define_symbol(s, "__FreeBSD__", str( __FreeBSD__)); -# undef str -# endif -# if defined(__FreeBSD_kernel__) - tcc_define_symbol(s, "__FreeBSD_kernel__", NULL); -# endif -#endif -# if defined(__NetBSD__) -# define str(s) #s - tcc_define_symbol(s, "__NetBSD__", str( __NetBSD__)); -# undef str -# endif - - /* TinyCC & gcc defines */ -#if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64 - tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long long"); - tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long long"); -#else - tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long"); - tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long"); -#endif - -#ifdef TCC_TARGET_PE - tcc_define_symbol(s, "__WCHAR_TYPE__", "unsigned short"); - tcc_define_symbol(s, "__WINT_TYPE__", "unsigned short"); -#else - tcc_define_symbol(s, "__WCHAR_TYPE__", "int"); - /* wint_t is unsigned int by default, but (signed) int on BSDs - and unsigned short on windows. Other OSes might have still - other conventions, sigh. */ -#if defined(__FreeBSD__) || defined (__FreeBSD_kernel__) || defined(__NetBSD__) - tcc_define_symbol(s, "__WINT_TYPE__", "int"); -#else - tcc_define_symbol(s, "__WINT_TYPE__", "unsigned int"); -#endif -#endif - -#ifndef TCC_TARGET_PE - /* glibc defines */ - tcc_define_symbol(s, "__REDIRECT(name, proto, alias)", "name proto __asm__ (#alias)"); - tcc_define_symbol(s, "__REDIRECT_NTH(name, proto, alias)", "name proto __asm__ (#alias) __THROW"); - /* paths for crt objects */ - tcc_split_path(s, (void ***)&s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX); -#endif - - /* no section zero */ - dynarray_add((void ***)&s->sections, &s->nb_sections, NULL); - - /* create standard sections */ - text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR); - data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); - bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); - - /* symbols are always generated for linking stage */ - symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0, - ".strtab", - ".hashtab", SHF_PRIVATE); - strtab_section = symtab_section->link; - s->symtab = symtab_section; - - /* private symbol table for dynamic symbols */ - s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE, - ".dynstrtab", - ".dynhashtab", SHF_PRIVATE); - s->alacarte_link = 1; - s->nocommon = 1; - s->warn_implicit_function_declaration = 1; - -#ifdef CHAR_IS_UNSIGNED - s->char_is_unsigned = 1; -#endif - /* enable this if you want symbols with leading underscore on windows: */ -#if 0 /* def TCC_TARGET_PE */ - s->leading_underscore = 1; -#endif -#ifdef TCC_TARGET_I386 - s->seg_size = 32; -#endif -#ifdef TCC_IS_NATIVE - s->runtime_main = "main"; -#endif - return s; -} - -LIBTCCAPI void tcc_delete(TCCState *s1) -{ - int i; - int bench = s1->do_bench; - - tcc_cleanup(); - - /* close a preprocessor output */ - if (s1->ppfp && s1->ppfp != stdout) - fclose(s1->ppfp); - - /* free all sections */ - for(i = 1; i < s1->nb_sections; i++) - free_section(s1->sections[i]); - dynarray_reset(&s1->sections, &s1->nb_sections); - - for(i = 0; i < s1->nb_priv_sections; i++) - free_section(s1->priv_sections[i]); - dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections); - - /* free any loaded DLLs */ -#ifdef TCC_IS_NATIVE - for ( i = 0; i < s1->nb_loaded_dlls; i++) { - DLLReference *ref = s1->loaded_dlls[i]; - if ( ref->handle ) - dlclose(ref->handle); - } -#endif - - /* free loaded dlls array */ - dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls); - - /* free library paths */ - dynarray_reset(&s1->library_paths, &s1->nb_library_paths); - dynarray_reset(&s1->crt_paths, &s1->nb_crt_paths); - - /* free include paths */ - dynarray_reset(&s1->cached_includes, &s1->nb_cached_includes); - dynarray_reset(&s1->include_paths, &s1->nb_include_paths); - dynarray_reset(&s1->sysinclude_paths, &s1->nb_sysinclude_paths); - - tcc_free(s1->tcc_lib_path); - tcc_free(s1->soname); - tcc_free(s1->rpath); - tcc_free(s1->init_symbol); - tcc_free(s1->fini_symbol); - tcc_free(s1->outfile); - tcc_free(s1->deps_outfile); - dynarray_reset(&s1->files, &s1->nb_files); - dynarray_reset(&s1->target_deps, &s1->nb_target_deps); - dynarray_reset(&s1->pragma_libs, &s1->nb_pragma_libs); - -#ifdef TCC_IS_NATIVE -# ifdef HAVE_SELINUX - munmap (s1->write_mem, s1->mem_size); - munmap (s1->runtime_mem, s1->mem_size); -# else - tcc_free(s1->runtime_mem); -# endif -#endif - - tcc_free(s1->sym_attrs); - tcc_free(s1); - tcc_memstats(bench); -} - -LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname) -{ - tcc_split_path(s, (void ***)&s->include_paths, &s->nb_include_paths, pathname); - return 0; -} - -LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname) -{ - tcc_split_path(s, (void ***)&s->sysinclude_paths, &s->nb_sysinclude_paths, pathname); - return 0; -} - -ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags, int filetype) -{ - ElfW(Ehdr) ehdr; - int fd, ret, size; - - parse_flags = 0; -#ifdef CONFIG_TCC_ASM - /* if .S file, define __ASSEMBLER__ like gcc does */ - if ((filetype == TCC_FILETYPE_ASM) || (filetype == TCC_FILETYPE_ASM_PP)) { - tcc_define_symbol(s1, "__ASSEMBLER__", NULL); - parse_flags = PARSE_FLAG_ASM_FILE; - } -#endif - - /* open the file */ - ret = tcc_open(s1, filename); - if (ret < 0) { - if (flags & AFF_PRINT_ERROR) - tcc_error_noabort("file '%s' not found", filename); - return ret; - } - - /* update target deps */ - dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps, - tcc_strdup(filename)); - - if (flags & AFF_PREPROCESS) { - ret = tcc_preprocess(s1); - goto the_end; - } - - if (filetype == TCC_FILETYPE_C) { - /* C file assumed */ - ret = tcc_compile(s1); - goto the_end; - } - -#ifdef CONFIG_TCC_ASM - if (filetype == TCC_FILETYPE_ASM_PP) { - /* non preprocessed assembler */ - ret = tcc_assemble(s1, 1); - goto the_end; - } - - if (filetype == TCC_FILETYPE_ASM) { - /* preprocessed assembler */ - ret = tcc_assemble(s1, 0); - goto the_end; - } -#endif - - fd = file->fd; - /* assume executable format: auto guess file type */ - size = read(fd, &ehdr, sizeof(ehdr)); - lseek(fd, 0, SEEK_SET); - if (size <= 0) { - tcc_error_noabort("could not read header"); - goto the_end; - } - - if (size == sizeof(ehdr) && - ehdr.e_ident[0] == ELFMAG0 && - ehdr.e_ident[1] == ELFMAG1 && - ehdr.e_ident[2] == ELFMAG2 && - ehdr.e_ident[3] == ELFMAG3) { - - /* do not display line number if error */ - file->line_num = 0; - if (ehdr.e_type == ET_REL) { - ret = tcc_load_object_file(s1, fd, 0); - goto the_end; - - } -#ifndef TCC_TARGET_PE - if (ehdr.e_type == ET_DYN) { - if (s1->output_type == TCC_OUTPUT_MEMORY) { -#ifdef TCC_IS_NATIVE - void *h; - h = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY); - if (h) -#endif - ret = 0; - } else { - ret = tcc_load_dll(s1, fd, filename, - (flags & AFF_REFERENCED_DLL) != 0); - } - goto the_end; - } -#endif - tcc_error_noabort("unrecognized ELF file"); - goto the_end; - } - - if (memcmp((char *)&ehdr, ARMAG, 8) == 0) { - file->line_num = 0; /* do not display line number if error */ - ret = tcc_load_archive(s1, fd); - goto the_end; - } - -#ifdef TCC_TARGET_COFF - if (*(uint16_t *)(&ehdr) == COFF_C67_MAGIC) { - ret = tcc_load_coff(s1, fd); - goto the_end; - } -#endif - -#ifdef TCC_TARGET_PE - ret = pe_load_file(s1, filename, fd); -#else - /* as GNU ld, consider it is an ld script if not recognized */ - ret = tcc_load_ldscript(s1); -#endif - if (ret < 0) - tcc_error_noabort("unrecognized file type"); - -the_end: - tcc_close(); - return ret; -} - -LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename, int filetype) -{ - if (s->output_type == TCC_OUTPUT_PREPROCESS) - return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS, filetype); - else - return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR, filetype); -} - -LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname) -{ - tcc_split_path(s, (void ***)&s->library_paths, &s->nb_library_paths, pathname); - return 0; -} - -static int tcc_add_library_internal(TCCState *s, const char *fmt, - const char *filename, int flags, char **paths, int nb_paths) -{ - char buf[1024]; - int i; - - for(i = 0; i < nb_paths; i++) { - snprintf(buf, sizeof(buf), fmt, paths[i], filename); - if (tcc_add_file_internal(s, buf, flags, TCC_FILETYPE_BINARY) == 0) - return 0; - } - return -1; -} - -#ifndef TCC_TARGET_PE -/* find and load a dll. Return non zero if not found */ -/* XXX: add '-rpath' option support ? */ -ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags) -{ - return tcc_add_library_internal(s, "%s/%s", filename, flags, - s->library_paths, s->nb_library_paths); -} -#endif - -ST_FUNC int tcc_add_crt(TCCState *s, const char *filename) -{ - if (-1 == tcc_add_library_internal(s, "%s/%s", - filename, 0, s->crt_paths, s->nb_crt_paths)) - tcc_error_noabort("file '%s' not found", filename); - return 0; -} - -/* the library name is the same as the argument of the '-l' option */ -LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname) -{ -#ifdef TCC_TARGET_PE - const char *libs[] = { "%s/%s.def", "%s/lib%s.def", "%s/%s.dll", "%s/lib%s.dll", "%s/lib%s.a", NULL }; - const char **pp = s->static_link ? libs + 4 : libs; -#else - const char *libs[] = { "%s/lib%s.so", "%s/lib%s.a", NULL }; - const char **pp = s->static_link ? libs + 1 : libs; -#endif - while (*pp) { - if (0 == tcc_add_library_internal(s, *pp, - libraryname, 0, s->library_paths, s->nb_library_paths)) - return 0; - ++pp; - } - return -1; -} - -PUB_FUNC int tcc_add_library_err(TCCState *s, const char *libname) -{ - int ret = tcc_add_library(s, libname); - if (ret < 0) - tcc_error_noabort("cannot find library 'lib%s'", libname); - return ret; -} - -/* habdle #pragma comment(lib,) */ -ST_FUNC void tcc_add_pragma_libs(TCCState *s1) -{ - int i; - for (i = 0; i < s1->nb_pragma_libs; i++) - tcc_add_library_err(s1, s1->pragma_libs[i]); -} - -LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val) -{ -#ifdef TCC_TARGET_PE - /* On x86_64 'val' might not be reachable with a 32bit offset. - So it is handled here as if it were in a DLL. */ - pe_putimport(s, 0, name, (uintptr_t)val); -#else - add_elf_sym(symtab_section, (uintptr_t)val, 0, - ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, - SHN_ABS, name); -#endif - return 0; -} - -LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) -{ - s->output_type = output_type; - - if (!s->nostdinc) { - /* default include paths */ - /* -isystem paths have already been handled */ - tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS); - } - - /* if bound checking, then add corresponding sections */ -#ifdef CONFIG_TCC_BCHECK - if (s->do_bounds_check) { - /* define symbol */ - tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL); - /* create bounds sections */ - bounds_section = new_section(s, ".bounds", - SHT_PROGBITS, SHF_ALLOC); - lbounds_section = new_section(s, ".lbounds", - SHT_PROGBITS, SHF_ALLOC); - } -#endif - - if (s->char_is_unsigned) { - tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL); - } - - /* add debug sections */ - if (s->do_debug) { - /* stab symbols */ - stab_section = new_section(s, ".stab", SHT_PROGBITS, 0); - stab_section->sh_entsize = sizeof(Stab_Sym); - stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0); - put_elf_str(stabstr_section, ""); - stab_section->link = stabstr_section; - /* put first entry */ - put_stabs("", 0, 0, 0, 0); - } - - tcc_add_library_path(s, CONFIG_TCC_LIBPATHS); -#ifdef TCC_TARGET_PE -# ifdef _WIN32 - tcc_add_systemdir(s); -# endif -#else - /* add libc crt1/crti objects */ - if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) && - !s->nostdlib) { - if (output_type != TCC_OUTPUT_DLL) - tcc_add_crt(s, "crt1.o"); - tcc_add_crt(s, "crti.o"); - } -#endif - -#ifdef CONFIG_TCC_BCHECK - if (s->do_bounds_check && (output_type == TCC_OUTPUT_EXE)) - { - /* force a bcheck.o linking */ - addr_t func = TOK___bound_init; - Sym *sym = external_global_sym(func, &func_old_type, 0); - if (!sym->c) - put_extern_sym(sym, NULL, 0, 0); - } -#endif - - if (s->output_type == TCC_OUTPUT_PREPROCESS) - print_defines(); - - return 0; -} - -LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path) -{ - tcc_free(s->tcc_lib_path); - s->tcc_lib_path = tcc_strdup(path); -} - -#define WD_ALL 0x0001 /* warning is activated when using -Wall */ -#define FD_INVERT 0x0002 /* invert value before storing */ - -typedef struct FlagDef { - uint16_t offset; - uint16_t flags; - const char *name; -} FlagDef; - -static const FlagDef warning_defs[] = { - { offsetof(TCCState, warn_unsupported), 0, "unsupported" }, - { offsetof(TCCState, warn_write_strings), 0, "write-strings" }, - { offsetof(TCCState, warn_error), 0, "error" }, - { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL, - "implicit-function-declaration" }, -}; - -ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, int nb_flags, - const char *name, int value) -{ - int i; - const FlagDef *p; - const char *r; - - r = name; - if (r[0] == 'n' && r[1] == 'o' && r[2] == '-') { - r += 3; - value = !value; - } - for(i = 0, p = flags; i < nb_flags; i++, p++) { - if (!strcmp(r, p->name)) - goto found; - } - return -1; - found: - if (p->flags & FD_INVERT) - value = !value; - *(int *)((uint8_t *)s + p->offset) = value; - return 0; -} - -/* set/reset a warning */ -static int tcc_set_warning(TCCState *s, const char *warning_name, int value) -{ - int i; - const FlagDef *p; - - if (!strcmp(warning_name, "all")) { - for(i = 0, p = warning_defs; i < countof(warning_defs); i++, p++) { - if (p->flags & WD_ALL) - *(int *)((uint8_t *)s + p->offset) = 1; - } - return 0; - } else { - return set_flag(s, warning_defs, countof(warning_defs), - warning_name, value); - } -} - -static const FlagDef flag_defs[] = { - { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" }, - { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" }, - { offsetof(TCCState, nocommon), FD_INVERT, "common" }, - { offsetof(TCCState, leading_underscore), 0, "leading-underscore" }, - { offsetof(TCCState, ms_extensions), 0, "ms-extensions" }, - { offsetof(TCCState, old_struct_init_code), 0, "old-struct-init-code" }, - { offsetof(TCCState, dollars_in_identifiers), 0, "dollars-in-identifiers" }, -}; - -/* set/reset a flag */ -static int tcc_set_flag(TCCState *s, const char *flag_name, int value) -{ - return set_flag(s, flag_defs, countof(flag_defs), - flag_name, value); -} - - -static int strstart(const char *val, const char **str) -{ - const char *p, *q; - p = *str; - q = val; - while (*q) { - if (*p != *q) - return 0; - p++; - q++; - } - *str = p; - return 1; -} - -/* Like strstart, but automatically takes into account that ld options can - * - * - start with double or single dash (e.g. '--soname' or '-soname') - * - arguments can be given as separate or after '=' (e.g. '-Wl,-soname,x.so' - * or '-Wl,-soname=x.so') - * - * you provide `val` always in 'option[=]' form (no leading -) - */ -static int link_option(const char *str, const char *val, const char **ptr) -{ - const char *p, *q; - - /* there should be 1 or 2 dashes */ - if (*str++ != '-') - return 0; - if (*str == '-') - str++; - - /* then str & val should match (potentialy up to '=') */ - p = str; - q = val; - - while (*q != '\0' && *q != '=') { - if (*p != *q) - return 0; - p++; - q++; - } - - /* '=' near eos means ',' or '=' is ok */ - if (*q == '=') { - if (*p != ',' && *p != '=') - return 0; - p++; - q++; - } - - if (ptr) - *ptr = p; - return 1; -} - -static const char *skip_linker_arg(const char **str) -{ - const char *s1 = *str; - const char *s2 = strchr(s1, ','); - *str = s2 ? s2++ : (s2 = s1 + strlen(s1)); - return s2; -} - -static char *copy_linker_arg(const char *p) -{ - const char *q = p; - skip_linker_arg(&q); - return pstrncpy(tcc_malloc(q - p + 1), p, q - p); -} - -/* set linker options */ -static int tcc_set_linker(TCCState *s, const char *option) -{ - while (option && *option) { - - const char *p = option; - char *end = NULL; - int ignoring = 0; - - if (link_option(option, "Bsymbolic", &p)) { - s->symbolic = 1; - } else if (link_option(option, "nostdlib", &p)) { - s->nostdlib = 1; - } else if (link_option(option, "fini=", &p)) { - s->fini_symbol = copy_linker_arg(p); - ignoring = 1; - } else if (link_option(option, "image-base=", &p) - || link_option(option, "Ttext=", &p)) { - s->text_addr = strtoull(p, &end, 16); - s->has_text_addr = 1; - } else if (link_option(option, "init=", &p)) { - s->init_symbol = copy_linker_arg(p); - ignoring = 1; - } else if (link_option(option, "oformat=", &p)) { -#if defined(TCC_TARGET_PE) - if (strstart("pe-", &p)) { -#elif defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) - if (strstart("elf64-", &p)) { -#else - if (strstart("elf32-", &p)) { -#endif - s->output_format = TCC_OUTPUT_FORMAT_ELF; - } else if (!strcmp(p, "binary")) { - s->output_format = TCC_OUTPUT_FORMAT_BINARY; -#ifdef TCC_TARGET_COFF - } else if (!strcmp(p, "coff")) { - s->output_format = TCC_OUTPUT_FORMAT_COFF; -#endif - } else - goto err; - - } else if (link_option(option, "as-needed", &p)) { - ignoring = 1; - } else if (link_option(option, "O", &p)) { - ignoring = 1; - } else if (link_option(option, "rpath=", &p)) { - s->rpath = copy_linker_arg(p); - } else if (link_option(option, "section-alignment=", &p)) { - s->section_align = strtoul(p, &end, 16); - } else if (link_option(option, "soname=", &p)) { - s->soname = copy_linker_arg(p); -#ifdef TCC_TARGET_PE - } else if (link_option(option, "file-alignment=", &p)) { - s->pe_file_align = strtoul(p, &end, 16); - } else if (link_option(option, "stack=", &p)) { - s->pe_stack_size = strtoul(p, &end, 10); - } else if (link_option(option, "subsystem=", &p)) { -#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) - if (!strcmp(p, "native")) { - s->pe_subsystem = 1; - } else if (!strcmp(p, "console")) { - s->pe_subsystem = 3; - } else if (!strcmp(p, "gui")) { - s->pe_subsystem = 2; - } else if (!strcmp(p, "posix")) { - s->pe_subsystem = 7; - } else if (!strcmp(p, "efiapp")) { - s->pe_subsystem = 10; - } else if (!strcmp(p, "efiboot")) { - s->pe_subsystem = 11; - } else if (!strcmp(p, "efiruntime")) { - s->pe_subsystem = 12; - } else if (!strcmp(p, "efirom")) { - s->pe_subsystem = 13; -#elif defined(TCC_TARGET_ARM) - if (!strcmp(p, "wince")) { - s->pe_subsystem = 9; -#endif - } else - goto err; -#endif - } else - goto err; - - if (ignoring && s->warn_unsupported) err: { - char buf[100], *e; - pstrcpy(buf, sizeof buf, e = copy_linker_arg(option)), tcc_free(e); - if (ignoring) - tcc_warning("unsupported linker option '%s'", buf); - else - tcc_error("unsupported linker option '%s'", buf); - } - option = skip_linker_arg(&p); - } - return 0; -} - -typedef struct TCCOption { - const char *name; - uint16_t index; - uint16_t flags; -} TCCOption; - -enum { - TCC_OPTION_HELP, - TCC_OPTION_I, - TCC_OPTION_D, - TCC_OPTION_U, - TCC_OPTION_P, - TCC_OPTION_L, - TCC_OPTION_B, - TCC_OPTION_l, - TCC_OPTION_bench, - TCC_OPTION_bt, - TCC_OPTION_b, - TCC_OPTION_g, - TCC_OPTION_c, - TCC_OPTION_dumpversion, - TCC_OPTION_d, - TCC_OPTION_float_abi, - TCC_OPTION_static, - TCC_OPTION_std, - TCC_OPTION_shared, - TCC_OPTION_soname, - TCC_OPTION_o, - TCC_OPTION_r, - TCC_OPTION_s, - TCC_OPTION_traditional, - TCC_OPTION_Wl, - TCC_OPTION_W, - TCC_OPTION_O, - TCC_OPTION_m, - TCC_OPTION_f, - TCC_OPTION_isystem, - TCC_OPTION_iwithprefix, - TCC_OPTION_nostdinc, - TCC_OPTION_nostdlib, - TCC_OPTION_print_search_dirs, - TCC_OPTION_rdynamic, - TCC_OPTION_pedantic, - TCC_OPTION_pthread, - TCC_OPTION_run, - TCC_OPTION_v, - TCC_OPTION_w, - TCC_OPTION_pipe, - TCC_OPTION_E, - TCC_OPTION_MD, - TCC_OPTION_MF, - TCC_OPTION_x -}; - -#define TCC_OPTION_HAS_ARG 0x0001 -#define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */ - -static const TCCOption tcc_options[] = { - { "h", TCC_OPTION_HELP, 0 }, - { "-help", TCC_OPTION_HELP, 0 }, - { "?", TCC_OPTION_HELP, 0 }, - { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG }, - { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG }, - { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG }, - { "P", TCC_OPTION_P, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, - { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG }, - { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG }, - { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, - { "bench", TCC_OPTION_bench, 0 }, -#ifdef CONFIG_TCC_BACKTRACE - { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG }, -#endif -#ifdef CONFIG_TCC_BCHECK - { "b", TCC_OPTION_b, 0 }, -#endif - { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, - { "c", TCC_OPTION_c, 0 }, - { "dumpversion", TCC_OPTION_dumpversion, 0}, - { "d", TCC_OPTION_d, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, -#ifdef TCC_TARGET_ARM - { "mfloat-abi", TCC_OPTION_float_abi, TCC_OPTION_HAS_ARG }, -#endif - { "static", TCC_OPTION_static, 0 }, - { "std", TCC_OPTION_std, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, - { "shared", TCC_OPTION_shared, 0 }, - { "soname", TCC_OPTION_soname, TCC_OPTION_HAS_ARG }, - { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG }, - { "pedantic", TCC_OPTION_pedantic, 0}, - { "pthread", TCC_OPTION_pthread, 0}, - { "run", TCC_OPTION_run, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, - { "rdynamic", TCC_OPTION_rdynamic, 0 }, - { "r", TCC_OPTION_r, 0 }, - { "s", TCC_OPTION_s, 0 }, - { "traditional", TCC_OPTION_traditional, 0 }, - { "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, - { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, - { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, - { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG }, - { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, - { "isystem", TCC_OPTION_isystem, TCC_OPTION_HAS_ARG }, - { "iwithprefix", TCC_OPTION_iwithprefix, TCC_OPTION_HAS_ARG }, - { "nostdinc", TCC_OPTION_nostdinc, 0 }, - { "nostdlib", TCC_OPTION_nostdlib, 0 }, - { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 }, - { "v", TCC_OPTION_v, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, - { "w", TCC_OPTION_w, 0 }, - { "pipe", TCC_OPTION_pipe, 0}, - { "E", TCC_OPTION_E, 0}, - { "MD", TCC_OPTION_MD, 0}, - { "MF", TCC_OPTION_MF, TCC_OPTION_HAS_ARG }, - { "x", TCC_OPTION_x, TCC_OPTION_HAS_ARG }, - { NULL, 0, 0 }, -}; - -static void parse_option_D(TCCState *s1, const char *optarg) -{ - char *sym = tcc_strdup(optarg); - char *value = strchr(sym, '='); - if (value) - *value++ = '\0'; - tcc_define_symbol(s1, sym, value); - tcc_free(sym); -} - -static void args_parser_add_file(TCCState *s, const char* filename, int filetype) -{ - int len = strlen(filename); - char *p = tcc_malloc(len + 2); - if (filetype) { - *p = filetype; - } - else { - /* use a file extension to detect a filetype */ - const char *ext = tcc_fileextension(filename); - if (ext[0]) { - ext++; - if (!strcmp(ext, "S")) - *p = TCC_FILETYPE_ASM_PP; - else - if (!strcmp(ext, "s")) - *p = TCC_FILETYPE_ASM; - else - if (!PATHCMP(ext, "c") || !PATHCMP(ext, "i")) - *p = TCC_FILETYPE_C; - else - *p = TCC_FILETYPE_BINARY; - } - else { - *p = TCC_FILETYPE_C; - } - } - strcpy(p+1, filename); - dynarray_add((void ***)&s->files, &s->nb_files, p); -} - -PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) -{ - const TCCOption *popt; - const char *optarg, *r; - int run = 0; - int pthread = 0; - int optind = 0; - int filetype = 0; - - /* collect -Wl options for input such as "-Wl,-rpath -Wl," */ - CString linker_arg; - cstr_new(&linker_arg); - - while (optind < argc) { - - r = argv[optind++]; - if (r[0] != '-' || r[1] == '\0') { - args_parser_add_file(s, r, filetype); - if (run) { - optind--; - /* argv[0] will be this file */ - break; - } - continue; - } - - /* find option in table */ - for(popt = tcc_options; ; ++popt) { - const char *p1 = popt->name; - const char *r1 = r + 1; - if (p1 == NULL) - tcc_error("invalid option -- '%s'", r); - if (!strstart(p1, &r1)) - continue; - optarg = r1; - if (popt->flags & TCC_OPTION_HAS_ARG) { - if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) { - if (optind >= argc) - tcc_error("argument to '%s' is missing", r); - optarg = argv[optind++]; - } - } else if (*r1 != '\0') - continue; - break; - } - - switch(popt->index) { - case TCC_OPTION_HELP: - return 0; - case TCC_OPTION_I: - tcc_add_include_path(s, optarg); - break; - case TCC_OPTION_D: - parse_option_D(s, optarg); - break; - case TCC_OPTION_U: - tcc_undefine_symbol(s, optarg); - break; - case TCC_OPTION_L: - tcc_add_library_path(s, optarg); - break; - case TCC_OPTION_B: - /* set tcc utilities path (mainly for tcc development) */ - tcc_set_lib_path(s, optarg); - break; - case TCC_OPTION_l: - args_parser_add_file(s, r, TCC_FILETYPE_BINARY); - s->nb_libraries++; - break; - case TCC_OPTION_pthread: - parse_option_D(s, "_REENTRANT"); - pthread = 1; - break; - case TCC_OPTION_bench: - s->do_bench = 1; - break; -#ifdef CONFIG_TCC_BACKTRACE - case TCC_OPTION_bt: - tcc_set_num_callers(atoi(optarg)); - break; -#endif -#ifdef CONFIG_TCC_BCHECK - case TCC_OPTION_b: - s->do_bounds_check = 1; - s->do_debug = 1; - break; -#endif - case TCC_OPTION_g: - s->do_debug = 1; - break; - case TCC_OPTION_c: - if (s->output_type) - tcc_warning("-c: some compiler action already specified (%d)", s->output_type); - s->output_type = TCC_OUTPUT_OBJ; - break; - case TCC_OPTION_d: - if (*optarg == 'D') - s->dflag = 1; - else { - if (s->warn_unsupported) - goto unsupported_option; - tcc_error("invalid option -- '%s'", r); - } - break; -#ifdef TCC_TARGET_ARM - case TCC_OPTION_float_abi: - /* tcc doesn't support soft float yet */ - if (!strcmp(optarg, "softfp")) { - s->float_abi = ARM_SOFTFP_FLOAT; - tcc_undefine_symbol(s, "__ARM_PCS_VFP"); - } else if (!strcmp(optarg, "hard")) - s->float_abi = ARM_HARD_FLOAT; - else - tcc_error("unsupported float abi '%s'", optarg); - break; -#endif - case TCC_OPTION_static: - s->static_link = 1; - break; - case TCC_OPTION_std: - /* silently ignore, a current purpose: - allow to use a tcc as a reference compiler for "make test" */ - break; - case TCC_OPTION_shared: - if (s->output_type) - tcc_warning("-shared: some compiler action already specified (%d)", s->output_type); - s->output_type = TCC_OUTPUT_DLL; - break; - case TCC_OPTION_soname: - s->soname = tcc_strdup(optarg); - break; - case TCC_OPTION_m: - s->option_m = tcc_strdup(optarg); - break; - case TCC_OPTION_o: - if (s->outfile) { - tcc_warning("multiple -o option"); - tcc_free(s->outfile); - } - s->outfile = tcc_strdup(optarg); - break; - case TCC_OPTION_r: - /* generate a .o merging several output files */ - if (s->output_type) - tcc_warning("-r: some compiler action already specified (%d)", s->output_type); - s->option_r = 1; - s->output_type = TCC_OUTPUT_OBJ; - break; - case TCC_OPTION_isystem: - tcc_add_sysinclude_path(s, optarg); - break; - case TCC_OPTION_iwithprefix: - if (1) { - char buf[1024]; - int buf_size = sizeof(buf)-1; - char *p = &buf[0]; - - char *sysroot = "{B}/"; - int len = strlen(sysroot); - if (len > buf_size) - len = buf_size; - strncpy(p, sysroot, len); - p += len; - buf_size -= len; - - len = strlen(optarg); - if (len > buf_size) - len = buf_size; - strncpy(p, optarg, len+1); - tcc_add_sysinclude_path(s, buf); - } - break; - case TCC_OPTION_nostdinc: - s->nostdinc = 1; - break; - case TCC_OPTION_nostdlib: - s->nostdlib = 1; - break; - case TCC_OPTION_print_search_dirs: - s->print_search_dirs = 1; - break; - case TCC_OPTION_run: - if (s->output_type) - tcc_warning("-run: some compiler action already specified (%d)", s->output_type); - s->output_type = TCC_OUTPUT_MEMORY; - tcc_set_options(s, optarg); - run = 1; - break; - case TCC_OPTION_v: - do ++s->verbose; while (*optarg++ == 'v'); - break; - case TCC_OPTION_f: - if (tcc_set_flag(s, optarg, 1) < 0 && s->warn_unsupported) - goto unsupported_option; - break; - case TCC_OPTION_W: - if (tcc_set_warning(s, optarg, 1) < 0 && - s->warn_unsupported) - goto unsupported_option; - break; - case TCC_OPTION_w: - s->warn_none = 1; - break; - case TCC_OPTION_rdynamic: - s->rdynamic = 1; - break; - case TCC_OPTION_Wl: - if (linker_arg.size) - --linker_arg.size, cstr_ccat(&linker_arg, ','); - cstr_cat(&linker_arg, optarg); - cstr_ccat(&linker_arg, '\0'); - break; - case TCC_OPTION_E: - if (s->output_type) - tcc_warning("-E: some compiler action already specified (%d)", s->output_type); - s->output_type = TCC_OUTPUT_PREPROCESS; - break; - case TCC_OPTION_P: - s->Pflag = atoi(optarg) + 1; - break; - case TCC_OPTION_MD: - s->gen_deps = 1; - break; - case TCC_OPTION_MF: - s->deps_outfile = tcc_strdup(optarg); - break; - case TCC_OPTION_dumpversion: - printf ("%s\n", TCC_VERSION); - exit(0); - case TCC_OPTION_s: - s->do_strip = 1; - break; - case TCC_OPTION_traditional: - break; - case TCC_OPTION_x: - if (*optarg == 'c') - filetype = TCC_FILETYPE_C; - else - if (*optarg == 'a') - filetype = TCC_FILETYPE_ASM_PP; - else - if (*optarg == 'n') - filetype = 0; - else - tcc_warning("unsupported language '%s'", optarg); - break; - case TCC_OPTION_O: - if (1) { - int opt = atoi(optarg); - char *sym = "__OPTIMIZE__"; - if (opt) - tcc_define_symbol(s, sym, 0); - else - tcc_undefine_symbol(s, sym); - } - break; - case TCC_OPTION_pedantic: - case TCC_OPTION_pipe: - /* ignored */ - break; - default: - if (s->warn_unsupported) { - unsupported_option: - tcc_warning("unsupported option '%s'", r); - } - break; - } - } - - if (s->output_type == 0) - s->output_type = TCC_OUTPUT_EXE; - - if (pthread && s->output_type != TCC_OUTPUT_OBJ) - tcc_set_options(s, "-lpthread"); - - if (s->output_type == TCC_OUTPUT_EXE) - tcc_set_linker(s, (const char *)linker_arg.data); - cstr_free(&linker_arg); - - return optind; -} - -LIBTCCAPI int tcc_set_options(TCCState *s, const char *str) -{ - const char *s1; - char **argv, *arg; - int argc, len; - int ret; - - argc = 0, argv = NULL; - for(;;) { - while (is_space(*str)) - str++; - if (*str == '\0') - break; - s1 = str; - while (*str != '\0' && !is_space(*str)) - str++; - len = str - s1; - arg = tcc_malloc(len + 1); - pstrncpy(arg, s1, len); - dynarray_add((void ***)&argv, &argc, arg); - } - ret = tcc_parse_args(s, argc, argv); - dynarray_reset(&argv, &argc); - return ret; -} - -PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time) -{ - double tt; - tt = (double)total_time / 1000000.0; - if (tt < 0.001) - tt = 0.001; - if (total_bytes < 1) - total_bytes = 1; - fprintf(stderr, "%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n", - tok_ident - TOK_IDENT, total_lines, total_bytes, - tt, (int)(total_lines / tt), - total_bytes / tt / 1000000.0); -} - -PUB_FUNC void tcc_set_environment(TCCState *s) -{ - char * path; - - path = getenv("C_INCLUDE_PATH"); - if(path != NULL) { - tcc_add_include_path(s, path); - } - path = getenv("CPATH"); - if(path != NULL) { - tcc_add_include_path(s, path); - } - path = getenv("LIBRARY_PATH"); - if(path != NULL) { - tcc_add_library_path(s, path); - } -} diff --git a/external/TCC/libtcc.h b/external/TCC/libtcc.h deleted file mode 100644 index 97b85872..00000000 --- a/external/TCC/libtcc.h +++ /dev/null @@ -1,104 +0,0 @@ -#ifndef LIBTCC_H -#define LIBTCC_H - -#ifndef LIBTCCAPI -# define LIBTCCAPI -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -struct TCCState; - -typedef struct TCCState TCCState; - -/* create a new TCC compilation context */ -LIBTCCAPI TCCState *tcc_new(void); - -/* free a TCC compilation context */ -LIBTCCAPI void tcc_delete(TCCState *s); - -/* set CONFIG_TCCDIR at runtime */ -LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path); - -/* set error/warning display callback */ -LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, - void (*error_func)(void *opaque, const char *msg)); - -/* set options as from command line (multiple supported) */ -LIBTCCAPI int tcc_set_options(TCCState *s, const char *str); - -/*****************************/ -/* preprocessor */ - -/* add include path */ -LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname); - -/* add in system include path */ -LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname); - -/* define preprocessor symbol 'sym'. Can put optional value */ -LIBTCCAPI void tcc_define_symbol(TCCState *s, const char *sym, const char *value); - -/* undefine preprocess symbol 'sym' */ -LIBTCCAPI void tcc_undefine_symbol(TCCState *s, const char *sym); - -/*****************************/ -/* compiling */ - -/* add a file (C file, dll, object, library, ld script). Return -1 if error. */ -LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename, int filetype); -#define TCC_FILETYPE_BINARY 1 -#define TCC_FILETYPE_C 2 -#define TCC_FILETYPE_ASM 3 -#define TCC_FILETYPE_ASM_PP 4 - -/* compile a string containing a C source. Return -1 if error. */ -LIBTCCAPI int tcc_compile_string(TCCState *s, const char *buf); - -/*****************************/ -/* linking commands */ - -/* set output type. MUST BE CALLED before any compilation */ -LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type); -#define TCC_OUTPUT_MEMORY 1 /* output will be run in memory (default) */ -#define TCC_OUTPUT_EXE 2 /* executable file */ -#define TCC_OUTPUT_DLL 3 /* dynamic library */ -#define TCC_OUTPUT_OBJ 4 /* object file */ -#define TCC_OUTPUT_PREPROCESS 5 /* only preprocess (used internally) */ - -/* equivalent to -Lpath option */ -LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname); - -/* the library name is the same as the argument of the '-l' option */ -LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname); - -/* add a symbol to the compiled program */ -LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val); - -/* output an executable, library or object file. DO NOT call - tcc_relocate() before. */ -LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename); - -/* link and run main() function and return its value. DO NOT call - tcc_relocate() before. */ -LIBTCCAPI int tcc_run(TCCState *s, int argc, char **argv); - -/* do all relocations (needed before using tcc_get_symbol()) */ -LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr); -/* possible values for 'ptr': - - TCC_RELOCATE_AUTO : Allocate and manage memory internally - - NULL : return required memory size for the step below - - memory address : copy code to memory passed by the caller - returns -1 if error. */ -#define TCC_RELOCATE_AUTO (void*)1 - -/* return symbol value or NULL if not found */ -LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/external/TCC/stab.def b/external/TCC/stab.def deleted file mode 100644 index 48ea231e..00000000 --- a/external/TCC/stab.def +++ /dev/null @@ -1,234 +0,0 @@ -/* Table of DBX symbol codes for the GNU system. - Copyright (C) 1988, 1997 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The GNU C 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* This contains contribution from Cygnus Support. */ - -/* Global variable. Only the name is significant. - To find the address, look in the corresponding external symbol. */ -__define_stab (N_GSYM, 0x20, "GSYM") - -/* Function name for BSD Fortran. Only the name is significant. - To find the address, look in the corresponding external symbol. */ -__define_stab (N_FNAME, 0x22, "FNAME") - -/* Function name or text-segment variable for C. Value is its address. - Desc is supposedly starting line number, but GCC doesn't set it - and DBX seems not to miss it. */ -__define_stab (N_FUN, 0x24, "FUN") - -/* Data-segment variable with internal linkage. Value is its address. - "Static Sym". */ -__define_stab (N_STSYM, 0x26, "STSYM") - -/* BSS-segment variable with internal linkage. Value is its address. */ -__define_stab (N_LCSYM, 0x28, "LCSYM") - -/* Name of main routine. Only the name is significant. - This is not used in C. */ -__define_stab (N_MAIN, 0x2a, "MAIN") - -/* Global symbol in Pascal. - Supposedly the value is its line number; I'm skeptical. */ -__define_stab (N_PC, 0x30, "PC") - -/* Number of symbols: 0, files,,funcs,lines according to Ultrix V4.0. */ -__define_stab (N_NSYMS, 0x32, "NSYMS") - -/* "No DST map for sym: name, ,0,type,ignored" according to Ultrix V4.0. */ -__define_stab (N_NOMAP, 0x34, "NOMAP") - -/* New stab from Solaris. I don't know what it means, but it - don't seem to contain useful information. */ -__define_stab (N_OBJ, 0x38, "OBJ") - -/* New stab from Solaris. I don't know what it means, but it - don't seem to contain useful information. Possibly related to the - optimization flags used in this module. */ -__define_stab (N_OPT, 0x3c, "OPT") - -/* Register variable. Value is number of register. */ -__define_stab (N_RSYM, 0x40, "RSYM") - -/* Modula-2 compilation unit. Can someone say what info it contains? */ -__define_stab (N_M2C, 0x42, "M2C") - -/* Line number in text segment. Desc is the line number; - value is corresponding address. */ -__define_stab (N_SLINE, 0x44, "SLINE") - -/* Similar, for data segment. */ -__define_stab (N_DSLINE, 0x46, "DSLINE") - -/* Similar, for bss segment. */ -__define_stab (N_BSLINE, 0x48, "BSLINE") - -/* Sun's source-code browser stabs. ?? Don't know what the fields are. - Supposedly the field is "path to associated .cb file". THIS VALUE - OVERLAPS WITH N_BSLINE! */ -__define_stab (N_BROWS, 0x48, "BROWS") - -/* GNU Modula-2 definition module dependency. Value is the modification time - of the definition file. Other is non-zero if it is imported with the - GNU M2 keyword %INITIALIZE. Perhaps N_M2C can be used if there - are enough empty fields? */ -__define_stab(N_DEFD, 0x4a, "DEFD") - -/* THE FOLLOWING TWO STAB VALUES CONFLICT. Happily, one is for Modula-2 - and one is for C++. Still,... */ -/* GNU C++ exception variable. Name is variable name. */ -__define_stab (N_EHDECL, 0x50, "EHDECL") -/* Modula2 info "for imc": name,,0,0,0 according to Ultrix V4.0. */ -__define_stab (N_MOD2, 0x50, "MOD2") - -/* GNU C++ `catch' clause. Value is its address. Desc is nonzero if - this entry is immediately followed by a CAUGHT stab saying what exception - was caught. Multiple CAUGHT stabs means that multiple exceptions - can be caught here. If Desc is 0, it means all exceptions are caught - here. */ -__define_stab (N_CATCH, 0x54, "CATCH") - -/* Structure or union element. Value is offset in the structure. */ -__define_stab (N_SSYM, 0x60, "SSYM") - -/* Name of main source file. - Value is starting text address of the compilation. */ -__define_stab (N_SO, 0x64, "SO") - -/* Automatic variable in the stack. Value is offset from frame pointer. - Also used for type descriptions. */ -__define_stab (N_LSYM, 0x80, "LSYM") - -/* Beginning of an include file. Only Sun uses this. - In an object file, only the name is significant. - The Sun linker puts data into some of the other fields. */ -__define_stab (N_BINCL, 0x82, "BINCL") - -/* Name of sub-source file (#include file). - Value is starting text address of the compilation. */ -__define_stab (N_SOL, 0x84, "SOL") - -/* Parameter variable. Value is offset from argument pointer. - (On most machines the argument pointer is the same as the frame pointer. */ -__define_stab (N_PSYM, 0xa0, "PSYM") - -/* End of an include file. No name. - This and N_BINCL act as brackets around the file's output. - In an object file, there is no significant data in this entry. - The Sun linker puts data into some of the fields. */ -__define_stab (N_EINCL, 0xa2, "EINCL") - -/* Alternate entry point. Value is its address. */ -__define_stab (N_ENTRY, 0xa4, "ENTRY") - -/* Beginning of lexical block. - The desc is the nesting level in lexical blocks. - The value is the address of the start of the text for the block. - The variables declared inside the block *precede* the N_LBRAC symbol. */ -__define_stab (N_LBRAC, 0xc0, "LBRAC") - -/* Place holder for deleted include file. Replaces a N_BINCL and everything - up to the corresponding N_EINCL. The Sun linker generates these when - it finds multiple identical copies of the symbols from an include file. - This appears only in output from the Sun linker. */ -__define_stab (N_EXCL, 0xc2, "EXCL") - -/* Modula-2 scope information. Can someone say what info it contains? */ -__define_stab (N_SCOPE, 0xc4, "SCOPE") - -/* End of a lexical block. Desc matches the N_LBRAC's desc. - The value is the address of the end of the text for the block. */ -__define_stab (N_RBRAC, 0xe0, "RBRAC") - -/* Begin named common block. Only the name is significant. */ -__define_stab (N_BCOMM, 0xe2, "BCOMM") - -/* End named common block. Only the name is significant - (and it should match the N_BCOMM). */ -__define_stab (N_ECOMM, 0xe4, "ECOMM") - -/* End common (local name): value is address. - I'm not sure how this is used. */ -__define_stab (N_ECOML, 0xe8, "ECOML") - -/* These STAB's are used on Gould systems for Non-Base register symbols - or something like that. FIXME. I have assigned the values at random - since I don't have a Gould here. Fixups from Gould folk welcome... */ -__define_stab (N_NBTEXT, 0xF0, "NBTEXT") -__define_stab (N_NBDATA, 0xF2, "NBDATA") -__define_stab (N_NBBSS, 0xF4, "NBBSS") -__define_stab (N_NBSTS, 0xF6, "NBSTS") -__define_stab (N_NBLCS, 0xF8, "NBLCS") - -/* Second symbol entry containing a length-value for the preceding entry. - The value is the length. */ -__define_stab (N_LENG, 0xfe, "LENG") - -/* The above information, in matrix format. - - STAB MATRIX - _________________________________________________ - | 00 - 1F are not dbx stab symbols | - | In most cases, the low bit is the EXTernal bit| - - | 00 UNDEF | 02 ABS | 04 TEXT | 06 DATA | - | 01 |EXT | 03 |EXT | 05 |EXT | 07 |EXT | - - | 08 BSS | 0A INDR | 0C FN_SEQ | 0E | - | 09 |EXT | 0B | 0D | 0F | - - | 10 | 12 COMM | 14 SETA | 16 SETT | - | 11 | 13 | 15 | 17 | - - | 18 SETD | 1A SETB | 1C SETV | 1E WARNING| - | 19 | 1B | 1D | 1F FN | - - |_______________________________________________| - | Debug entries with bit 01 set are unused. | - | 20 GSYM | 22 FNAME | 24 FUN | 26 STSYM | - | 28 LCSYM | 2A MAIN | 2C | 2E | - | 30 PC | 32 NSYMS | 34 NOMAP | 36 | - | 38 OBJ | 3A | 3C OPT | 3E | - | 40 RSYM | 42 M2C | 44 SLINE | 46 DSLINE | - | 48 BSLINE*| 4A DEFD | 4C | 4E | - | 50 EHDECL*| 52 | 54 CATCH | 56 | - | 58 | 5A | 5C | 5E | - | 60 SSYM | 62 | 64 SO | 66 | - | 68 | 6A | 6C | 6E | - | 70 | 72 | 74 | 76 | - | 78 | 7A | 7C | 7E | - | 80 LSYM | 82 BINCL | 84 SOL | 86 | - | 88 | 8A | 8C | 8E | - | 90 | 92 | 94 | 96 | - | 98 | 9A | 9C | 9E | - | A0 PSYM | A2 EINCL | A4 ENTRY | A6 | - | A8 | AA | AC | AE | - | B0 | B2 | B4 | B6 | - | B8 | BA | BC | BE | - | C0 LBRAC | C2 EXCL | C4 SCOPE | C6 | - | C8 | CA | CC | CE | - | D0 | D2 | D4 | D6 | - | D8 | DA | DC | DE | - | E0 RBRAC | E2 BCOMM | E4 ECOMM | E6 | - | E8 ECOML | EA | EC | EE | - | F0 | F2 | F4 | F6 | - | F8 | FA | FC | FE LENG | - +-----------------------------------------------+ - * 50 EHDECL is also MOD2. - * 48 BSLINE is also BROWS. - */ diff --git a/external/TCC/stab.h b/external/TCC/stab.h deleted file mode 100644 index 80bd594a..00000000 --- a/external/TCC/stab.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __GNU_STAB__ - -/* Indicate the GNU stab.h is in use. */ - -#define __GNU_STAB__ - -#define __define_stab(NAME, CODE, STRING) NAME=CODE, - -enum __stab_debug_code -{ -#include "stab.def" -LAST_UNUSED_STAB_CODE -}; - -#undef __define_stab - -#endif /* __GNU_STAB_ */ diff --git a/external/TCC/tcc.c b/external/TCC/tcc.c deleted file mode 100644 index 9daf6e66..00000000 --- a/external/TCC/tcc.c +++ /dev/null @@ -1,367 +0,0 @@ -/* - * TCC - Tiny C Compiler - * - * Copyright (c) 2001-2004 Fabrice Bellard - * - * 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef ONE_SOURCE -#include "libtcc.c" -#else -#include "tcc.h" -#endif - -static void print_paths(const char *msg, char **paths, int nb_paths) -{ - int i; - printf("%s:\n%s", msg, nb_paths ? "" : " -\n"); - for(i = 0; i < nb_paths; i++) - printf(" %s\n", paths[i]); -} - -static void display_info(TCCState *s, int what) -{ - switch (what) { - case 0: - printf("tcc version %s (" -#ifdef TCC_TARGET_I386 - "i386" -#elif defined TCC_TARGET_X86_64 - "x86-64" -#elif defined TCC_TARGET_C67 - "C67" -#elif defined TCC_TARGET_ARM - "ARM" -# ifdef TCC_ARM_HARDFLOAT - " Hard Float" -# endif -#elif defined TCC_TARGET_ARM64 - "AArch64" -# ifdef TCC_ARM_HARDFLOAT - " Hard Float" -# endif -#endif -#ifdef TCC_TARGET_PE - " Windows" -#else - " Linux" -#endif - ")\n", TCC_VERSION); - break; - case 1: - printf("install: %s\n", s->tcc_lib_path); - /* print_paths("programs", NULL, 0); */ - print_paths("include", s->sysinclude_paths, s->nb_sysinclude_paths); - print_paths("libraries", s->library_paths, s->nb_library_paths); -#ifndef TCC_TARGET_PE - print_paths("crt", s->crt_paths, s->nb_crt_paths); - printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(s)); -#endif - break; - } -} - -static void help(void) -{ - printf("Tiny C Compiler "TCC_VERSION" - Copyright (C) 2001-2006 Fabrice Bellard\n" - "Usage: tcc [options...] [-o outfile] [-c] infile(s)...\n" - " tcc [options...] -run infile [arguments...]\n" - "General options:\n" - " -c compile only - generate an object file\n" - " -o outfile set output filename\n" - " -run run compiled source\n" - " -fflag set or reset (with 'no-' prefix) 'flag' (see man page)\n" - " -Wwarning set or reset (with 'no-' prefix) 'warning' (see man page)\n" - " -w disable all warnings\n" - " -v show version\n" - " -vv show included files (as sole argument: show search paths)\n" - " -dumpversion\n" - " -bench show compilation statistics\n" - " -xc -xa specify type of the next infile\n" - " - use stdin pipe as infile\n" - "Preprocessor options:\n" - " -Idir add include path 'dir'\n" - " -Dsym[=val] define 'sym' with value 'val'\n" - " -Usym undefine 'sym'\n" - " -E preprocess only\n" - " -P[1] no/alternative output of #line directives with -E\n" - " -dD dump defines\n" - "Linker options:\n" - " -Ldir add library path 'dir'\n" - " -llib link with dynamic or static library 'lib'\n" - " -pthread link with -lpthread and -D_REENTRANT (POSIX Linux)\n" - " -r generate (relocatable) object file\n" - " -rdynamic export all global symbols to dynamic linker\n" - " -shared generate a shared library\n" - " -soname set name for shared library to be used at runtime\n" - " -static static linking\n" - " -Wl,-opt[=val] set linker option (see manual)\n" - "Debugger options:\n" - " -g generate runtime debug info\n" -#ifdef CONFIG_TCC_BCHECK - " -b compile with built-in memory and bounds checker (implies -g)\n" -#endif -#ifdef CONFIG_TCC_BACKTRACE - " -bt N show N callers in stack traces\n" -#endif - "Misc options:\n" - " -nostdinc do not use standard system include paths\n" - " -nostdlib do not link with standard crt and libraries\n" - " -Bdir use 'dir' as tcc internal library and include path\n" - " -MD generate target dependencies for make\n" - " -MF depfile put generated dependencies here\n" - ); -} - -/* re-execute the i386/x86_64 cross-compilers with tcc -m32/-m64: */ -#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 -#ifdef _WIN32 -#include -static int execvp_win32(const char *prog, char **argv) -{ - int ret = spawnvp(P_NOWAIT, prog, (const char *const*)argv); - if (-1 == ret) - return ret; - cwait(&ret, ret, WAIT_CHILD); - exit(ret); -} -#define execvp execvp_win32 -#endif -static void exec_other_tcc(TCCState *s, char **argv, const char *optarg) -{ - char child_path[4096], *child_name; const char *target; - switch (atoi(optarg)) { -#ifdef TCC_TARGET_I386 - case 32: break; - case 64: target = "x86_64"; -#else - case 64: break; - case 32: target = "i386"; -#endif - pstrcpy(child_path, sizeof child_path - 40, argv[0]); - child_name = tcc_basename(child_path); - strcpy(child_name, target); -#ifdef TCC_TARGET_PE - strcat(child_name, "-win32"); -#endif - strcat(child_name, "-tcc"); - if (strcmp(argv[0], child_path)) { - if (s->verbose > 0) - printf("tcc: using '%s'\n", child_name), fflush(stdout); - execvp(argv[0] = child_path, argv); - } - tcc_error("'%s' not found", child_name); - case 0: /* ignore -march etc. */ - break; - default: - tcc_warning("unsupported option \"-m%s\"", optarg); - } -} -#else -#define exec_other_tcc(s, argv, optarg) -#endif - -static void gen_makedeps(TCCState *s, const char *target, const char *filename) -{ - FILE *depout; - char buf[1024], *ext; - int i; - - if (!filename) { - /* compute filename automatically - * dir/file.o -> dir/file.d */ - pstrcpy(buf, sizeof(buf), target); - ext = tcc_fileextension(buf); - pstrcpy(ext, sizeof(buf) - (ext-buf), ".d"); - filename = buf; - } - - if (s->verbose) - printf("<- %s\n", filename); - - /* XXX return err codes instead of error() ? */ - depout = fopen(filename, "w"); - if (!depout) - tcc_error("could not open '%s'", filename); - - fprintf(depout, "%s : \\\n", target); - for (i=0; inb_target_deps; ++i) - fprintf(depout, " %s \\\n", s->target_deps[i]); - fprintf(depout, "\n"); - fclose(depout); -} - -static char *default_outputfile(TCCState *s, const char *first_file) -{ - char buf[1024]; - char *ext; - const char *name = "a"; - - if (first_file && strcmp(first_file, "-")) - name = tcc_basename(first_file); - pstrcpy(buf, sizeof(buf), name); - ext = tcc_fileextension(buf); -#ifdef TCC_TARGET_PE - if (s->output_type == TCC_OUTPUT_DLL) - strcpy(ext, ".dll"); - else - if (s->output_type == TCC_OUTPUT_EXE) - strcpy(ext, ".exe"); - else -#endif - if (( (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) || - (s->output_type == TCC_OUTPUT_PREPROCESS) ) - && *ext) - strcpy(ext, ".o"); - else - strcpy(buf, "a.out"); - - return tcc_strdup(buf); -} - -static int64_t getclock_us(void) -{ -#ifdef _WIN32 - struct _timeb tb; - _ftime(&tb); - return (tb.time * 1000LL + tb.millitm) * 1000LL; -#else - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec * 1000000LL + tv.tv_usec; -#endif -} - -int main(int argc, char **argv) -{ - TCCState *s; - int ret, optind, i; - int64_t start_time = 0; - - s = tcc_new(); - - optind = tcc_parse_args(s, argc - 1, argv + 1); - - if (s->do_bench) - start_time = getclock_us(); - - tcc_set_environment(s); - - if (optind == 0) { - help(); - return 1; - } - - if (s->option_m) - exec_other_tcc(s, argv, s->option_m); - - if (s->verbose) - display_info(s, 0); - - if (s->print_search_dirs || (s->verbose == 2 && optind == 1)) { - tcc_set_output_type(s, TCC_OUTPUT_MEMORY); - display_info(s, 1); - return 0; - } - - if (s->verbose && optind == 1) - return 0; - - if (s->nb_files == 0) - tcc_error("no input files\n"); - - /* check -c consistency : only single file handled. XXX: checks file type */ - if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) { - if (s->nb_libraries != 0) - tcc_error("cannot specify libraries with -c"); - /* accepts only a single input file */ - if ((s->nb_files != 1) && s->outfile) { - tcc_error("cannot specify multiple files with -c and -o"); - } - } - - if (s->output_type == TCC_OUTPUT_PREPROCESS) { - if (!s->outfile) { - s->ppfp = stdout; - } else { - s->ppfp = fopen(s->outfile, "w"); - if (!s->ppfp) - tcc_error("could not write '%s'", s->outfile); - } - } - - tcc_set_output_type(s, s->output_type); - - /* compile or add each files or library */ - for(i = ret = 0; i < s->nb_files && ret == 0; i++) { - int filetype = *(unsigned char *)s->files[i]; - const char *filename = s->files[i] + 1; - if (filename[0] == '-' && filename[1] == 'l') { - if (tcc_add_library(s, filename + 2) < 0) { - tcc_error_noabort("cannot find library 'lib%s'", filename+2); - ret = 1; - } - } else { - if (1 == s->verbose) - printf("-> %s\n", filename); - if (!s->outfile) - s->outfile = default_outputfile(s, filename); - if (tcc_add_file(s, filename, filetype) < 0) - ret = 1; - else - if (s->output_type == TCC_OUTPUT_OBJ) { - ret = !!tcc_output_file(s, s->outfile); - if (s->gen_deps && !ret) - gen_makedeps(s, s->outfile, s->deps_outfile); - if (!ret) { - if ((i+1) < s->nb_files) { - tcc_delete(s); - s = tcc_new(); - tcc_parse_args(s, argc - 1, argv + 1); - tcc_set_environment(s); - if (s->output_type != TCC_OUTPUT_OBJ) - tcc_error("interlnal error"); - tcc_set_output_type(s, s->output_type); - } - } - } - } - } - - if (0 == ret) { - if (s->output_type == TCC_OUTPUT_MEMORY) { -#ifdef TCC_IS_NATIVE - ret = tcc_run(s, argc - 1 - optind, argv + 1 + optind); -#else - tcc_error_noabort("-run is not available in a cross compiler"); - ret = 1; -#endif - } else - if (s->output_type == TCC_OUTPUT_EXE || - s->output_type == TCC_OUTPUT_DLL) - { - ret = !!tcc_output_file(s, s->outfile); - if (s->gen_deps && !ret) - gen_makedeps(s, s->outfile, s->deps_outfile); - } - } - - if (s->do_bench) - tcc_print_stats(s, getclock_us() - start_time); - - tcc_delete(s); - return ret; -} diff --git a/external/TCC/tcc.h b/external/TCC/tcc.h deleted file mode 100644 index d891554f..00000000 --- a/external/TCC/tcc.h +++ /dev/null @@ -1,1540 +0,0 @@ -/* - * TCC - Tiny C Compiler - * - * Copyright (c) 2001-2004 Fabrice Bellard - * - * 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _TCC_H -#define _TCC_H - -#define _GNU_SOURCE -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* stat() */ - -#ifdef CONFIG_TCCASSERT -#include -#define TCC_ASSERT(ex) assert(ex) -#else -#define TCC_ASSERT(ex) -#endif - -#ifndef _WIN32 -# include -# include -# include -# include -# ifndef CONFIG_TCC_STATIC -# include -# endif -/* XXX: need to define this to use them in non ISOC99 context */ - extern float strtof (const char *__nptr, char **__endptr); - extern long double strtold (const char *__nptr, char **__endptr); -#else /* on _WIN32: */ -# include -# include -# include /* open, close etc. */ -# include /* getcwd */ -# ifdef __GNUC__ -# include -# endif -# define inline __inline -# define inp next_inp -# define snprintf _snprintf -# define vsnprintf _vsnprintf -# ifndef __GNUC__ -# define strtold (long double)strtod -# define strtof (float)strtod -# define strtoll _strtoi64 -# define strtoull _strtoui64 -# endif -# ifdef LIBTCC_AS_DLL -# define LIBTCCAPI __declspec(dllexport) -# define PUB_FUNC LIBTCCAPI -# endif -#endif - -#ifndef O_BINARY -# define O_BINARY 0 -#endif - -#ifdef __GNUC__ -# define NORETURN __attribute__ ((noreturn)) -#elif defined _MSC_VER -# define NORETURN __declspec(noreturn) -#else -# define NORETURN -#endif - -#ifdef _WIN32 -# define IS_DIRSEP(c) (c == '/' || c == '\\') -# define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2]))) -# define PATHCMP stricmp -#else -# define IS_DIRSEP(c) (c == '/') -# define IS_ABSPATH(p) IS_DIRSEP(p[0]) -# define PATHCMP strcmp -#endif - -#ifdef TCC_TARGET_PE -#define PATHSEP ';' -#else -#define PATHSEP ':' -#endif - -#include "elf.h" -#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) -# define ELFCLASSW ELFCLASS64 -# define ElfW(type) Elf##64##_##type -# define ELFW(type) ELF##64##_##type -# define ElfW_Rel ElfW(Rela) -# define SHT_RELX SHT_RELA -# define REL_SECTION_FMT ".rela%s" -/* XXX: DLL with PLT would only work with x86-64 for now */ -# define TCC_OUTPUT_DLL_WITH_PLT -#else -# define ELFCLASSW ELFCLASS32 -# define ElfW(type) Elf##32##_##type -# define ELFW(type) ELF##32##_##type -# define ElfW_Rel ElfW(Rel) -# define SHT_RELX SHT_REL -# define REL_SECTION_FMT ".rel%s" -#endif - -/* target address type */ -#define addr_t ElfW(Addr) - -#include "stab.h" -#include "libtcc.h" - -static inline uint16_t read16le(unsigned char *p) -{ - return p[0] | (uint16_t)p[1] << 8; -} - -static inline void write16le(unsigned char *p, uint16_t x) -{ - p[0] = x & 255; - p[1] = x >> 8 & 255; -} - -static inline uint32_t read32le(unsigned char *p) -{ - return (p[0] | (uint32_t)p[1] << 8 | - (uint32_t)p[2] << 16 | (uint32_t)p[3] << 24); -} - -static inline void write32le(unsigned char *p, uint32_t x) -{ - p[0] = x & 255; - p[1] = x >> 8 & 255; - p[2] = x >> 16 & 255; - p[3] = x >> 24 & 255; -} - -static inline uint64_t read64le(unsigned char *p) -{ - return (p[0] | (uint64_t)p[1] << 8 | - (uint64_t)p[2] << 16 | (uint64_t)p[3] << 24 | - (uint64_t)p[4] << 32 | (uint64_t)p[5] << 40 | - (uint64_t)p[6] << 48 | (uint64_t)p[7] << 56); -} - -static inline void write64le(unsigned char *p, uint64_t x) -{ - p[0] = x & 255; - p[1] = x >> 8 & 255; - p[2] = x >> 16 & 255; - p[3] = x >> 24 & 255; - p[4] = x >> 32 & 255; - p[5] = x >> 40 & 255; - p[6] = x >> 48 & 255; - p[7] = x >> 56 & 255; -} - -/* parser debug */ -/* #define PARSE_DEBUG */ -/* preprocessor debug */ -/* #define PP_DEBUG */ -/* include file debug */ -/* #define INC_DEBUG */ -/* memory leak debug */ -/* #define MEM_DEBUG */ -/* assembler debug */ -/* #define ASM_DEBUG */ - -/* target selection */ -/* #define TCC_TARGET_I386 *//* i386 code generator */ -/* #define TCC_TARGET_ARM *//* ARMv4 code generator */ -/* #define TCC_TARGET_ARM64 *//* ARMv8 code generator */ -/* #define TCC_TARGET_C67 *//* TMS320C67xx code generator */ -/* #define TCC_TARGET_X86_64 *//* x86-64 code generator */ - -/* default target is I386 */ -#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \ - !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_C67) && \ - !defined(TCC_TARGET_X86_64) -#define TCC_TARGET_I386 -#endif - -#if !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \ - !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_C67) && \ - !defined(CONFIG_USE_LIBGCC) -#define CONFIG_TCC_BCHECK /* enable bound checking code */ -#endif - -/* define it to include assembler support */ -#if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_ARM64) && \ - !defined(TCC_TARGET_C67) -#define CONFIG_TCC_ASM -#endif - -/* object format selection */ -#if defined(TCC_TARGET_C67) -#define TCC_TARGET_COFF -#endif - -/* only native compiler supports -run */ -#if defined _WIN32 == defined TCC_TARGET_PE -# if (defined __i386__ || defined _X86_) && defined TCC_TARGET_I386 -# define TCC_IS_NATIVE -# elif (defined __x86_64__ || defined _AMD64_) && defined TCC_TARGET_X86_64 -# define TCC_IS_NATIVE -# elif defined __arm__ && defined TCC_TARGET_ARM -# define TCC_IS_NATIVE -# elif defined __aarch64__ && defined TCC_TARGET_ARM64 -# define TCC_IS_NATIVE -# endif -#endif - -#if defined TCC_IS_NATIVE && !defined CONFIG_TCCBOOT -# define CONFIG_TCC_BACKTRACE -#endif - -/* ------------ path configuration ------------ */ - -#ifndef CONFIG_SYSROOT -# define CONFIG_SYSROOT "" -#endif -#ifndef CONFIG_TCCDIR -# define CONFIG_TCCDIR "." -#endif -#ifndef CONFIG_LDDIR -# ifdef TCC_TARGET_X86_64 -# define CONFIG_LDDIR "lib64" -# else -# define CONFIG_LDDIR "lib" -# endif -#endif - -#ifdef CONFIG_MULTIARCHDIR -# define USE_MUADIR(s) s "/" CONFIG_MULTIARCHDIR -# define ALSO_MUADIR(s) s "/" CONFIG_MULTIARCHDIR ":" s -#else -# define USE_MUADIR(s) s -# define ALSO_MUADIR(s) s -#endif - -/* path to find crt1.o, crti.o and crtn.o */ -#ifndef CONFIG_TCC_CRTPREFIX -# define CONFIG_TCC_CRTPREFIX USE_MUADIR(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR) -#endif - -/* Below: {B} is substituted by CONFIG_TCCDIR (rsp. -B option) */ - -/* system include paths */ -#ifndef CONFIG_TCC_SYSINCLUDEPATHS -# ifdef TCC_TARGET_PE -# define CONFIG_TCC_SYSINCLUDEPATHS "{B}/include;{B}/include/winapi" -# else -# define CONFIG_TCC_SYSINCLUDEPATHS \ - "{B}/include" \ - ":" ALSO_MUADIR(CONFIG_SYSROOT "/usr/local/include") \ - ":" ALSO_MUADIR(CONFIG_SYSROOT "/usr/include") -# endif -#endif - -/* library search paths */ -#ifndef CONFIG_TCC_LIBPATHS -# ifdef TCC_TARGET_PE -# define CONFIG_TCC_LIBPATHS "{B}/lib" -# else -# define CONFIG_TCC_LIBPATHS \ - ALSO_MUADIR(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR) \ - ":" ALSO_MUADIR(CONFIG_SYSROOT "/" CONFIG_LDDIR) \ - ":" ALSO_MUADIR(CONFIG_SYSROOT "/usr/local/" CONFIG_LDDIR) -# endif -#endif - -/* name of ELF interpreter */ -#ifndef CONFIG_TCC_ELFINTERP -# if defined __FreeBSD__ -# define CONFIG_TCC_ELFINTERP "/libexec/ld-elf.so.1" -# elif defined __FreeBSD_kernel__ -# if defined(TCC_TARGET_X86_64) -# define CONFIG_TCC_ELFINTERP "/lib/ld-kfreebsd-x86-64.so.1" -# else -# define CONFIG_TCC_ELFINTERP "/lib/ld.so.1" -# endif -# elif defined __DragonFly__ -# define CONFIG_TCC_ELFINTERP "/usr/libexec/ld-elf.so.2" -# elif defined __NetBSD__ -# define CONFIG_TCC_ELFINTERP "/usr/libexec/ld.elf_so" -# elif defined __GNU__ -# define CONFIG_TCC_ELFINTERP "/lib/ld.so" -# elif defined(TCC_TARGET_PE) -# define CONFIG_TCC_ELFINTERP "-" -# elif defined(TCC_UCLIBC) -# define CONFIG_TCC_ELFINTERP "/lib/ld-uClibc.so.0" /* is there a uClibc for x86_64 ? */ -# elif defined TCC_TARGET_ARM64 -# define CONFIG_TCC_ELFINTERP "/lib/ld-linux-aarch64.so.1" -# elif defined(TCC_TARGET_X86_64) -# define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2" -# elif !defined(TCC_ARM_EABI) -# define CONFIG_TCC_ELFINTERP "/lib/ld-linux.so.2" -# endif -#endif - -/* var elf_interp dans *-gen.c */ -#ifdef CONFIG_TCC_ELFINTERP -# define DEFAULT_ELFINTERP(s) CONFIG_TCC_ELFINTERP -#else -# define DEFAULT_ELFINTERP(s) default_elfinterp(s) -#endif - -/* library to use with CONFIG_USE_LIBGCC instead of libtcc1.a */ -#define TCC_LIBGCC USE_MUADIR(CONFIG_SYSROOT "/" CONFIG_LDDIR) "/libgcc_s.so.1" - -/* -------------------------------------------- */ -/* include the target specific definitions */ - -#define TARGET_DEFS_ONLY -#ifdef TCC_TARGET_I386 -# include "i386-gen.c" -#endif -#ifdef TCC_TARGET_X86_64 -# include "x86_64-gen.c" -#endif -#ifdef TCC_TARGET_ARM -# include "arm-gen.c" -#endif -#ifdef TCC_TARGET_ARM64 -# include "arm64-gen.c" -#endif -#ifdef TCC_TARGET_C67 -# include "coff.h" -# include "c67-gen.c" -#endif -#undef TARGET_DEFS_ONLY - -/* -------------------------------------------- */ - -#define INCLUDE_STACK_SIZE 32 -#define IFDEF_STACK_SIZE 64 -#define VSTACK_SIZE 256 -#define STRING_MAX_SIZE 1024 -#define PACK_STACK_SIZE 8 - -#define TOK_HASH_SIZE 8192 /* must be a power of two */ -#define TOK_ALLOC_INCR 512 /* must be a power of two */ -#define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */ - -/* token symbol management */ -typedef struct TokenSym { - struct TokenSym *hash_next; - struct Sym *sym_define; /* direct pointer to define */ - struct Sym *sym_label; /* direct pointer to label */ - struct Sym *sym_struct; /* direct pointer to structure */ - struct Sym *sym_identifier; /* direct pointer to identifier */ - int tok; /* token number */ - int len; - char str[1]; -} TokenSym; - -#ifdef TCC_TARGET_PE -typedef unsigned short nwchar_t; -#else -typedef int nwchar_t; -#endif - -typedef struct CString { - int size; /* size in bytes */ - void *data; /* either 'char *' or 'nwchar_t *' */ - int size_allocated; - void *data_allocated; /* if non NULL, data has been malloced */ -} CString; - -/* type definition */ -typedef struct CType { - int t; - struct Sym *ref; -} CType; - -/* constant value */ -typedef union CValue { - long double ld; - double d; - float f; - uint64_t i; - struct { - int size; - const void *data; - void *data_allocated; - } str; - int tab[LDOUBLE_SIZE/4]; -} CValue; - -/* value on stack */ -typedef struct SValue { - CType type; /* type */ - unsigned short r; /* register + flags */ - unsigned short r2; /* second register, used for 'long long' - type. If not used, set to VT_CONST */ - CValue c; /* constant, if VT_CONST */ - struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST) */ -} SValue; - -struct Attribute { - unsigned - func_call : 3, /* calling convention (0..5), see below */ - aligned : 5, /* alignement (0..16) */ - packed : 1, - func_export : 1, - func_import : 1, - func_args : 5, - func_proto : 1, - mode : 4, - weak : 1, - visibility : 2, - fill : 8; // 8 bits left to fit well in union below -}; - -/* GNUC attribute definition */ -typedef struct AttributeDef { - struct Attribute a; - struct Section *section; - int alias_target; /* token */ - int asm_label; /* associated asm label */ -} AttributeDef; - -/* symbol management */ -typedef struct Sym { - int v; /* symbol token */ - int asm_label; /* associated asm label */ - union { - long r; /* associated register */ - struct Attribute a; - }; - union { - long c; /* associated number */ - int *d; /* define token stream */ - }; - CType type; /* associated type */ - union { - struct Sym *next; /* next related symbol */ - long jnext; /* next jump label */ - }; - struct Sym *prev; /* prev symbol in stack */ - struct Sym *prev_tok; /* previous symbol for this token */ -} Sym; - -/* section definition */ -/* XXX: use directly ELF structure for parameters ? */ -/* special flag to indicate that the section should not be linked to - the other ones */ -#define SHF_PRIVATE 0x80000000 - -/* special flag, too */ -#define SECTION_ABS ((void *)1) - -typedef struct Section { - unsigned long data_offset; /* current data offset */ - unsigned char *data; /* section data */ - unsigned long data_allocated; /* used for realloc() handling */ - int sh_name; /* elf section name (only used during output) */ - int sh_num; /* elf section number */ - int sh_type; /* elf section type */ - int sh_flags; /* elf section flags */ - int sh_info; /* elf section info */ - int sh_addralign; /* elf section alignment */ - int sh_entsize; /* elf entry size */ - unsigned long sh_size; /* section size (only used during output) */ - addr_t sh_addr; /* address at which the section is relocated */ - unsigned long sh_offset; /* file offset */ - int nb_hashed_syms; /* used to resize the hash table */ - struct Section *link; /* link to another section */ - struct Section *reloc; /* corresponding section for relocation, if any */ - struct Section *hash; /* hash table for symbols */ - struct Section *next; - char name[1]; /* section name */ -} Section; - -typedef struct DLLReference { - int level; - void *handle; - char name[1]; -} DLLReference; - -/* -------------------------------------------------- */ - -#define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */ -#define SYM_FIELD 0x20000000 /* struct/union field symbol space */ -#define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */ - -/* stored in 'Sym.c' field */ -#define FUNC_NEW 1 /* ansi function prototype */ -#define FUNC_OLD 2 /* old function prototype */ -#define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */ - -/* stored in 'Sym.r' field */ -#define FUNC_CDECL 0 /* standard c call */ -#define FUNC_STDCALL 1 /* pascal c call */ -#define FUNC_FASTCALL1 2 /* first param in %eax */ -#define FUNC_FASTCALL2 3 /* first parameters in %eax, %edx */ -#define FUNC_FASTCALL3 4 /* first parameter in %eax, %edx, %ecx */ -#define FUNC_FASTCALLW 5 /* first parameter in %ecx, %edx */ - -/* field 'Sym.t' for macros */ -#define MACRO_OBJ 0 /* object like macro */ -#define MACRO_FUNC 1 /* function like macro */ - -/* field 'Sym.r' for C labels */ -#define LABEL_DEFINED 0 /* label is defined */ -#define LABEL_FORWARD 1 /* label is forward defined */ -#define LABEL_DECLARED 2 /* label is declared but never used */ - -/* type_decl() types */ -#define TYPE_ABSTRACT 1 /* type without variable */ -#define TYPE_DIRECT 2 /* type with variable */ - -#define IO_BUF_SIZE 8192 - -typedef struct BufferedFile { - uint8_t *buf_ptr; - uint8_t *buf_end; - int fd; - struct BufferedFile *prev; - int line_num; /* current line number - here to simplify code */ - int line_ref; /* tcc -E: last printed line */ - int ifndef_macro; /* #ifndef macro / #endif search */ - int ifndef_macro_saved; /* saved ifndef_macro */ - int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */ - int include_next_index; /* next search path */ - char filename[1024]; /* filename */ - unsigned char unget[4]; - unsigned char buffer[1]; /* extra size for CH_EOB char */ -} BufferedFile; - -#define CH_EOB '\\' /* end of buffer or '\0' char in file */ -#define CH_EOF (-1) /* end of file */ - -/* parsing state (used to save parser state to reparse part of the - source several times) */ -typedef struct ParseState { - const int *macro_ptr; - int line_num; - int tok; - CValue tokc; -} ParseState; - -/* used to record tokens */ -typedef struct TokenString { - int *str; - int len; - int allocated_len; - int last_line_num; - /* used to chain token-strings with begin/end_macro() */ - struct TokenString *prev; - const int *prev_ptr; - char alloc; -} TokenString; - -/* inline functions */ -typedef struct InlineFunc { - TokenString func_str; - Sym *sym; - char filename[1]; -} InlineFunc; - -/* include file cache, used to find files faster and also to eliminate - inclusion if the include file is protected by #ifndef ... #endif */ -typedef struct CachedInclude { - int ifndef_macro; - int hash_next; /* -1 if none */ - char filename[1]; /* path specified in #include */ -} CachedInclude; - -#define CACHED_INCLUDES_HASH_SIZE 512 - -#ifdef CONFIG_TCC_ASM -typedef struct ExprValue { - uint32_t v; - Sym *sym; -} ExprValue; - -#define MAX_ASM_OPERANDS 30 -typedef struct ASMOperand { - int id; /* GCC 3 optionnal identifier (0 if number only supported */ - char *constraint; - char asm_str[16]; /* computed asm string for operand */ - SValue *vt; /* C value of the expression */ - int ref_index; /* if >= 0, gives reference to a output constraint */ - int input_index; /* if >= 0, gives reference to an input constraint */ - int priority; /* priority, used to assign registers */ - int reg; /* if >= 0, register number used for this operand */ - int is_llong; /* true if double register value */ - int is_memory; /* true if memory operand */ - int is_rw; /* for '+' modifier */ -} ASMOperand; -#endif - -struct sym_attr { - unsigned long got_offset; - unsigned long plt_offset; -#ifdef TCC_TARGET_ARM - unsigned char plt_thumb_stub:1; -#endif -}; - -struct TCCState { - - int verbose; /* if true, display some information during compilation */ - int nostdinc; /* if true, no standard headers are added */ - int nostdlib; /* if true, no standard libraries are added */ - int nocommon; /* if true, do not use common symbols for .bss data */ - int static_link; /* if true, static linking is performed */ - int rdynamic; /* if true, all symbols are exported */ - int symbolic; /* if true, resolve symbols in the current module first */ - int alacarte_link; /* if true, only link in referenced objects from archive */ - - char *tcc_lib_path; /* CONFIG_TCCDIR or -B option */ - char *soname; /* as specified on the command line (-soname) */ - char *rpath; /* as specified on the command line (-Wl,-rpath=) */ - - /* output type, see TCC_OUTPUT_XXX */ - int output_type; - /* output format, see TCC_OUTPUT_FORMAT_xxx */ - int output_format; - - /* C language options */ - int char_is_unsigned; - int leading_underscore; - int ms_extensions; /* allow nested named struct w/o identifier behave like unnamed */ - int old_struct_init_code; /* use old algorithm to init array in struct when there is no '{' used. - Liuux 2.4.26 can't find initrd when compiled with a new algorithm */ - int dollars_in_identifiers; /* allows '$' char in indentifiers */ - - /* warning switches */ - int warn_write_strings; - int warn_unsupported; - int warn_error; - int warn_none; - int warn_implicit_function_declaration; - - /* compile with debug symbol (and use them if error during execution) */ - int do_debug; - int do_strip; -#ifdef CONFIG_TCC_BCHECK - /* compile with built-in memory and bounds checker */ - int do_bounds_check; -#endif -#ifdef TCC_TARGET_ARM - enum float_abi float_abi; /* float ABI of the generated code*/ -#endif - - addr_t text_addr; /* address of text section */ - int has_text_addr; - - unsigned long section_align; /* section alignment */ - - char *init_symbol; /* symbols to call at load-time (not used currently) */ - char *fini_symbol; /* symbols to call at unload-time (not used currently) */ - -#ifdef TCC_TARGET_I386 - int seg_size; /* 32. Can be 16 with i386 assembler (.code16) */ -#endif - - /* array of all loaded dlls (including those referenced by loaded dlls) */ - DLLReference **loaded_dlls; - int nb_loaded_dlls; - - /* include paths */ - char **include_paths; - int nb_include_paths; - - char **sysinclude_paths; - int nb_sysinclude_paths; - - /* library paths */ - char **library_paths; - int nb_library_paths; - - /* crt?.o object path */ - char **crt_paths; - int nb_crt_paths; - - /* error handling */ - void *error_opaque; - void (*error_func)(void *opaque, const char *msg); - int error_set_jmp_enabled; - jmp_buf error_jmp_buf; - int nb_errors; - - /* output file for preprocessing (-E) */ - FILE *ppfp; - enum { - LINE_MACRO_OUTPUT_FORMAT_GCC, - LINE_MACRO_OUTPUT_FORMAT_NONE, - LINE_MACRO_OUTPUT_FORMAT_STD - } Pflag; /* -P switch */ - int dflag; /* -dX value */ - - /* for -MD/-MF: collected dependencies for this compilation */ - char **target_deps; - int nb_target_deps; - - /* compilation */ - BufferedFile *include_stack[INCLUDE_STACK_SIZE]; - BufferedFile **include_stack_ptr; - - int ifdef_stack[IFDEF_STACK_SIZE]; - int *ifdef_stack_ptr; - - /* included files enclosed with #ifndef MACRO */ - int cached_includes_hash[CACHED_INCLUDES_HASH_SIZE]; - CachedInclude **cached_includes; - int nb_cached_includes; - - /* #pragma pack stack */ - int pack_stack[PACK_STACK_SIZE]; - int *pack_stack_ptr; - char **pragma_libs; - int nb_pragma_libs; - - /* inline functions are stored as token lists and compiled last - only if referenced */ - struct InlineFunc **inline_fns; - int nb_inline_fns; - - /* sections */ - Section **sections; - int nb_sections; /* number of sections, including first dummy section */ - - Section **priv_sections; - int nb_priv_sections; /* number of private sections */ - - /* got & plt handling */ - Section *got; - Section *plt; - struct sym_attr *sym_attrs; - int nb_sym_attrs; - /* give the correspondance from symtab indexes to dynsym indexes */ - int *symtab_to_dynsym; - - /* temporary dynamic symbol sections (for dll loading) */ - Section *dynsymtab_section; - /* exported dynamic symbol section */ - Section *dynsym; - /* copy of the gobal symtab_section variable */ - Section *symtab; - /* tiny assembler state */ - Sym *asm_labels; - -#ifdef TCC_TARGET_PE - /* PE info */ - int pe_subsystem; - unsigned pe_file_align; - unsigned pe_stack_size; -# ifdef TCC_TARGET_X86_64 - Section *uw_pdata; - int uw_sym; - unsigned uw_offs; -# endif -#endif - -#ifdef TCC_IS_NATIVE - const char *runtime_main; - /* for tcc_relocate */ - void *runtime_mem; -# ifdef HAVE_SELINUX - void *write_mem; - unsigned long mem_size; -# endif -#endif - - /* used by main and tcc_parse_args only */ - char **files; /* files seen on command line */ - int nb_files; /* number thereof */ - int nb_libraries; /* number of libs thereof */ - char *outfile; /* output filename */ - char *option_m; /* only -m32/-m64 handled */ - int print_search_dirs; /* option */ - int option_r; /* option -r */ - int do_bench; /* option -bench */ - int gen_deps; /* option -MD */ - char *deps_outfile; /* option -MF */ -}; - -/* The current value can be: */ -#define VT_VALMASK 0x003f /* mask for value location, register or: */ -#define VT_CONST 0x0030 /* constant in vc (must be first non register value) */ -#define VT_LLOCAL 0x0031 /* lvalue, offset on stack */ -#define VT_LOCAL 0x0032 /* offset on stack */ -#define VT_CMP 0x0033 /* the value is stored in processor flags (in vc) */ -#define VT_JMP 0x0034 /* value is the consequence of jmp true (even) */ -#define VT_JMPI 0x0035 /* value is the consequence of jmp false (odd) */ -#define VT_REF 0x0040 /* value is pointer to structure rather than address */ -#define VT_LVAL 0x0100 /* var is an lvalue */ -#define VT_SYM 0x0200 /* a symbol value is added */ -#define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for - char/short stored in integer registers) */ -#define VT_MUSTBOUND 0x0800 /* bound checking must be done before - dereferencing value */ -#define VT_BOUNDED 0x8000 /* value is bounded. The address of the - bounding function call point is in vc */ -#define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */ -#define VT_LVAL_SHORT 0x2000 /* lvalue is a short */ -#define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */ -#define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED) - -/* types */ -#define VT_BTYPE 0x000f /* mask for basic type */ -#define VT_INT 0 /* integer type */ -#define VT_BYTE 1 /* signed byte type */ -#define VT_SHORT 2 /* short type */ -#define VT_VOID 3 /* void type */ -#define VT_PTR 4 /* pointer */ -#define VT_ENUM 5 /* enum definition */ -#define VT_FUNC 6 /* function type */ -#define VT_STRUCT 7 /* struct/union definition */ -#define VT_FLOAT 8 /* IEEE float */ -#define VT_DOUBLE 9 /* IEEE double */ -#define VT_LDOUBLE 10 /* IEEE long double */ -#define VT_BOOL 11 /* ISOC99 boolean type */ -#define VT_LLONG 12 /* 64 bit integer */ -#define VT_LONG 13 /* long integer (NEVER USED as type, only - during parsing) */ -#define VT_QLONG 14 /* 128-bit integer. Only used for x86-64 ABI */ -#define VT_QFLOAT 15 /* 128-bit float. Only used for x86-64 ABI */ -#define VT_UNSIGNED 0x0010 /* unsigned type */ -#define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */ -#define VT_BITFIELD 0x0040 /* bitfield modifier */ -#define VT_CONSTANT 0x0800 /* const modifier */ -#define VT_VOLATILE 0x1000 /* volatile modifier */ -#define VT_DEFSIGN 0x2000 /* signed type */ -#define VT_VLA 0x00020000 /* VLA type (also has VT_PTR and VT_ARRAY) */ - -/* storage */ -#define VT_EXTERN 0x00000080 /* extern definition */ -#define VT_STATIC 0x00000100 /* static variable */ -#define VT_TYPEDEF 0x00000200 /* typedef definition */ -#define VT_INLINE 0x00000400 /* inline definition */ -#define VT_IMPORT 0x00004000 /* win32: extern data imported from dll */ -#define VT_EXPORT 0x00008000 /* win32: data exported from dll */ -#define VT_WEAK 0x00010000 /* weak symbol */ -#define VT_TLS 0x00040000 /* thread-local storage */ -#define VT_VIS_SHIFT 19 /* shift for symbol visibility, overlapping - bitfield values, because bitfields never - have linkage and hence never have - visibility. */ -#define VT_VIS_SIZE 2 /* We have four visibilities. */ -#define VT_VIS_MASK (((1 << VT_VIS_SIZE)-1) << VT_VIS_SHIFT) - -#define VT_STRUCT_SHIFT 19 /* shift for bitfield shift values (max: 32 - 2*6) */ - - -/* type mask (except storage) */ -#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE | VT_IMPORT | VT_EXPORT | VT_WEAK | VT_VIS_MASK) -#define VT_TYPE (~(VT_STORAGE)) - -/* token values */ - -/* warning: the following compare tokens depend on i386 asm code */ -#define TOK_ULT 0x92 -#define TOK_UGE 0x93 -#define TOK_EQ 0x94 -#define TOK_NE 0x95 -#define TOK_ULE 0x96 -#define TOK_UGT 0x97 -#define TOK_Nset 0x98 -#define TOK_Nclear 0x99 -#define TOK_LT 0x9c -#define TOK_GE 0x9d -#define TOK_LE 0x9e -#define TOK_GT 0x9f - -#define TOK_LAND 0xa0 -#define TOK_LOR 0xa1 -#define TOK_DEC 0xa2 -#define TOK_MID 0xa3 /* inc/dec, to void constant */ -#define TOK_INC 0xa4 -#define TOK_UDIV 0xb0 /* unsigned division */ -#define TOK_UMOD 0xb1 /* unsigned modulo */ -#define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */ - -/* tokens that carry values (in additional token string space / tokc) --> */ -#define TOK_CCHAR 0xb3 /* char constant in tokc */ -#define TOK_LCHAR 0xb4 -#define TOK_CINT 0xb5 /* number in tokc */ -#define TOK_CUINT 0xb6 /* unsigned int constant */ -#define TOK_CLLONG 0xb7 /* long long constant */ -#define TOK_CULLONG 0xb8 /* unsigned long long constant */ -#define TOK_STR 0xb9 /* pointer to string in tokc */ -#define TOK_LSTR 0xba -#define TOK_CFLOAT 0xbb /* float constant */ -#define TOK_CDOUBLE 0xbc /* double constant */ -#define TOK_CLDOUBLE 0xbd /* long double constant */ -#define TOK_PPNUM 0xbe /* preprocessor number */ -#define TOK_PPSTR 0xbf /* preprocessor string */ -#define TOK_LINENUM 0xc0 /* line number info */ -/* <-- */ - -#define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */ -#define TOK_ADDC1 0xc3 /* add with carry generation */ -#define TOK_ADDC2 0xc4 /* add with carry use */ -#define TOK_SUBC1 0xc5 /* add with carry generation */ -#define TOK_SUBC2 0xc6 /* add with carry use */ -#define TOK_ARROW 0xc7 -#define TOK_DOTS 0xc8 /* three dots */ -#define TOK_SHR 0xc9 /* unsigned shift right */ -#define TOK_TWOSHARPS 0xca /* ## preprocessing token */ -#define TOK_PLCHLDR 0xcb /* placeholder token as defined in C99 */ -#define TOK_NOSUBST 0xcc /* means following token has already been pp'd */ - -#define TOK_SHL 0x01 /* shift left */ -#define TOK_SAR 0x02 /* signed shift right */ - -/* assignement operators : normal operator or 0x80 */ -#define TOK_A_MOD 0xa5 -#define TOK_A_AND 0xa6 -#define TOK_A_MUL 0xaa -#define TOK_A_ADD 0xab -#define TOK_A_SUB 0xad -#define TOK_A_DIV 0xaf -#define TOK_A_XOR 0xde -#define TOK_A_OR 0xfc -#define TOK_A_SHL 0x81 -#define TOK_A_SAR 0x82 - -#ifndef offsetof -#define offsetof(type, field) ((size_t) &((type *)0)->field) -#endif - -#ifndef countof -#define countof(tab) (sizeof(tab) / sizeof((tab)[0])) -#endif - -#define TOK_EOF (-1) /* end of file */ -#define TOK_LINEFEED 10 /* line feed */ - -/* all identificators and strings have token above that */ -#define TOK_IDENT 256 - -#define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x) -#define TOK_ASM_int TOK_INT -#define DEF_ASMDIR(x) DEF(TOK_ASMDIR_ ## x, "." #x) -#define TOK_ASMDIR_FIRST TOK_ASMDIR_byte -#define TOK_ASMDIR_LAST TOK_ASMDIR_section - -#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 -/* only used for i386 asm opcodes definitions */ -#define DEF_BWL(x) \ - DEF(TOK_ASM_ ## x ## b, #x "b") \ - DEF(TOK_ASM_ ## x ## w, #x "w") \ - DEF(TOK_ASM_ ## x ## l, #x "l") \ - DEF(TOK_ASM_ ## x, #x) -#define DEF_WL(x) \ - DEF(TOK_ASM_ ## x ## w, #x "w") \ - DEF(TOK_ASM_ ## x ## l, #x "l") \ - DEF(TOK_ASM_ ## x, #x) -#ifdef TCC_TARGET_X86_64 -# define DEF_BWLQ(x) \ - DEF(TOK_ASM_ ## x ## b, #x "b") \ - DEF(TOK_ASM_ ## x ## w, #x "w") \ - DEF(TOK_ASM_ ## x ## l, #x "l") \ - DEF(TOK_ASM_ ## x ## q, #x "q") \ - DEF(TOK_ASM_ ## x, #x) -# define DEF_WLQ(x) \ - DEF(TOK_ASM_ ## x ## w, #x "w") \ - DEF(TOK_ASM_ ## x ## l, #x "l") \ - DEF(TOK_ASM_ ## x ## q, #x "q") \ - DEF(TOK_ASM_ ## x, #x) -# define DEF_BWLX DEF_BWLQ -# define DEF_WLX DEF_WLQ -/* number of sizes + 1 */ -# define NBWLX 5 -#else -# define DEF_BWLX DEF_BWL -# define DEF_WLX DEF_WL -/* number of sizes + 1 */ -# define NBWLX 4 -#endif - -#define DEF_FP1(x) \ - DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \ - DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \ - DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \ - DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s") - -#define DEF_FP(x) \ - DEF(TOK_ASM_ ## f ## x, "f" #x ) \ - DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \ - DEF_FP1(x) - -#define DEF_ASMTEST(x,suffix) \ - DEF_ASM(x ## o ## suffix) \ - DEF_ASM(x ## no ## suffix) \ - DEF_ASM(x ## b ## suffix) \ - DEF_ASM(x ## c ## suffix) \ - DEF_ASM(x ## nae ## suffix) \ - DEF_ASM(x ## nb ## suffix) \ - DEF_ASM(x ## nc ## suffix) \ - DEF_ASM(x ## ae ## suffix) \ - DEF_ASM(x ## e ## suffix) \ - DEF_ASM(x ## z ## suffix) \ - DEF_ASM(x ## ne ## suffix) \ - DEF_ASM(x ## nz ## suffix) \ - DEF_ASM(x ## be ## suffix) \ - DEF_ASM(x ## na ## suffix) \ - DEF_ASM(x ## nbe ## suffix) \ - DEF_ASM(x ## a ## suffix) \ - DEF_ASM(x ## s ## suffix) \ - DEF_ASM(x ## ns ## suffix) \ - DEF_ASM(x ## p ## suffix) \ - DEF_ASM(x ## pe ## suffix) \ - DEF_ASM(x ## np ## suffix) \ - DEF_ASM(x ## po ## suffix) \ - DEF_ASM(x ## l ## suffix) \ - DEF_ASM(x ## nge ## suffix) \ - DEF_ASM(x ## nl ## suffix) \ - DEF_ASM(x ## ge ## suffix) \ - DEF_ASM(x ## le ## suffix) \ - DEF_ASM(x ## ng ## suffix) \ - DEF_ASM(x ## nle ## suffix) \ - DEF_ASM(x ## g ## suffix) - -#endif /* defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 */ - -enum tcc_token { - TOK_LAST = TOK_IDENT - 1 -#define DEF(id, str) ,id -#include "tcctok.h" -#undef DEF -}; - -#define TOK_UIDENT TOK_DEFINE - -/* space exlcuding newline */ -static inline int is_space(int ch) -{ - return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r'; -} - -static inline int isid(int c) -{ - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'; -} - -static inline int isnum(int c) -{ - return c >= '0' && c <= '9'; -} - -static inline int isoct(int c) -{ - return c >= '0' && c <= '7'; -} - -static inline int toup(int c) -{ - return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; -} - -#ifndef PUB_FUNC -# define PUB_FUNC -#endif - -#ifdef ONE_SOURCE -#define ST_INLN static inline -#define ST_FUNC static -#define ST_DATA static -#else -#define ST_INLN -#define ST_FUNC -#define ST_DATA extern -#endif - -/* ------------ libtcc.c ------------ */ - -/* use GNU C extensions */ -ST_DATA int gnu_ext; -/* use Tiny C extensions */ -ST_DATA int tcc_ext; -/* XXX: get rid of this ASAP */ -ST_DATA struct TCCState *tcc_state; - -#define AFF_PRINT_ERROR 0x0001 /* print error if file not found */ -#define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */ -#define AFF_PREPROCESS 0x0004 /* preprocess file */ - -/* public functions currently used by the tcc main function */ -PUB_FUNC char *pstrcpy(char *buf, int buf_size, const char *s); -PUB_FUNC char *pstrcat(char *buf, int buf_size, const char *s); -PUB_FUNC char *pstrncpy(char *out, const char *in, size_t num); -PUB_FUNC char *tcc_basename(const char *name); -PUB_FUNC char *tcc_fileextension (const char *name); - -#ifndef MEM_DEBUG -PUB_FUNC void tcc_free(void *ptr); -PUB_FUNC void *tcc_malloc(unsigned long size); -PUB_FUNC void *tcc_mallocz(unsigned long size); -PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size); -PUB_FUNC char *tcc_strdup(const char *str); -#else -#define tcc_free(ptr) tcc_free_debug(ptr) -#define tcc_malloc(size) tcc_malloc_debug(size, __FILE__, __LINE__) -#define tcc_mallocz(size) tcc_mallocz_debug(size, __FILE__, __LINE__) -#define tcc_realloc(ptr,size) tcc_realloc_debug(ptr, size, __FILE__, __LINE__) -#define tcc_strdup(str) tcc_strdup_debug(str, __FILE__, __LINE__) -PUB_FUNC void tcc_free_debug(void *ptr); -PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line); -PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line); -PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line); -PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line); -#endif - -#define free(p) use_tcc_free(p) -#define malloc(s) use_tcc_malloc(s) -#define realloc(p, s) use_tcc_realloc(p, s) -#undef strdup -#define strdup(s) use_tcc_strdup(s) -PUB_FUNC void tcc_memstats(int bench); -PUB_FUNC void tcc_error_noabort(const char *fmt, ...); -PUB_FUNC NORETURN void tcc_error(const char *fmt, ...); -PUB_FUNC void tcc_warning(const char *fmt, ...); - -/* other utilities */ -ST_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data); -ST_FUNC void dynarray_reset(void *pp, int *n); -ST_FUNC void cstr_ccat(CString *cstr, int ch); -ST_FUNC void cstr_cat(CString *cstr, const char *str); -ST_FUNC void cstr_wccat(CString *cstr, int ch); -ST_FUNC void cstr_new(CString *cstr); -ST_FUNC void cstr_free(CString *cstr); -ST_FUNC void cstr_reset(CString *cstr); - -ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags); -ST_FUNC void section_realloc(Section *sec, unsigned long new_size); -ST_FUNC void *section_ptr_add(Section *sec, addr_t size); -ST_FUNC void section_reserve(Section *sec, unsigned long size); -ST_FUNC Section *find_section(TCCState *s1, const char *name); - -ST_FUNC void put_extern_sym2(Sym *sym, Section *section, addr_t value, unsigned long size, int can_add_underscore); -ST_FUNC void put_extern_sym(Sym *sym, Section *section, addr_t value, unsigned long size); -ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type); -ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, addr_t addend); - -ST_INLN void sym_free(Sym *sym); -ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c); -ST_FUNC Sym *sym_find2(Sym *s, int v); -ST_FUNC Sym *sym_push(int v, CType *type, int r, int c); -ST_FUNC void sym_pop(Sym **ptop, Sym *b); -ST_INLN Sym *struct_find(int v); -ST_INLN Sym *sym_find(int v); -ST_FUNC Sym *global_identifier_push(int v, int t, int c); - -ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen); -ST_FUNC int tcc_open(TCCState *s1, const char *filename); -ST_FUNC void tcc_close(void); - -ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags, int filetype); -ST_FUNC int tcc_add_crt(TCCState *s, const char *filename); - -#ifndef TCC_TARGET_PE -ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags); -#endif - -ST_FUNC void tcc_add_pragma_libs(TCCState *s1); -PUB_FUNC int tcc_add_library_err(TCCState *s, const char *f); - -PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time); -PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv); -PUB_FUNC void tcc_set_environment(TCCState *s); - -/* ------------ tccpp.c ------------ */ - -ST_DATA struct BufferedFile *file; -ST_DATA int ch, tok; -ST_DATA CValue tokc; -ST_DATA const int *macro_ptr; -ST_DATA int parse_flags; -ST_DATA int tok_flags; -ST_DATA CString tokcstr; /* current parsed string, if any */ - -/* display benchmark infos */ -ST_DATA int total_lines; -ST_DATA int total_bytes; -ST_DATA int tok_ident; -ST_DATA TokenSym **table_ident; - -#define TOK_FLAG_BOL 0x0001 /* beginning of line before */ -#define TOK_FLAG_BOF 0x0002 /* beginning of file before */ -#define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */ -#define TOK_FLAG_EOF 0x0008 /* end of file */ - -#define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */ -#define PARSE_FLAG_TOK_NUM 0x0002 /* return numbers instead of TOK_PPNUM */ -#define PARSE_FLAG_LINEFEED 0x0004 /* line feed is returned as a - token. line feed is also - returned at eof */ -#define PARSE_FLAG_ASM_FILE 0x0008 /* we processing an asm file: '#' can be used for line comment, etc. */ -#define PARSE_FLAG_SPACES 0x0010 /* next() returns space tokens (for -E) */ -#define PARSE_FLAG_ACCEPT_STRAYS 0x0020 /* next() returns '\\' token */ -#define PARSE_FLAG_TOK_STR 0x0040 /* return parsed strings instead of TOK_PPSTR */ - -ST_FUNC TokenSym *tok_alloc(const char *str, int len); -ST_FUNC const char *get_tok_str(int v, CValue *cv); -ST_FUNC void begin_macro(TokenString *str, int alloc); -ST_FUNC void end_macro(void); -ST_FUNC void save_parse_state(ParseState *s); -ST_FUNC void restore_parse_state(ParseState *s); -ST_INLN void tok_str_new(TokenString *s); -ST_FUNC void tok_str_free(int *str); -ST_FUNC void tok_str_add(TokenString *s, int t); -ST_FUNC void tok_str_add_tok(TokenString *s); -ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg); -ST_FUNC void define_undef(Sym *s); -ST_INLN Sym *define_find(int v); -ST_FUNC void free_defines(Sym *b); -ST_FUNC void print_defines(void); -ST_FUNC Sym *label_find(int v); -ST_FUNC Sym *label_push(Sym **ptop, int v, int flags); -ST_FUNC void label_pop(Sym **ptop, Sym *slast); -ST_FUNC void parse_define(void); -ST_FUNC void preprocess(int is_bof); -ST_FUNC void next_nomacro(void); -ST_FUNC void next(void); -ST_INLN void unget_tok(int last_tok); -ST_FUNC void preprocess_init(TCCState *s1); -ST_FUNC void preprocess_new(void); -ST_FUNC void preprocess_delete(void); -ST_FUNC int tcc_preprocess(TCCState *s1); -ST_FUNC void skip(int c); -ST_FUNC NORETURN void expect(const char *msg); - -/* ------------ tccgen.c ------------ */ - -ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */ -ST_DATA Section *cur_text_section; /* current section where function code is generated */ -#ifdef CONFIG_TCC_ASM -ST_DATA Section *last_text_section; /* to handle .previous asm directive */ -#endif -#ifdef CONFIG_TCC_BCHECK -/* bound check related sections */ -ST_DATA Section *bounds_section; /* contains global data bound description */ -ST_DATA Section *lbounds_section; /* contains local data bound description */ -#endif -/* symbol sections */ -ST_DATA Section *symtab_section, *strtab_section; -/* debug sections */ -ST_DATA Section *stab_section, *stabstr_section; - -#define SYM_POOL_NB (8192 / sizeof(Sym)) -ST_DATA Sym *sym_free_first; -ST_DATA void **sym_pools; -ST_DATA int nb_sym_pools; - -ST_DATA Sym *global_stack; -ST_DATA Sym *local_stack; -ST_DATA Sym *local_label_stack; -ST_DATA Sym *global_label_stack; -ST_DATA Sym *define_stack; -ST_DATA CType char_pointer_type, func_old_type, int_type, size_type; -ST_DATA SValue __vstack[1+/*to make bcheck happy*/ VSTACK_SIZE], *vtop, *pvtop; -#define vstack (__vstack + 1) -ST_DATA int rsym, anon_sym, ind, loc; - -ST_DATA int const_wanted; /* true if constant wanted */ -ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */ -ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */ -ST_DATA CType func_vt; /* current function return type (used by return instruction) */ -ST_DATA int func_var; /* true if current function is variadic */ -ST_DATA int func_vc; -ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */ -ST_DATA const char *funcname; - -ST_FUNC void check_vstack(void); -ST_INLN int is_float(int t); -ST_FUNC int ieee_finite(double d); -ST_FUNC void test_lvalue(void); -ST_FUNC void swap(int *p, int *q); -ST_FUNC void vpushi(int v); -ST_FUNC Sym *external_global_sym(int v, CType *type, int r); -ST_FUNC void vset(CType *type, int r, int v); -ST_FUNC void vswap(void); -ST_FUNC void vpush_global_sym(CType *type, int v); -ST_FUNC void vrote(SValue *e, int n); -ST_FUNC void vrott(int n); -ST_FUNC void vrotb(int n); -#ifdef TCC_TARGET_ARM -ST_FUNC int get_reg_ex(int rc, int rc2); -ST_FUNC void lexpand_nr(void); -#endif -ST_FUNC void vpushv(SValue *v); -ST_FUNC void save_reg(int r); -ST_FUNC int get_reg(int rc); -ST_FUNC void save_regs(int n); -ST_FUNC void gaddrof(void); -ST_FUNC int gv(int rc); -ST_FUNC void gv2(int rc1, int rc2); -ST_FUNC void vpop(void); -ST_FUNC void gen_op(int op); -ST_FUNC int type_size(CType *type, int *a); -ST_FUNC void mk_pointer(CType *type); -ST_FUNC void vstore(void); -ST_FUNC void inc(int post, int c); -ST_FUNC void parse_asm_str(CString *astr); -ST_FUNC int lvalue_type(int t); -ST_FUNC void indir(void); -ST_FUNC void unary(void); -ST_FUNC void expr_prod(void); -ST_FUNC void expr_sum(void); -ST_FUNC void gexpr(void); -ST_FUNC int expr_const(void); -ST_FUNC void gen_inline_functions(void); -ST_FUNC void decl(int l); -#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67 -ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size); -#endif -#if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE -ST_FUNC int classify_x86_64_va_arg(CType *ty); -#endif - -/* ------------ tccelf.c ------------ */ - -#define TCC_OUTPUT_FORMAT_ELF 0 /* default output format: ELF */ -#define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */ -#define TCC_OUTPUT_FORMAT_COFF 2 /* COFF */ - -#define ARMAG "!\012" /* For COFF and a.out archives */ - -typedef struct { - unsigned int n_strx; /* index into string table of name */ - unsigned char n_type; /* type of symbol */ - unsigned char n_other; /* misc info (usually empty) */ - unsigned short n_desc; /* description field */ - unsigned int n_value; /* value of symbol */ -} Stab_Sym; - -ST_FUNC Section *new_symtab(TCCState *s1, const char *symtab_name, int sh_type, int sh_flags, const char *strtab_name, const char *hash_name, int hash_sh_flags); - -ST_FUNC int put_elf_str(Section *s, const char *sym); -ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name); -ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int sh_num, const char *name); -ST_FUNC int find_elf_sym(Section *s, const char *name); -ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol); -ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, int type, int symbol, addr_t addend); - -ST_FUNC void put_stabs(const char *str, int type, int other, int desc, unsigned long value); -ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc, unsigned long value, Section *sec, int sym_index); -ST_FUNC void put_stabn(int type, int other, int desc, int value); -ST_FUNC void put_stabd(int type, int other, int desc); - -ST_FUNC void relocate_common_syms(void); -ST_FUNC void relocate_syms(TCCState *s1, int do_resolve); -ST_FUNC void relocate_section(TCCState *s1, Section *s); -ST_FUNC void relocate_plt(TCCState *s1); - -ST_FUNC void tcc_add_linker_symbols(TCCState *s1); -ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset); -ST_FUNC int tcc_load_archive(TCCState *s1, int fd); -ST_FUNC void tcc_add_bcheck(TCCState *s1); - -ST_FUNC void build_got_entries(TCCState *s1); -ST_FUNC void tcc_add_runtime(TCCState *s1); - -ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err); -#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE -ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name); -#endif - -#ifndef TCC_TARGET_PE -ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level); -ST_FUNC int tcc_load_ldscript(TCCState *s1); -ST_FUNC uint8_t *parse_comment(uint8_t *p); -ST_FUNC void minp(void); -ST_INLN void inp(void); -ST_FUNC int handle_eob(void); -#endif - -/* ------------ xxx-gen.c ------------ */ - -ST_DATA const int reg_classes[NB_REGS]; - -ST_FUNC void gsym_addr(int t, int a); -ST_FUNC void gsym(int t); -ST_FUNC void load(int r, SValue *sv); -ST_FUNC void store(int r, SValue *v); -ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *align, int *regsize); -ST_FUNC void gfunc_call(int nb_args); -ST_FUNC void gfunc_prolog(CType *func_type); -ST_FUNC void gfunc_epilog(void); -ST_FUNC int gjmp(int t); -ST_FUNC void gjmp_addr(int a); -ST_FUNC int gtst(int inv, int t); -ST_FUNC void gen_opi(int op); -ST_FUNC void gen_opf(int op); -ST_FUNC void gen_cvt_ftoi(int t); -ST_FUNC void gen_cvt_ftof(int t); -ST_FUNC void ggoto(void); -#ifndef TCC_TARGET_C67 -ST_FUNC void o(unsigned int c); -#endif -#ifndef TCC_TARGET_ARM -ST_FUNC void gen_cvt_itof(int t); -#endif -ST_FUNC void gen_vla_sp_save(int addr); -ST_FUNC void gen_vla_sp_restore(int addr); -ST_FUNC void gen_vla_alloc(CType *type, int align); - -/* ------------ i386-gen.c ------------ */ -#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 -ST_FUNC void g(int c); -ST_FUNC int oad(int c, int s); -ST_FUNC void gen_le16(int c); -ST_FUNC void gen_le32(int c); -ST_FUNC void gen_addr32(int r, Sym *sym, int c); -ST_FUNC void gen_addrpc32(int r, Sym *sym, int c); -#endif - -#ifdef CONFIG_TCC_BCHECK -ST_FUNC void gen_bounded_ptr_add(void); -ST_FUNC void gen_bounded_ptr_deref(void); -#endif - -/* ------------ x86_64-gen.c ------------ */ -#ifdef TCC_TARGET_X86_64 -ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c); -ST_FUNC void gen_opl(int op); -#endif - -/* ------------ arm-gen.c ------------ */ -#ifdef TCC_TARGET_ARM -#if defined(TCC_ARM_EABI) && !defined(CONFIG_TCC_ELFINTERP) -ST_FUNC char *default_elfinterp(struct TCCState *s); -#endif -ST_FUNC void arm_init(struct TCCState *s); -ST_FUNC uint32_t encbranch(int pos, int addr, int fail); -ST_FUNC void gen_cvt_itof1(int t); -#endif - -/* ------------ arm64-gen.c ------------ */ -#ifdef TCC_TARGET_ARM64 -ST_FUNC void gen_cvt_sxtw(void); -ST_FUNC void gen_opl(int op); -ST_FUNC void greturn(void); -ST_FUNC void gen_va_start(void); -ST_FUNC void gen_va_arg(CType *t); -ST_FUNC void gen_clear_cache(void); -#endif - -/* ------------ c67-gen.c ------------ */ -#ifdef TCC_TARGET_C67 -#endif - -/* ------------ tcccoff.c ------------ */ - -#ifdef TCC_TARGET_COFF -ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f); -ST_FUNC int tcc_load_coff(TCCState * s1, int fd); -#endif - -/* ------------ tccasm.c ------------ */ -ST_FUNC void asm_instr(void); -ST_FUNC void asm_global_instr(void); -#ifdef CONFIG_TCC_ASM -ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, const char *name, const char **pp); -ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe); -ST_FUNC int asm_int_expr(TCCState *s1); -ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess); -/* ------------ i386-asm.c ------------ */ -ST_FUNC void gen_expr32(ExprValue *pe); -ST_FUNC void asm_opcode(TCCState *s1, int opcode); -ST_FUNC void asm_compute_constraints(ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg); -ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier); -ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, int nb_outputs, int is_output, uint8_t *clobber_regs, int out_reg); -ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str); -#endif - -/* ------------ tccpe.c -------------- */ -#ifdef TCC_TARGET_PE -ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd); -ST_FUNC int pe_output_file(TCCState * s1, const char *filename); -ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value); -ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2); -#ifdef TCC_TARGET_X86_64 -ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack); -#endif -/* symbol properties stored in Elf32_Sym->st_other */ -# define ST_PE_EXPORT 0x10 -# define ST_PE_IMPORT 0x20 -# define ST_PE_STDCALL 0x40 -#endif - -/* ------------ tccrun.c ----------------- */ -#ifdef TCC_IS_NATIVE -#ifdef CONFIG_TCC_STATIC -#define RTLD_LAZY 0x001 -#define RTLD_NOW 0x002 -#define RTLD_GLOBAL 0x100 -#define RTLD_DEFAULT NULL -/* dummy function for profiling */ -ST_FUNC void *dlopen(const char *filename, int flag); -ST_FUNC void dlclose(void *p); -ST_FUNC const char *dlerror(void); -ST_FUNC void *resolve_sym(TCCState *s1, const char *symbol); -#elif !defined _WIN32 -ST_FUNC void *resolve_sym(TCCState *s1, const char *symbol); -#endif - -#ifdef CONFIG_TCC_BACKTRACE -ST_DATA int rt_num_callers; -ST_DATA const char **rt_bound_error_msg; -ST_DATA void *rt_prog_main; -ST_FUNC void tcc_set_num_callers(int n); -#endif -#endif - -/********************************************************/ -#undef ST_DATA -#ifdef ONE_SOURCE -#define ST_DATA static -#else -#define ST_DATA -#endif -/********************************************************/ -#endif /* _TCC_H */ diff --git a/external/TCC/tccasm.c b/external/TCC/tccasm.c deleted file mode 100644 index fade2d10..00000000 --- a/external/TCC/tccasm.c +++ /dev/null @@ -1,1138 +0,0 @@ -/* - * GAS like assembler for TCC - * - * Copyright (c) 2001-2004 Fabrice Bellard - * - * 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "tcc.h" -#ifdef CONFIG_TCC_ASM - -ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n) -{ - char buf[64]; - TokenSym *ts; - - snprintf(buf, sizeof(buf), "L..%u", n); - ts = tok_alloc(buf, strlen(buf)); - return ts->tok; -} - -ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe); - -/* We do not use the C expression parser to handle symbols. Maybe the - C expression parser could be tweaked to do so. */ - -static void asm_expr_unary(TCCState *s1, ExprValue *pe) -{ - Sym *sym; - int op, n, label; - const char *p; - - switch(tok) { - case TOK_PPNUM: - p = tokc.str.data; - n = strtoul(p, (char **)&p, 0); - if (*p == 'b' || *p == 'f') { - /* backward or forward label */ - label = asm_get_local_label_name(s1, n); - sym = label_find(label); - if (*p == 'b') { - /* backward : find the last corresponding defined label */ - if (sym && sym->r == 0) - sym = sym->prev_tok; - if (!sym) - tcc_error("local label '%d' not found backward", n); - } else { - /* forward */ - if (!sym || sym->r) { - /* if the last label is defined, then define a new one */ - sym = label_push(&s1->asm_labels, label, 0); - sym->type.t = VT_STATIC | VT_VOID; - } - } - pe->v = 0; - pe->sym = sym; - } else if (*p == '\0') { - pe->v = n; - pe->sym = NULL; - } else { - tcc_error("invalid number syntax"); - } - next(); - break; - case '+': - next(); - asm_expr_unary(s1, pe); - break; - case '-': - case '~': - op = tok; - next(); - asm_expr_unary(s1, pe); - if (pe->sym) - tcc_error("invalid operation with label"); - if (op == '-') - pe->v = -pe->v; - else - pe->v = ~pe->v; - break; - case TOK_CCHAR: - case TOK_LCHAR: - pe->v = tokc.i; - pe->sym = NULL; - next(); - break; - case '(': - next(); - asm_expr(s1, pe); - skip(')'); - break; - default: - if (tok >= TOK_IDENT) { - /* label case : if the label was not found, add one */ - sym = label_find(tok); - if (!sym) { - sym = label_push(&s1->asm_labels, tok, 0); - /* NOTE: by default, the symbol is global */ - sym->type.t = VT_VOID; - } - if (sym->r == SHN_ABS) { - /* if absolute symbol, no need to put a symbol value */ - pe->v = sym->jnext; - pe->sym = NULL; - } else { - pe->v = 0; - pe->sym = sym; - } - next(); - } else { - tcc_error("bad expression syntax [%s]", get_tok_str(tok, &tokc)); - } - break; - } -} - -static void asm_expr_prod(TCCState *s1, ExprValue *pe) -{ - int op; - ExprValue e2; - - asm_expr_unary(s1, pe); - for(;;) { - op = tok; - if (op != '*' && op != '/' && op != '%' && - op != TOK_SHL && op != TOK_SAR) - break; - next(); - asm_expr_unary(s1, &e2); - if (pe->sym || e2.sym) - tcc_error("invalid operation with label"); - switch(op) { - case '*': - pe->v *= e2.v; - break; - case '/': - if (e2.v == 0) { - div_error: - tcc_error("division by zero"); - } - pe->v /= e2.v; - break; - case '%': - if (e2.v == 0) - goto div_error; - pe->v %= e2.v; - break; - case TOK_SHL: - pe->v <<= e2.v; - break; - default: - case TOK_SAR: - pe->v >>= e2.v; - break; - } - } -} - -static void asm_expr_logic(TCCState *s1, ExprValue *pe) -{ - int op; - ExprValue e2; - - asm_expr_prod(s1, pe); - for(;;) { - op = tok; - if (op != '&' && op != '|' && op != '^') - break; - next(); - asm_expr_prod(s1, &e2); - if (pe->sym || e2.sym) - tcc_error("invalid operation with label"); - switch(op) { - case '&': - pe->v &= e2.v; - break; - case '|': - pe->v |= e2.v; - break; - default: - case '^': - pe->v ^= e2.v; - break; - } - } -} - -static inline void asm_expr_sum(TCCState *s1, ExprValue *pe) -{ - int op; - ExprValue e2; - - asm_expr_logic(s1, pe); - for(;;) { - op = tok; - if (op != '+' && op != '-') - break; - next(); - asm_expr_logic(s1, &e2); - if (op == '+') { - if (pe->sym != NULL && e2.sym != NULL) - goto cannot_relocate; - pe->v += e2.v; - if (pe->sym == NULL && e2.sym != NULL) - pe->sym = e2.sym; - } else { - pe->v -= e2.v; - /* NOTE: we are less powerful than gas in that case - because we store only one symbol in the expression */ - if (!pe->sym && !e2.sym) { - /* OK */ - } else if (pe->sym && !e2.sym) { - /* OK */ - } else if (pe->sym && e2.sym) { - if (pe->sym == e2.sym) { - /* OK */ - } else if (pe->sym->r == e2.sym->r && pe->sym->r != 0) { - /* we also accept defined symbols in the same section */ - pe->v += pe->sym->jnext - e2.sym->jnext; - } else { - goto cannot_relocate; - } - pe->sym = NULL; /* same symbols can be subtracted to NULL */ - } else { - cannot_relocate: - tcc_error("invalid operation with label"); - } - } - } -} - -ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe) -{ - asm_expr_sum(s1, pe); -} - -ST_FUNC int asm_int_expr(TCCState *s1) -{ - ExprValue e; - asm_expr(s1, &e); - if (e.sym) - expect("constant"); - return e.v; -} - -/* NOTE: the same name space as C labels is used to avoid using too - much memory when storing labels in TokenStrings */ -static void asm_new_label1(TCCState *s1, int label, int is_local, - int sh_num, int value) -{ - Sym *sym; - - sym = label_find(label); - if (sym) { - if (sym->r) { - /* the label is already defined */ - if (!is_local) { - tcc_error("assembler label '%s' already defined", - get_tok_str(label, NULL)); - } else { - /* redefinition of local labels is possible */ - goto new_label; - } - } - } else { - new_label: - sym = label_push(&s1->asm_labels, label, 0); - sym->type.t = VT_STATIC | VT_VOID; - } - sym->r = sh_num; - sym->jnext = value; -} - -static void asm_new_label(TCCState *s1, int label, int is_local) -{ - asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind); -} - -static void asm_free_labels(TCCState *st) -{ - Sym *s, *s1; - Section *sec; - - for(s = st->asm_labels; s != NULL; s = s1) { - s1 = s->prev; - /* define symbol value in object file */ - if (s->r) { - if (s->r == SHN_ABS) - sec = SECTION_ABS; - else - sec = st->sections[s->r]; - put_extern_sym2(s, sec, s->jnext, 0, 0); - } - /* remove label */ - table_ident[s->v - TOK_IDENT]->sym_label = NULL; - sym_free(s); - } - st->asm_labels = NULL; -} - -static void use_section1(TCCState *s1, Section *sec) -{ - cur_text_section->data_offset = ind; - cur_text_section = sec; - ind = cur_text_section->data_offset; -} - -static void use_section(TCCState *s1, const char *name) -{ - Section *sec; - sec = find_section(s1, name); - use_section1(s1, sec); -} - -static void asm_parse_directive(TCCState *s1) -{ - int n, offset, v, size, tok1; - Section *sec; - uint8_t *ptr; - - /* assembler directive */ - sec = cur_text_section; - switch(tok) { - case TOK_ASMDIR_align: - case TOK_ASMDIR_p2align: - case TOK_ASMDIR_skip: - case TOK_ASMDIR_space: - tok1 = tok; - next(); - n = asm_int_expr(s1); - if (tok1 == TOK_ASMDIR_p2align) - { - if (n < 0 || n > 30) - tcc_error("invalid p2align, must be between 0 and 30"); - n = 1 << n; - tok1 = TOK_ASMDIR_align; - } - if (tok1 == TOK_ASMDIR_align) { - if (n < 0 || (n & (n-1)) != 0) - tcc_error("alignment must be a positive power of two"); - offset = (ind + n - 1) & -n; - size = offset - ind; - /* the section must have a compatible alignment */ - if (sec->sh_addralign < n) - sec->sh_addralign = n; - } else { - size = n; - } - v = 0; - if (tok == ',') { - next(); - v = asm_int_expr(s1); - } - zero_pad: - if (sec->sh_type != SHT_NOBITS) { - sec->data_offset = ind; - ptr = section_ptr_add(sec, size); - memset(ptr, v, size); - } - ind += size; - break; - case TOK_ASMDIR_quad: - next(); - for(;;) { - uint64_t vl; - const char *p; - - p = tokc.str.data; - if (tok != TOK_PPNUM) { - error_constant: - tcc_error("64 bit constant"); - } - vl = strtoll(p, (char **)&p, 0); - if (*p != '\0') - goto error_constant; - next(); - if (sec->sh_type != SHT_NOBITS) { - /* XXX: endianness */ - gen_le32(vl); - gen_le32(vl >> 32); - } else { - ind += 8; - } - if (tok != ',') - break; - next(); - } - break; - case TOK_ASMDIR_byte: - size = 1; - goto asm_data; - case TOK_ASMDIR_word: - case TOK_ASMDIR_short: - size = 2; - goto asm_data; - case TOK_ASMDIR_long: - case TOK_ASMDIR_int: - size = 4; - asm_data: - next(); - for(;;) { - ExprValue e; - asm_expr(s1, &e); - if (sec->sh_type != SHT_NOBITS) { - if (size == 4) { - gen_expr32(&e); - } else { - if (e.sym) - expect("constant"); - if (size == 1) - g(e.v); - else - gen_le16(e.v); - } - } else { - ind += size; - } - if (tok != ',') - break; - next(); - } - break; - case TOK_ASMDIR_fill: - { - int repeat, size, val, i, j; - uint8_t repeat_buf[8]; - next(); - repeat = asm_int_expr(s1); - if (repeat < 0) { - tcc_error("repeat < 0; .fill ignored"); - break; - } - size = 1; - val = 0; - if (tok == ',') { - next(); - size = asm_int_expr(s1); - if (size < 0) { - tcc_error("size < 0; .fill ignored"); - break; - } - if (size > 8) - size = 8; - if (tok == ',') { - next(); - val = asm_int_expr(s1); - } - } - /* XXX: endianness */ - repeat_buf[0] = val; - repeat_buf[1] = val >> 8; - repeat_buf[2] = val >> 16; - repeat_buf[3] = val >> 24; - repeat_buf[4] = 0; - repeat_buf[5] = 0; - repeat_buf[6] = 0; - repeat_buf[7] = 0; - for(i = 0; i < repeat; i++) { - for(j = 0; j < size; j++) { - g(repeat_buf[j]); - } - } - } - break; - case TOK_ASMDIR_org: - { - unsigned long n; - next(); - /* XXX: handle section symbols too */ - n = asm_int_expr(s1); - if (n < ind) - tcc_error("attempt to .org backwards"); - v = 0; - size = n - ind; - goto zero_pad; - } - break; - case TOK_ASMDIR_globl: - case TOK_ASMDIR_global: - case TOK_ASMDIR_weak: - case TOK_ASMDIR_hidden: - tok1 = tok; - do { - Sym *sym; - - next(); - sym = label_find(tok); - if (!sym) { - sym = label_push(&s1->asm_labels, tok, 0); - sym->type.t = VT_VOID; - } - if (tok1 != TOK_ASMDIR_hidden) - sym->type.t &= ~VT_STATIC; - if (tok1 == TOK_ASMDIR_weak) - sym->type.t |= VT_WEAK; - else if (tok1 == TOK_ASMDIR_hidden) - sym->type.t |= STV_HIDDEN << VT_VIS_SHIFT; - next(); - } while (tok == ','); - break; - case TOK_ASMDIR_string: - case TOK_ASMDIR_ascii: - case TOK_ASMDIR_asciz: - { - const uint8_t *p; - int i, size, t; - - t = tok; - next(); - for(;;) { - if (tok != TOK_STR) - expect("string constant"); - p = tokc.str.data; - size = tokc.str.size; - if (t == TOK_ASMDIR_ascii && size > 0) - size--; - for(i = 0; i < size; i++) - g(p[i]); - next(); - if (tok == ',') { - next(); - } else if (tok != TOK_STR) { - break; - } - } - } - break; - case TOK_ASMDIR_text: - case TOK_ASMDIR_data: - case TOK_ASMDIR_bss: - { - char sname[64]; - tok1 = tok; - n = 0; - next(); - if (tok != ';' && tok != TOK_LINEFEED) { - n = asm_int_expr(s1); - next(); - } - if (n) - sprintf(sname, ".%s%d", get_tok_str(tok1, NULL), n); - else - sprintf(sname, ".%s", get_tok_str(tok1, NULL)); - use_section(s1, sname); - } - break; - case TOK_ASMDIR_file: - { - char filename[512]; - - filename[0] = '\0'; - next(); - - if (tok == TOK_STR) - pstrcat(filename, sizeof(filename), tokc.str.data); - else - pstrcat(filename, sizeof(filename), get_tok_str(tok, NULL)); - - if (s1->warn_unsupported) - tcc_warning("ignoring .file %s", filename); - - next(); - } - break; - case TOK_ASMDIR_ident: - { - char ident[256]; - - ident[0] = '\0'; - next(); - - if (tok == TOK_STR) - pstrcat(ident, sizeof(ident), tokc.str.data); - else - pstrcat(ident, sizeof(ident), get_tok_str(tok, NULL)); - - if (s1->warn_unsupported) - tcc_warning("ignoring .ident %s", ident); - - next(); - } - break; - case TOK_ASMDIR_size: - { - Sym *sym; - - next(); - sym = label_find(tok); - if (!sym) { - tcc_error("label not found: %s", get_tok_str(tok, NULL)); - } - - /* XXX .size name,label2-label1 */ - if (s1->warn_unsupported) - tcc_warning("ignoring .size %s,*", get_tok_str(tok, NULL)); - - next(); - skip(','); - while (tok != '\n' && tok != CH_EOF) { - next(); - } - } - break; - case TOK_ASMDIR_type: - { - Sym *sym; - const char *newtype; - - next(); - sym = label_find(tok); - if (!sym) { - sym = label_push(&s1->asm_labels, tok, 0); - sym->type.t = VT_VOID; - } - - next(); - skip(','); - if (tok == TOK_STR) { - newtype = tokc.str.data; - } else { - if (tok == '@' || tok == '%') - next(); - newtype = get_tok_str(tok, NULL); - } - - if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) { - sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC; - } - else if (s1->warn_unsupported) - tcc_warning("change type of '%s' from 0x%x to '%s' ignored", - get_tok_str(sym->v, NULL), sym->type.t, newtype); - - next(); - } - break; - case TOK_ASMDIR_section: - { - char sname[256]; - - /* XXX: support more options */ - next(); - sname[0] = '\0'; - while (tok != ';' && tok != TOK_LINEFEED && tok != ',') { - if (tok == TOK_STR) - pstrcat(sname, sizeof(sname), tokc.str.data); - else - pstrcat(sname, sizeof(sname), get_tok_str(tok, NULL)); - next(); - } - if (tok == ',') { - /* skip section options */ - next(); - if (tok != TOK_STR) - expect("string constant"); - next(); - if (tok == ',') { - next(); - if (tok == '@' || tok == '%') - next(); - next(); - } - } - last_text_section = cur_text_section; - use_section(s1, sname); - } - break; - case TOK_ASMDIR_previous: - { - Section *sec; - next(); - if (!last_text_section) - tcc_error("no previous section referenced"); - sec = cur_text_section; - use_section1(s1, last_text_section); - last_text_section = sec; - } - break; -#ifdef TCC_TARGET_I386 - case TOK_ASMDIR_code16: - { - next(); - s1->seg_size = 16; - } - break; - case TOK_ASMDIR_code32: - { - next(); - s1->seg_size = 32; - } - break; -#endif -#ifdef TCC_TARGET_X86_64 - /* added for compatibility with GAS */ - case TOK_ASMDIR_code64: - next(); - break; -#endif - default: - tcc_error("unknown assembler directive '.%s'", get_tok_str(tok, NULL)); - break; - } -} - - -/* assemble a file */ -static int tcc_assemble_internal(TCCState *s1, int do_preprocess) -{ - int opcode; - -#if 0 - /* print stats about opcodes */ - { - const ASMInstr *pa; - int freq[4]; - int op_vals[500]; - int nb_op_vals, i, j; - - nb_op_vals = 0; - memset(freq, 0, sizeof(freq)); - for(pa = asm_instrs; pa->sym != 0; pa++) { - freq[pa->nb_ops]++; - for(i=0;inb_ops;i++) { - for(j=0;jop_type[i] == op_vals[j]) - goto found; - } - op_vals[nb_op_vals++] = pa->op_type[i]; - found: ; - } - } - for(i=0;ibuf_ptr[0]; - tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; - parse_flags = PARSE_FLAG_ASM_FILE | PARSE_FLAG_TOK_STR; - if (do_preprocess) - parse_flags |= PARSE_FLAG_PREPROCESS; - next(); - for(;;) { - if (tok == TOK_EOF) - break; - parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */ - redo: - if (tok == '#') { - /* horrible gas comment */ - while (tok != TOK_LINEFEED) - next(); - } else if (tok >= TOK_ASMDIR_FIRST && tok <= TOK_ASMDIR_LAST) { - asm_parse_directive(s1); - } else if (tok == TOK_PPNUM) { - const char *p; - int n; - p = tokc.str.data; - n = strtoul(p, (char **)&p, 10); - if (*p != '\0') - expect("':'"); - /* new local label */ - asm_new_label(s1, asm_get_local_label_name(s1, n), 1); - next(); - skip(':'); - goto redo; - } else if (tok >= TOK_IDENT) { - /* instruction or label */ - opcode = tok; - next(); - if (tok == ':') { - /* new label */ - asm_new_label(s1, opcode, 0); - next(); - goto redo; - } else if (tok == '=') { - int n; - next(); - n = asm_int_expr(s1); - asm_new_label1(s1, opcode, 0, SHN_ABS, n); - goto redo; - } else { - asm_opcode(s1, opcode); - } - } - /* end of line */ - if (tok != ';' && tok != TOK_LINEFEED){ - expect("end of line"); - } - parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */ - next(); - } - - asm_free_labels(s1); - - return 0; -} - -/* Assemble the current file */ -ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess) -{ - Sym *define_start; - int ret; - - preprocess_init(s1); - - /* default section is text */ - cur_text_section = text_section; - ind = cur_text_section->data_offset; - - define_start = define_stack; - - /* an elf symbol of type STT_FILE must be put so that STB_LOCAL - symbols can be safely used */ - put_elf_sym(symtab_section, 0, 0, - ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0, - SHN_ABS, file->filename); - - ret = tcc_assemble_internal(s1, do_preprocess); - - cur_text_section->data_offset = ind; - - free_defines(define_start); - - return ret; -} - -/********************************************************************/ -/* GCC inline asm support */ - -/* assemble the string 'str' in the current C compilation unit without - C preprocessing. NOTE: str is modified by modifying the '\0' at the - end */ -static void tcc_assemble_inline(TCCState *s1, char *str, int len) -{ - int saved_parse_flags; - const int *saved_macro_ptr; - - saved_parse_flags = parse_flags; - saved_macro_ptr = macro_ptr; - - tcc_open_bf(s1, ":asm:", len); - memcpy(file->buffer, str, len); - - macro_ptr = NULL; - tcc_assemble_internal(s1, 0); - tcc_close(); - - parse_flags = saved_parse_flags; - macro_ptr = saved_macro_ptr; -} - -/* find a constraint by its number or id (gcc 3 extended - syntax). return -1 if not found. Return in *pp in char after the - constraint */ -ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, - const char *name, const char **pp) -{ - int index; - TokenSym *ts; - const char *p; - - if (isnum(*name)) { - index = 0; - while (isnum(*name)) { - index = (index * 10) + (*name) - '0'; - name++; - } - if ((unsigned)index >= nb_operands) - index = -1; - } else if (*name == '[') { - name++; - p = strchr(name, ']'); - if (p) { - ts = tok_alloc(name, p - name); - for(index = 0; index < nb_operands; index++) { - if (operands[index].id == ts->tok) - goto found; - } - index = -1; - found: - name = p + 1; - } else { - index = -1; - } - } else { - index = -1; - } - if (pp) - *pp = name; - return index; -} - -static void subst_asm_operands(ASMOperand *operands, int nb_operands, - int nb_outputs, - CString *out_str, CString *in_str) -{ - int c, index, modifier; - const char *str; - ASMOperand *op; - SValue sv; - - cstr_new(out_str); - str = in_str->data; - for(;;) { - c = *str++; - if (c == '%') { - if (*str == '%') { - str++; - goto add_char; - } - modifier = 0; - if (*str == 'c' || *str == 'n' || - *str == 'b' || *str == 'w' || *str == 'h') - modifier = *str++; - index = find_constraint(operands, nb_operands, str, &str); - if (index < 0) - tcc_error("invalid operand reference after %%"); - op = &operands[index]; - sv = *op->vt; - if (op->reg >= 0) { - sv.r = op->reg; - if ((op->vt->r & VT_VALMASK) == VT_LLOCAL && op->is_memory) - sv.r |= VT_LVAL; - } - subst_asm_operand(out_str, &sv, modifier); - } else { - add_char: - cstr_ccat(out_str, c); - if (c == '\0') - break; - } - } -} - - -static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr, - int is_output) -{ - ASMOperand *op; - int nb_operands; - - if (tok != ':') { - nb_operands = *nb_operands_ptr; - for(;;) { - if (nb_operands >= MAX_ASM_OPERANDS) - tcc_error("too many asm operands"); - op = &operands[nb_operands++]; - op->id = 0; - if (tok == '[') { - next(); - if (tok < TOK_IDENT) - expect("identifier"); - op->id = tok; - next(); - skip(']'); - } - if (tok != TOK_STR) - expect("string constant"); - op->constraint = tcc_malloc(tokc.str.size); - strcpy(op->constraint, tokc.str.data); - next(); - skip('('); - gexpr(); - if (is_output) { - test_lvalue(); - } else { - /* we want to avoid LLOCAL case, except when the 'm' - constraint is used. Note that it may come from - register storage, so we need to convert (reg) - case */ - if ((vtop->r & VT_LVAL) && - ((vtop->r & VT_VALMASK) == VT_LLOCAL || - (vtop->r & VT_VALMASK) < VT_CONST) && - !strchr(op->constraint, 'm')) { - gv(RC_INT); - } - } - op->vt = vtop; - skip(')'); - if (tok == ',') { - next(); - } else { - break; - } - } - *nb_operands_ptr = nb_operands; - } -} - -/* parse the GCC asm() instruction */ -ST_FUNC void asm_instr(void) -{ - CString astr, astr1; - ASMOperand operands[MAX_ASM_OPERANDS]; - int nb_outputs, nb_operands, i, must_subst, out_reg; - uint8_t clobber_regs[NB_ASM_REGS]; - - next(); - /* since we always generate the asm() instruction, we can ignore - volatile */ - if (tok == TOK_VOLATILE1 || tok == TOK_VOLATILE2 || tok == TOK_VOLATILE3) { - next(); - } - parse_asm_str(&astr); - nb_operands = 0; - nb_outputs = 0; - must_subst = 0; - memset(clobber_regs, 0, sizeof(clobber_regs)); - if (tok == ':') { - next(); - must_subst = 1; - /* output args */ - parse_asm_operands(operands, &nb_operands, 1); - nb_outputs = nb_operands; - if (tok == ':') { - next(); - if (tok != ')') { - /* input args */ - parse_asm_operands(operands, &nb_operands, 0); - if (tok == ':') { - /* clobber list */ - /* XXX: handle registers */ - next(); - for(;;) { - if (tok != TOK_STR) - expect("string constant"); - asm_clobber(clobber_regs, tokc.str.data); - next(); - if (tok == ',') { - next(); - } else { - break; - } - } - } - } - } - } - skip(')'); - /* NOTE: we do not eat the ';' so that we can restore the current - token after the assembler parsing */ - if (tok != ';') - expect("';'"); - - /* save all values in the memory */ - save_regs(0); - - /* compute constraints */ - asm_compute_constraints(operands, nb_operands, nb_outputs, - clobber_regs, &out_reg); - - /* substitute the operands in the asm string. No substitution is - done if no operands (GCC behaviour) */ -#ifdef ASM_DEBUG - printf("asm: \"%s\"\n", (char *)astr.data); -#endif - if (must_subst) { - subst_asm_operands(operands, nb_operands, nb_outputs, &astr1, &astr); - cstr_free(&astr); - } else { - astr1 = astr; - } -#ifdef ASM_DEBUG - printf("subst_asm: \"%s\"\n", (char *)astr1.data); -#endif - - /* generate loads */ - asm_gen_code(operands, nb_operands, nb_outputs, 0, - clobber_regs, out_reg); - - /* assemble the string with tcc internal assembler */ - tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1); - - /* restore the current C token */ - next(); - - /* store the output values if needed */ - asm_gen_code(operands, nb_operands, nb_outputs, 1, - clobber_regs, out_reg); - - /* free everything */ - for(i=0;iconstraint); - vpop(); - } - cstr_free(&astr1); -} - -ST_FUNC void asm_global_instr(void) -{ - CString astr; - - next(); - parse_asm_str(&astr); - skip(')'); - /* NOTE: we do not eat the ';' so that we can restore the current - token after the assembler parsing */ - if (tok != ';') - expect("';'"); - -#ifdef ASM_DEBUG - printf("asm_global: \"%s\"\n", (char *)astr.data); -#endif - cur_text_section = text_section; - ind = cur_text_section->data_offset; - - /* assemble the string with tcc internal assembler */ - tcc_assemble_inline(tcc_state, astr.data, astr.size - 1); - - cur_text_section->data_offset = ind; - - /* restore the current C token */ - next(); - - cstr_free(&astr); -} -#endif /* CONFIG_TCC_ASM */ diff --git a/external/TCC/tcccoff.c b/external/TCC/tcccoff.c deleted file mode 100644 index 1421ca26..00000000 --- a/external/TCC/tcccoff.c +++ /dev/null @@ -1,948 +0,0 @@ -/* - * COFF file handling for TCC - * - * Copyright (c) 2003, 2004 TK - * Copyright (c) 2004 Fabrice Bellard - * - * 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "tcc.h" - -#define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */ -#define MAX_STR_TABLE 1000000 -AOUTHDR o_filehdr; /* OPTIONAL (A.OUT) FILE HEADER */ - -SCNHDR section_header[MAXNSCNS]; - -#define MAX_FUNCS 1000 -#define MAX_FUNC_NAME_LENGTH 128 - -int nFuncs; -char Func[MAX_FUNCS][MAX_FUNC_NAME_LENGTH]; -char AssociatedFile[MAX_FUNCS][MAX_FUNC_NAME_LENGTH]; -int LineNoFilePtr[MAX_FUNCS]; -int EndAddress[MAX_FUNCS]; -int LastLineNo[MAX_FUNCS]; -int FuncEntries[MAX_FUNCS]; - -int OutputTheSection(Section * sect); -short int GetCoffFlags(const char *s); -void SortSymbolTable(void); -Section *FindSection(TCCState * s1, const char *sname); - -int C67_main_entry_point; - -int FindCoffSymbolIndex(const char *func_name); -int nb_syms; - -typedef struct { - long tag; - long size; - long fileptr; - long nextsym; - short int dummy; -} AUXFUNC; - -typedef struct { - long regmask; - unsigned short lineno; - unsigned short nentries; - int localframe; - int nextentry; - short int dummy; -} AUXBF; - -typedef struct { - long dummy; - unsigned short lineno; - unsigned short dummy1; - int dummy2; - int dummy3; - unsigned short dummy4; -} AUXEF; - -ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f) -{ - Section *tcc_sect; - SCNHDR *coff_sec; - int file_pointer; - char *Coff_str_table, *pCoff_str_table; - int CoffTextSectionNo, coff_nb_syms; - FILHDR file_hdr; /* FILE HEADER STRUCTURE */ - Section *stext, *sdata, *sbss; - int i, NSectionsToOutput = 0; - - Coff_str_table = pCoff_str_table = NULL; - - stext = FindSection(s1, ".text"); - sdata = FindSection(s1, ".data"); - sbss = FindSection(s1, ".bss"); - - nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym); - coff_nb_syms = FindCoffSymbolIndex("XXXXXXXXXX1"); - - file_hdr.f_magic = COFF_C67_MAGIC; /* magic number */ - file_hdr.f_timdat = 0; /* time & date stamp */ - file_hdr.f_opthdr = sizeof(AOUTHDR); /* sizeof(optional hdr) */ - file_hdr.f_flags = 0x1143; /* flags (copied from what code composer does) */ - file_hdr.f_TargetID = 0x99; /* for C6x = 0x0099 */ - - o_filehdr.magic = 0x0108; /* see magic.h */ - o_filehdr.vstamp = 0x0190; /* version stamp */ - o_filehdr.tsize = stext->data_offset; /* text size in bytes, padded to FW bdry */ - o_filehdr.dsize = sdata->data_offset; /* initialized data " " */ - o_filehdr.bsize = sbss->data_offset; /* uninitialized data " " */ - o_filehdr.entrypt = C67_main_entry_point; /* entry pt. */ - o_filehdr.text_start = stext->sh_addr; /* base of text used for this file */ - o_filehdr.data_start = sdata->sh_addr; /* base of data used for this file */ - - - // create all the section headers - - file_pointer = FILHSZ + sizeof(AOUTHDR); - - CoffTextSectionNo = -1; - - for (i = 1; i < s1->nb_sections; i++) { - coff_sec = §ion_header[i]; - tcc_sect = s1->sections[i]; - - if (OutputTheSection(tcc_sect)) { - NSectionsToOutput++; - - if (CoffTextSectionNo == -1 && tcc_sect == stext) - CoffTextSectionNo = NSectionsToOutput; // rem which coff sect number the .text sect is - - strcpy(coff_sec->s_name, tcc_sect->name); /* section name */ - - coff_sec->s_paddr = tcc_sect->sh_addr; /* physical address */ - coff_sec->s_vaddr = tcc_sect->sh_addr; /* virtual address */ - coff_sec->s_size = tcc_sect->data_offset; /* section size */ - coff_sec->s_scnptr = 0; /* file ptr to raw data for section */ - coff_sec->s_relptr = 0; /* file ptr to relocation */ - coff_sec->s_lnnoptr = 0; /* file ptr to line numbers */ - coff_sec->s_nreloc = 0; /* number of relocation entries */ - coff_sec->s_flags = GetCoffFlags(coff_sec->s_name); /* flags */ - coff_sec->s_reserved = 0; /* reserved byte */ - coff_sec->s_page = 0; /* memory page id */ - - file_pointer += sizeof(SCNHDR); - } - } - - file_hdr.f_nscns = NSectionsToOutput; /* number of sections */ - - // now loop through and determine file pointer locations - // for the raw data - - - for (i = 1; i < s1->nb_sections; i++) { - coff_sec = §ion_header[i]; - tcc_sect = s1->sections[i]; - - if (OutputTheSection(tcc_sect)) { - // put raw data - coff_sec->s_scnptr = file_pointer; /* file ptr to raw data for section */ - file_pointer += coff_sec->s_size; - } - } - - // now loop through and determine file pointer locations - // for the relocation data - - for (i = 1; i < s1->nb_sections; i++) { - coff_sec = §ion_header[i]; - tcc_sect = s1->sections[i]; - - if (OutputTheSection(tcc_sect)) { - // put relocations data - if (coff_sec->s_nreloc > 0) { - coff_sec->s_relptr = file_pointer; /* file ptr to relocation */ - file_pointer += coff_sec->s_nreloc * sizeof(struct reloc); - } - } - } - - // now loop through and determine file pointer locations - // for the line number data - - for (i = 1; i < s1->nb_sections; i++) { - coff_sec = §ion_header[i]; - tcc_sect = s1->sections[i]; - - coff_sec->s_nlnno = 0; - coff_sec->s_lnnoptr = 0; - - if (s1->do_debug && tcc_sect == stext) { - // count how many line nos data - - // also find association between source file name and function - // so we can sort the symbol table - - - Stab_Sym *sym, *sym_end; - char func_name[MAX_FUNC_NAME_LENGTH], - last_func_name[MAX_FUNC_NAME_LENGTH]; - unsigned long func_addr, last_pc, pc; - const char *incl_files[INCLUDE_STACK_SIZE]; - int incl_index, len, last_line_num; - const char *str, *p; - - coff_sec->s_lnnoptr = file_pointer; /* file ptr to linno */ - - - func_name[0] = '\0'; - func_addr = 0; - incl_index = 0; - last_func_name[0] = '\0'; - last_pc = 0xffffffff; - last_line_num = 1; - sym = (Stab_Sym *) stab_section->data + 1; - sym_end = - (Stab_Sym *) (stab_section->data + - stab_section->data_offset); - - nFuncs = 0; - while (sym < sym_end) { - switch (sym->n_type) { - /* function start or end */ - case N_FUN: - if (sym->n_strx == 0) { - // end of function - - coff_sec->s_nlnno++; - file_pointer += LINESZ; - - pc = sym->n_value + func_addr; - func_name[0] = '\0'; - func_addr = 0; - EndAddress[nFuncs] = pc; - FuncEntries[nFuncs] = - (file_pointer - - LineNoFilePtr[nFuncs]) / LINESZ - 1; - LastLineNo[nFuncs++] = last_line_num + 1; - } else { - // beginning of function - - LineNoFilePtr[nFuncs] = file_pointer; - coff_sec->s_nlnno++; - file_pointer += LINESZ; - - str = - (const char *) stabstr_section->data + - sym->n_strx; - - p = strchr(str, ':'); - if (!p) { - pstrcpy(func_name, sizeof(func_name), str); - pstrcpy(Func[nFuncs], sizeof(func_name), str); - } else { - len = p - str; - if (len > sizeof(func_name) - 1) - len = sizeof(func_name) - 1; - memcpy(func_name, str, len); - memcpy(Func[nFuncs], str, len); - func_name[len] = '\0'; - } - - // save the file that it came in so we can sort later - pstrcpy(AssociatedFile[nFuncs], sizeof(func_name), - incl_files[incl_index - 1]); - - func_addr = sym->n_value; - } - break; - - /* line number info */ - case N_SLINE: - pc = sym->n_value + func_addr; - - last_pc = pc; - last_line_num = sym->n_desc; - - /* XXX: slow! */ - strcpy(last_func_name, func_name); - - coff_sec->s_nlnno++; - file_pointer += LINESZ; - break; - /* include files */ - case N_BINCL: - str = - (const char *) stabstr_section->data + sym->n_strx; - add_incl: - if (incl_index < INCLUDE_STACK_SIZE) { - incl_files[incl_index++] = str; - } - break; - case N_EINCL: - if (incl_index > 1) - incl_index--; - break; - case N_SO: - if (sym->n_strx == 0) { - incl_index = 0; /* end of translation unit */ - } else { - str = - (const char *) stabstr_section->data + - sym->n_strx; - /* do not add path */ - len = strlen(str); - if (len > 0 && str[len - 1] != '/') - goto add_incl; - } - break; - } - sym++; - } - } - - } - - file_hdr.f_symptr = file_pointer; /* file pointer to symtab */ - - if (s1->do_debug) - file_hdr.f_nsyms = coff_nb_syms; /* number of symtab entries */ - else - file_hdr.f_nsyms = 0; - - file_pointer += file_hdr.f_nsyms * SYMNMLEN; - - // OK now we are all set to write the file - - - fwrite(&file_hdr, FILHSZ, 1, f); - fwrite(&o_filehdr, sizeof(o_filehdr), 1, f); - - // write section headers - for (i = 1; i < s1->nb_sections; i++) { - coff_sec = §ion_header[i]; - tcc_sect = s1->sections[i]; - - if (OutputTheSection(tcc_sect)) { - fwrite(coff_sec, sizeof(SCNHDR), 1, f); - } - } - - // write raw data - for (i = 1; i < s1->nb_sections; i++) { - coff_sec = §ion_header[i]; - tcc_sect = s1->sections[i]; - - if (OutputTheSection(tcc_sect)) { - fwrite(tcc_sect->data, tcc_sect->data_offset, 1, f); - } - } - - // write relocation data - for (i = 1; i < s1->nb_sections; i++) { - coff_sec = §ion_header[i]; - tcc_sect = s1->sections[i]; - - if (OutputTheSection(tcc_sect)) { - // put relocations data - if (coff_sec->s_nreloc > 0) { - fwrite(tcc_sect->reloc, - coff_sec->s_nreloc * sizeof(struct reloc), 1, f); - } - } - } - - - // group the symbols in order of filename, func1, func2, etc - // finally global symbols - - if (s1->do_debug) - SortSymbolTable(); - - // write line no data - - for (i = 1; i < s1->nb_sections; i++) { - coff_sec = §ion_header[i]; - tcc_sect = s1->sections[i]; - - if (s1->do_debug && tcc_sect == stext) { - // count how many line nos data - - - Stab_Sym *sym, *sym_end; - char func_name[128], last_func_name[128]; - unsigned long func_addr, last_pc, pc; - const char *incl_files[INCLUDE_STACK_SIZE]; - int incl_index, len, last_line_num; - const char *str, *p; - - LINENO CoffLineNo; - - func_name[0] = '\0'; - func_addr = 0; - incl_index = 0; - last_func_name[0] = '\0'; - last_pc = 0; - last_line_num = 1; - sym = (Stab_Sym *) stab_section->data + 1; - sym_end = - (Stab_Sym *) (stab_section->data + - stab_section->data_offset); - - while (sym < sym_end) { - switch (sym->n_type) { - /* function start or end */ - case N_FUN: - if (sym->n_strx == 0) { - // end of function - - CoffLineNo.l_addr.l_paddr = last_pc; - CoffLineNo.l_lnno = last_line_num + 1; - fwrite(&CoffLineNo, 6, 1, f); - - pc = sym->n_value + func_addr; - func_name[0] = '\0'; - func_addr = 0; - } else { - // beginning of function - - str = - (const char *) stabstr_section->data + - sym->n_strx; - - - p = strchr(str, ':'); - if (!p) { - pstrcpy(func_name, sizeof(func_name), str); - } else { - len = p - str; - if (len > sizeof(func_name) - 1) - len = sizeof(func_name) - 1; - memcpy(func_name, str, len); - func_name[len] = '\0'; - } - func_addr = sym->n_value; - last_pc = func_addr; - last_line_num = -1; - - // output a function begin - - CoffLineNo.l_addr.l_symndx = - FindCoffSymbolIndex(func_name); - CoffLineNo.l_lnno = 0; - - fwrite(&CoffLineNo, 6, 1, f); - } - break; - - /* line number info */ - case N_SLINE: - pc = sym->n_value + func_addr; - - - /* XXX: slow! */ - strcpy(last_func_name, func_name); - - // output a line reference - - CoffLineNo.l_addr.l_paddr = last_pc; - - if (last_line_num == -1) { - CoffLineNo.l_lnno = sym->n_desc; - } else { - CoffLineNo.l_lnno = last_line_num + 1; - } - - fwrite(&CoffLineNo, 6, 1, f); - - last_pc = pc; - last_line_num = sym->n_desc; - - break; - - /* include files */ - case N_BINCL: - str = - (const char *) stabstr_section->data + sym->n_strx; - add_incl2: - if (incl_index < INCLUDE_STACK_SIZE) { - incl_files[incl_index++] = str; - } - break; - case N_EINCL: - if (incl_index > 1) - incl_index--; - break; - case N_SO: - if (sym->n_strx == 0) { - incl_index = 0; /* end of translation unit */ - } else { - str = - (const char *) stabstr_section->data + - sym->n_strx; - /* do not add path */ - len = strlen(str); - if (len > 0 && str[len - 1] != '/') - goto add_incl2; - } - break; - } - sym++; - } - } - } - - // write symbol table - if (s1->do_debug) { - int k; - struct syment csym; - AUXFUNC auxfunc; - AUXBF auxbf; - AUXEF auxef; - int i; - Elf32_Sym *p; - const char *name; - int nstr; - int n = 0; - - Coff_str_table = (char *) tcc_malloc(MAX_STR_TABLE); - pCoff_str_table = Coff_str_table; - nstr = 0; - - p = (Elf32_Sym *) symtab_section->data; - - - for (i = 0; i < nb_syms; i++) { - - name = symtab_section->link->data + p->st_name; - - for (k = 0; k < 8; k++) - csym._n._n_name[k] = 0; - - if (strlen(name) <= 8) { - strcpy(csym._n._n_name, name); - } else { - if (pCoff_str_table - Coff_str_table + strlen(name) > - MAX_STR_TABLE - 1) - tcc_error("String table too large"); - - csym._n._n_n._n_zeroes = 0; - csym._n._n_n._n_offset = - pCoff_str_table - Coff_str_table + 4; - - strcpy(pCoff_str_table, name); - pCoff_str_table += strlen(name) + 1; // skip over null - nstr++; - } - - if (p->st_info == 4) { - // put a filename symbol - csym.n_value = 33; // ????? - csym.n_scnum = N_DEBUG; - csym.n_type = 0; - csym.n_sclass = C_FILE; - csym.n_numaux = 0; - fwrite(&csym, 18, 1, f); - n++; - - } else if (p->st_info == 0x12) { - // find the function data - - for (k = 0; k < nFuncs; k++) { - if (strcmp(name, Func[k]) == 0) - break; - } - - if (k >= nFuncs) { - tcc_error("debug info can't find function: %s", name); - } - // put a Function Name - - csym.n_value = p->st_value; // physical address - csym.n_scnum = CoffTextSectionNo; - csym.n_type = MKTYPE(T_INT, DT_FCN, 0, 0, 0, 0, 0); - csym.n_sclass = C_EXT; - csym.n_numaux = 1; - fwrite(&csym, 18, 1, f); - - // now put aux info - - auxfunc.tag = 0; - auxfunc.size = EndAddress[k] - p->st_value; - auxfunc.fileptr = LineNoFilePtr[k]; - auxfunc.nextsym = n + 6; // tktk - auxfunc.dummy = 0; - fwrite(&auxfunc, 18, 1, f); - - // put a .bf - - strcpy(csym._n._n_name, ".bf"); - csym.n_value = p->st_value; // physical address - csym.n_scnum = CoffTextSectionNo; - csym.n_type = 0; - csym.n_sclass = C_FCN; - csym.n_numaux = 1; - fwrite(&csym, 18, 1, f); - - // now put aux info - - auxbf.regmask = 0; - auxbf.lineno = 0; - auxbf.nentries = FuncEntries[k]; - auxbf.localframe = 0; - auxbf.nextentry = n + 6; - auxbf.dummy = 0; - fwrite(&auxbf, 18, 1, f); - - // put a .ef - - strcpy(csym._n._n_name, ".ef"); - csym.n_value = EndAddress[k]; // physical address - csym.n_scnum = CoffTextSectionNo; - csym.n_type = 0; - csym.n_sclass = C_FCN; - csym.n_numaux = 1; - fwrite(&csym, 18, 1, f); - - // now put aux info - - auxef.dummy = 0; - auxef.lineno = LastLineNo[k]; - auxef.dummy1 = 0; - auxef.dummy2 = 0; - auxef.dummy3 = 0; - auxef.dummy4 = 0; - fwrite(&auxef, 18, 1, f); - - n += 6; - - } else { - // try an put some type info - - if ((p->st_other & VT_BTYPE) == VT_DOUBLE) { - csym.n_type = T_DOUBLE; // int - csym.n_sclass = C_EXT; - } else if ((p->st_other & VT_BTYPE) == VT_FLOAT) { - csym.n_type = T_FLOAT; - csym.n_sclass = C_EXT; - } else if ((p->st_other & VT_BTYPE) == VT_INT) { - csym.n_type = T_INT; // int - csym.n_sclass = C_EXT; - } else if ((p->st_other & VT_BTYPE) == VT_SHORT) { - csym.n_type = T_SHORT; - csym.n_sclass = C_EXT; - } else if ((p->st_other & VT_BTYPE) == VT_BYTE) { - csym.n_type = T_CHAR; - csym.n_sclass = C_EXT; - } else { - csym.n_type = T_INT; // just mark as a label - csym.n_sclass = C_LABEL; - } - - - csym.n_value = p->st_value; - csym.n_scnum = 2; - csym.n_numaux = 1; - fwrite(&csym, 18, 1, f); - - auxfunc.tag = 0; - auxfunc.size = 0x20; - auxfunc.fileptr = 0; - auxfunc.nextsym = 0; - auxfunc.dummy = 0; - fwrite(&auxfunc, 18, 1, f); - n++; - n++; - - } - - p++; - } - } - - if (s1->do_debug) { - // write string table - - // first write the size - i = pCoff_str_table - Coff_str_table; - fwrite(&i, 4, 1, f); - - // then write the strings - fwrite(Coff_str_table, i, 1, f); - - tcc_free(Coff_str_table); - } - - return 0; -} - - - -// group the symbols in order of filename, func1, func2, etc -// finally global symbols - -void SortSymbolTable(void) -{ - int i, j, k, n = 0; - Elf32_Sym *p, *p2, *NewTable; - char *name, *name2; - - NewTable = (Elf32_Sym *) tcc_malloc(nb_syms * sizeof(Elf32_Sym)); - - p = (Elf32_Sym *) symtab_section->data; - - - // find a file symbol, copy it over - // then scan the whole symbol list and copy any function - // symbols that match the file association - - for (i = 0; i < nb_syms; i++) { - if (p->st_info == 4) { - name = (char *) symtab_section->link->data + p->st_name; - - // this is a file symbol, copy it over - - NewTable[n++] = *p; - - p2 = (Elf32_Sym *) symtab_section->data; - - for (j = 0; j < nb_syms; j++) { - if (p2->st_info == 0x12) { - // this is a func symbol - - name2 = - (char *) symtab_section->link->data + p2->st_name; - - // find the function data index - - for (k = 0; k < nFuncs; k++) { - if (strcmp(name2, Func[k]) == 0) - break; - } - - if (k >= nFuncs) { - tcc_error("debug (sort) info can't find function: %s", name2); - } - - if (strcmp(AssociatedFile[k], name) == 0) { - // yes they match copy it over - - NewTable[n++] = *p2; - } - } - p2++; - } - } - p++; - } - - // now all the filename and func symbols should have been copied over - // copy all the rest over (all except file and funcs) - - p = (Elf32_Sym *) symtab_section->data; - for (i = 0; i < nb_syms; i++) { - if (p->st_info != 4 && p->st_info != 0x12) { - NewTable[n++] = *p; - } - p++; - } - - if (n != nb_syms) - tcc_error("Internal Compiler error, debug info"); - - // copy it all back - - p = (Elf32_Sym *) symtab_section->data; - for (i = 0; i < nb_syms; i++) { - *p++ = NewTable[i]; - } - - tcc_free(NewTable); -} - - -int FindCoffSymbolIndex(const char *func_name) -{ - int i, n = 0; - Elf32_Sym *p; - char *name; - - p = (Elf32_Sym *) symtab_section->data; - - for (i = 0; i < nb_syms; i++) { - - name = (char *) symtab_section->link->data + p->st_name; - - if (p->st_info == 4) { - // put a filename symbol - n++; - } else if (p->st_info == 0x12) { - - if (strcmp(func_name, name) == 0) - return n; - - n += 6; - - // put a Function Name - - // now put aux info - - // put a .bf - - // now put aux info - - // put a .ef - - // now put aux info - - } else { - n += 2; - } - - p++; - } - - return n; // total number of symbols -} - -int OutputTheSection(Section * sect) -{ - const char *s = sect->name; - - if (!strcmp(s, ".text")) - return 1; - else if (!strcmp(s, ".data")) - return 1; - else - return 0; -} - -short int GetCoffFlags(const char *s) -{ - if (!strcmp(s, ".text")) - return STYP_TEXT | STYP_DATA | STYP_ALIGN | 0x400; - else if (!strcmp(s, ".data")) - return STYP_DATA; - else if (!strcmp(s, ".bss")) - return STYP_BSS; - else if (!strcmp(s, ".stack")) - return STYP_BSS | STYP_ALIGN | 0x200; - else if (!strcmp(s, ".cinit")) - return STYP_COPY | STYP_DATA | STYP_ALIGN | 0x200; - else - return 0; -} - -Section *FindSection(TCCState * s1, const char *sname) -{ - Section *s; - int i; - - for (i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; - - if (!strcmp(sname, s->name)) - return s; - } - - tcc_error("could not find section %s", sname); - return 0; -} - -ST_FUNC int tcc_load_coff(TCCState * s1, int fd) -{ -// tktk TokenSym *ts; - - FILE *f; - unsigned int str_size; - char *Coff_str_table, *name; - int i, k; - struct syment csym; - char name2[9]; - FILHDR file_hdr; /* FILE HEADER STRUCTURE */ - - f = fdopen(fd, "rb"); - if (!f) { - tcc_error("Unable to open .out file for input"); - } - - if (fread(&file_hdr, FILHSZ, 1, f) != 1) - tcc_error("error reading .out file for input"); - - if (fread(&o_filehdr, sizeof(o_filehdr), 1, f) != 1) - tcc_error("error reading .out file for input"); - - // first read the string table - - if (fseek(f, file_hdr.f_symptr + file_hdr.f_nsyms * SYMESZ, SEEK_SET)) - tcc_error("error reading .out file for input"); - - if (fread(&str_size, sizeof(int), 1, f) != 1) - tcc_error("error reading .out file for input"); - - - Coff_str_table = (char *) tcc_malloc(str_size); - - if (fread(Coff_str_table, str_size - 4, 1, f) != 1) - tcc_error("error reading .out file for input"); - - // read/process all the symbols - - // seek back to symbols - - if (fseek(f, file_hdr.f_symptr, SEEK_SET)) - tcc_error("error reading .out file for input"); - - for (i = 0; i < file_hdr.f_nsyms; i++) { - if (fread(&csym, SYMESZ, 1, f) != 1) - tcc_error("error reading .out file for input"); - - if (csym._n._n_n._n_zeroes == 0) { - name = Coff_str_table + csym._n._n_n._n_offset - 4; - } else { - name = csym._n._n_name; - - if (name[7] != 0) { - for (k = 0; k < 8; k++) - name2[k] = name[k]; - - name2[8] = 0; - - name = name2; - } - } -// if (strcmp("_DAC_Buffer",name)==0) // tktk -// name[0]=0; - - if (((csym.n_type & 0x30) == 0x20 && csym.n_sclass == 0x2) || ((csym.n_type & 0x30) == 0x30 && csym.n_sclass == 0x2) || (csym.n_type == 0x4 && csym.n_sclass == 0x2) || (csym.n_type == 0x8 && csym.n_sclass == 0x2) || // structures - (csym.n_type == 0x18 && csym.n_sclass == 0x2) || // pointer to structure - (csym.n_type == 0x7 && csym.n_sclass == 0x2) || // doubles - (csym.n_type == 0x6 && csym.n_sclass == 0x2)) // floats - { - // strip off any leading underscore (except for other main routine) - - if (name[0] == '_' && strcmp(name, "_main") != 0) - name++; - - tcc_add_symbol(s1, name, (void*)(uintptr_t)csym.n_value); - } - // skip any aux records - - if (csym.n_numaux == 1) { - if (fread(&csym, SYMESZ, 1, f) != 1) - tcc_error("error reading .out file for input"); - i++; - } - } - - return 0; -} diff --git a/external/TCC/tccelf.c b/external/TCC/tccelf.c deleted file mode 100644 index 9cfa8c41..00000000 --- a/external/TCC/tccelf.c +++ /dev/null @@ -1,3512 +0,0 @@ -/* - * ELF file handling for TCC - * - * Copyright (c) 2001-2004 Fabrice Bellard - * - * 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "tcc.h" - -/* Define this to get some debug output during relocation processing. */ -#undef DEBUG_RELOC - -/* XXX: avoid static variable */ -static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */ - -ST_FUNC int put_elf_str(Section *s, const char *sym) -{ - int offset, len; - char *ptr; - - len = strlen(sym) + 1; - offset = s->data_offset; - ptr = section_ptr_add(s, len); - memcpy(ptr, sym, len); - return offset; -} - -/* elf symbol hashing function */ -static unsigned long elf_hash(const unsigned char *name) -{ - unsigned long h = 0, g; - - while (*name) { - h = (h << 4) + *name++; - g = h & 0xf0000000; - if (g) - h ^= g >> 24; - h &= ~g; - } - return h; -} - -/* rebuild hash table of section s */ -/* NOTE: we do factorize the hash table code to go faster */ -static void rebuild_hash(Section *s, unsigned int nb_buckets) -{ - ElfW(Sym) *sym; - int *ptr, *hash, nb_syms, sym_index, h; - unsigned char *strtab; - - strtab = s->link->data; - nb_syms = s->data_offset / sizeof(ElfW(Sym)); - - s->hash->data_offset = 0; - ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int)); - ptr[0] = nb_buckets; - ptr[1] = nb_syms; - ptr += 2; - hash = ptr; - memset(hash, 0, (nb_buckets + 1) * sizeof(int)); - ptr += nb_buckets + 1; - - sym = (ElfW(Sym) *)s->data + 1; - for(sym_index = 1; sym_index < nb_syms; sym_index++) { - if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { - h = elf_hash(strtab + sym->st_name) % nb_buckets; - *ptr = hash[h]; - hash[h] = sym_index; - } else { - *ptr = 0; - } - ptr++; - sym++; - } -} - -/* return the symbol number */ -ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, - int info, int other, int shndx, const char *name) -{ - int name_offset, sym_index; - int nbuckets, h; - ElfW(Sym) *sym; - Section *hs; - - sym = section_ptr_add(s, sizeof(ElfW(Sym))); - if (name) - name_offset = put_elf_str(s->link, name); - else - name_offset = 0; - /* XXX: endianness */ - sym->st_name = name_offset; - sym->st_value = value; - sym->st_size = size; - sym->st_info = info; - sym->st_other = other; - sym->st_shndx = shndx; - sym_index = sym - (ElfW(Sym) *)s->data; - hs = s->hash; - if (hs) { - int *ptr, *base; - ptr = section_ptr_add(hs, sizeof(int)); - base = (int *)hs->data; - /* only add global or weak symbols */ - if (ELFW(ST_BIND)(info) != STB_LOCAL) { - /* add another hashing entry */ - nbuckets = base[0]; - h = elf_hash((unsigned char *) name) % nbuckets; - *ptr = base[2 + h]; - base[2 + h] = sym_index; - base[1]++; - /* we resize the hash table */ - hs->nb_hashed_syms++; - if (hs->nb_hashed_syms > 2 * nbuckets) { - rebuild_hash(s, 2 * nbuckets); - } - } else { - *ptr = 0; - base[1]++; - } - } - return sym_index; -} - -/* find global ELF symbol 'name' and return its index. Return 0 if not - found. */ -ST_FUNC int find_elf_sym(Section *s, const char *name) -{ - ElfW(Sym) *sym; - Section *hs; - int nbuckets, sym_index, h; - const char *name1; - - hs = s->hash; - if (!hs) - return 0; - nbuckets = ((int *)hs->data)[0]; - h = elf_hash((unsigned char *) name) % nbuckets; - sym_index = ((int *)hs->data)[2 + h]; - while (sym_index != 0) { - sym = &((ElfW(Sym) *)s->data)[sym_index]; - name1 = (char *) s->link->data + sym->st_name; - if (!strcmp(name, name1)) - return sym_index; - sym_index = ((int *)hs->data)[2 + nbuckets + sym_index]; - } - return 0; -} - -/* return elf symbol value, signal error if 'err' is nonzero */ -ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err) -{ - int sym_index; - ElfW(Sym) *sym; - - sym_index = find_elf_sym(s->symtab, name); - sym = &((ElfW(Sym) *)s->symtab->data)[sym_index]; - if (!sym_index || sym->st_shndx == SHN_UNDEF) { - if (err) - tcc_error("%s not defined", name); - return 0; - } - return sym->st_value; -} - -/* return elf symbol value */ -LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name) -{ - return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0); -} - -#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE -/* return elf symbol value or error */ -ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name) -{ - return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1); -} -#endif - -/* add an elf symbol : check if it is already defined and patch - it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */ -ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size, - int info, int other, int sh_num, const char *name) -{ - ElfW(Sym) *esym; - int sym_bind, sym_index, sym_type, esym_bind; - unsigned char sym_vis, esym_vis, new_vis; - - sym_bind = ELFW(ST_BIND)(info); - sym_type = ELFW(ST_TYPE)(info); - sym_vis = ELFW(ST_VISIBILITY)(other); - - if (sym_bind != STB_LOCAL) { - /* we search global or weak symbols */ - sym_index = find_elf_sym(s, name); - if (!sym_index) - goto do_def; - esym = &((ElfW(Sym) *)s->data)[sym_index]; - if (esym->st_shndx != SHN_UNDEF) { - esym_bind = ELFW(ST_BIND)(esym->st_info); - /* propagate the most constraining visibility */ - /* STV_DEFAULT(0)st_other); - if (esym_vis == STV_DEFAULT) { - new_vis = sym_vis; - } else if (sym_vis == STV_DEFAULT) { - new_vis = esym_vis; - } else { - new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis; - } - esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) - | new_vis; - other = esym->st_other; /* in case we have to patch esym */ - if (sh_num == SHN_UNDEF) { - /* ignore adding of undefined symbol if the - corresponding symbol is already defined */ - } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) { - /* global overrides weak, so patch */ - goto do_patch; - } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) { - /* weak is ignored if already global */ - } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) { - /* keep first-found weak definition, ignore subsequents */ - } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) { - /* ignore hidden symbols after */ - } else if (esym->st_shndx == SHN_COMMON - && (sh_num < SHN_LORESERVE || sh_num == SHN_COMMON)) { - /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01 - No idea if this is the correct solution ... */ - goto do_patch; - } else if (s == tcc_state->dynsymtab_section) { - /* we accept that two DLL define the same symbol */ - } else { -#if 0 - printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n", - sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis); -#endif - tcc_error_noabort("'%s' defined twice... may be -fcommon is needed?", name); - } - } else { - do_patch: - esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type); - esym->st_shndx = sh_num; - new_undef_sym = 1; - esym->st_value = value; - esym->st_size = size; - esym->st_other = other; - } - } else { - do_def: - sym_index = put_elf_sym(s, value, size, - ELFW(ST_INFO)(sym_bind, sym_type), other, - sh_num, name); - } - return sym_index; -} - -/* put relocation */ -ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, - int type, int symbol, addr_t addend) -{ - char buf[256]; - Section *sr; - ElfW_Rel *rel; - - sr = s->reloc; - if (!sr) { - /* if no relocation section, create it */ - snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name); - /* if the symtab is allocated, then we consider the relocation - are also */ - sr = new_section(tcc_state, buf, SHT_RELX, symtab->sh_flags); - sr->sh_entsize = sizeof(ElfW_Rel); - sr->link = symtab; - sr->sh_info = s->sh_num; - s->reloc = sr; - } - rel = section_ptr_add(sr, sizeof(ElfW_Rel)); - rel->r_offset = offset; - rel->r_info = ELFW(R_INFO)(symbol, type); -#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) - rel->r_addend = addend; -#else - if (addend) - tcc_error("non-zero addend on REL architecture"); -#endif -} - -ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, - int type, int symbol) -{ - put_elf_reloca(symtab, s, offset, type, symbol, 0); -} - -/* put stab debug information */ - -ST_FUNC void put_stabs(const char *str, int type, int other, int desc, - unsigned long value) -{ - Stab_Sym *sym; - - sym = section_ptr_add(stab_section, sizeof(Stab_Sym)); - if (str) { - sym->n_strx = put_elf_str(stabstr_section, str); - } else { - sym->n_strx = 0; - } - sym->n_type = type; - sym->n_other = other; - sym->n_desc = desc; - sym->n_value = value; -} - -ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc, - unsigned long value, Section *sec, int sym_index) -{ - put_stabs(str, type, other, desc, value); - put_elf_reloc(symtab_section, stab_section, - stab_section->data_offset - sizeof(unsigned int), - R_DATA_32, sym_index); -} - -ST_FUNC void put_stabn(int type, int other, int desc, int value) -{ - put_stabs(NULL, type, other, desc, value); -} - -ST_FUNC void put_stabd(int type, int other, int desc) -{ - put_stabs(NULL, type, other, desc, 0); -} - -/* Browse each elem of type in section starting at elem - using variable */ -#define for_each_elem(sec, startoff, elem, type) \ - for (elem = (type *) sec->data + startoff; \ - elem < (type *) (sec->data + sec->data_offset); elem++) - -/* In an ELF file symbol table, the local symbols must appear below - the global and weak ones. Since TCC cannot sort it while generating - the code, we must do it after. All the relocation tables are also - modified to take into account the symbol table sorting */ -static void sort_syms(TCCState *s1, Section *s) -{ - int *old_to_new_syms; - ElfW(Sym) *new_syms; - int nb_syms, i; - ElfW(Sym) *p, *q; - ElfW_Rel *rel; - Section *sr; - int type, sym_index; - - nb_syms = s->data_offset / sizeof(ElfW(Sym)); - new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym))); - old_to_new_syms = tcc_malloc(nb_syms * sizeof(int)); - - /* first pass for local symbols */ - p = (ElfW(Sym) *)s->data; - q = new_syms; - for(i = 0; i < nb_syms; i++) { - if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) { - old_to_new_syms[i] = q - new_syms; - *q++ = *p; - } - p++; - } - /* save the number of local symbols in section header */ - s->sh_info = q - new_syms; - - /* then second pass for non local symbols */ - p = (ElfW(Sym) *)s->data; - for(i = 0; i < nb_syms; i++) { - if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) { - old_to_new_syms[i] = q - new_syms; - *q++ = *p; - } - p++; - } - - /* we copy the new symbols to the old */ - memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym))); - tcc_free(new_syms); - - /* now we modify all the relocations */ - for(i = 1; i < s1->nb_sections; i++) { - sr = s1->sections[i]; - if (sr->sh_type == SHT_RELX && sr->link == s) { - for_each_elem(sr, 0, rel, ElfW_Rel) { - sym_index = ELFW(R_SYM)(rel->r_info); - type = ELFW(R_TYPE)(rel->r_info); - sym_index = old_to_new_syms[sym_index]; - rel->r_info = ELFW(R_INFO)(sym_index, type); - } - } - } - - tcc_free(old_to_new_syms); -} - -/* relocate common symbols in the .bss section */ -ST_FUNC void relocate_common_syms(void) -{ - ElfW(Sym) *sym; - unsigned long offset, align; - - for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { - if (sym->st_shndx == SHN_COMMON) { - /* align symbol */ - align = sym->st_value; - offset = bss_section->data_offset; - offset = (offset + align - 1) & -align; - sym->st_value = offset; - sym->st_shndx = bss_section->sh_num; - offset += sym->st_size; - bss_section->data_offset = offset; - } - } -} - -/* relocate symbol table, resolve undefined symbols if do_resolve is - true and output error if undefined symbol. */ -ST_FUNC void relocate_syms(TCCState *s1, int do_resolve) -{ - ElfW(Sym) *sym, *esym; - int sym_bind, sh_num, sym_index; - const char *name; - - for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { - sh_num = sym->st_shndx; - if (sh_num == SHN_UNDEF) { - name = (char *) strtab_section->data + sym->st_name; - /* Use ld.so to resolve symbol for us (for tcc -run) */ - if (do_resolve) { -#if defined TCC_IS_NATIVE && !defined _WIN32 - void *addr; - name = (char *) symtab_section->link->data + sym->st_name; - addr = resolve_sym(s1, name); - if (addr) { - sym->st_value = (addr_t)addr; -#ifdef DEBUG_RELOC - printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value); -#endif - goto found; - } -#endif - } else if (s1->dynsym) { - /* if dynamic symbol exist, then use it */ - sym_index = find_elf_sym(s1->dynsym, name); - if (sym_index) { - esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index]; - sym->st_value = esym->st_value; - goto found; - } - } - /* XXX: _fp_hw seems to be part of the ABI, so we ignore - it */ - if (!strcmp(name, "_fp_hw")) - goto found; - /* only weak symbols are accepted to be undefined. Their - value is zero */ - sym_bind = ELFW(ST_BIND)(sym->st_info); - if (sym_bind == STB_WEAK) { - sym->st_value = 0; - } else { - tcc_error_noabort("undefined symbol '%s'", name); - } - } else if (sh_num < SHN_LORESERVE) { - /* add section base */ - sym->st_value += s1->sections[sym->st_shndx]->sh_addr; - } - found: ; - } -} - -/* relocate a given section (CPU dependent) by applying the relocations - in the associated relocation section */ -ST_FUNC void relocate_section(TCCState *s1, Section *s) -{ - Section *sr = s->reloc; - ElfW_Rel *rel; - ElfW(Sym) *sym; - int type, sym_index; - unsigned char *ptr; - addr_t val, addr; -#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 - ElfW_Rel *qrel = (ElfW_Rel *) sr->data; /* ptr to next reloc entry reused */ - int esym_index; -#endif - - for_each_elem(sr, 0, rel, ElfW_Rel) { - ptr = s->data + rel->r_offset; - - sym_index = ELFW(R_SYM)(rel->r_info); - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - val = sym->st_value; -#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) - val += rel->r_addend; -#endif - type = ELFW(R_TYPE)(rel->r_info); - addr = s->sh_addr + rel->r_offset; - - /* CPU specific */ - switch(type) { -#if defined(TCC_TARGET_I386) - case R_386_32: - if (s1->output_type == TCC_OUTPUT_DLL) { - esym_index = s1->symtab_to_dynsym[sym_index]; - qrel->r_offset = rel->r_offset; - if (esym_index) { - qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32); - qrel++; - break; - } else { - qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE); - qrel++; - } - } - write32le(ptr, read32le(ptr) + val); - break; - case R_386_PC32: - if (s1->output_type == TCC_OUTPUT_DLL) { - /* DLL relocation */ - esym_index = s1->symtab_to_dynsym[sym_index]; - if (esym_index) { - qrel->r_offset = rel->r_offset; - qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32); - qrel++; - break; - } - } - write32le(ptr, read32le(ptr) + val - addr); - break; - case R_386_PLT32: - write32le(ptr, read32le(ptr) + val - addr); - break; - case R_386_GLOB_DAT: - case R_386_JMP_SLOT: - write32le(ptr, val); - break; - case R_386_GOTPC: - write32le(ptr, read32le(ptr) + s1->got->sh_addr - addr); - break; - case R_386_GOTOFF: - write32le(ptr, read32le(ptr) + val - s1->got->sh_addr); - break; - case R_386_GOT32: - case R_386_GOT32X: - /* we load the got offset */ - write32le(ptr, read32le(ptr) + s1->sym_attrs[sym_index].got_offset); - break; - case R_386_16: - if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) { - output_file: - tcc_error("can only produce 16-bit binary files"); - } - write16le(ptr, read16le(ptr) + val); - break; - case R_386_PC16: - if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) - goto output_file; - write16le(ptr, read16le(ptr) + val - addr); - break; - case R_386_RELATIVE: - /* do nothing */ - break; - default: - fprintf(stderr,"FIXME: handle reloc type %d at %x [%p] to %x\n", - type, (unsigned)addr, ptr, (unsigned)val); - break; -#elif defined(TCC_TARGET_ARM) - case R_ARM_PC24: - case R_ARM_CALL: - case R_ARM_JUMP24: - case R_ARM_PLT32: - { - int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko; - x = (*(int *) ptr) & 0xffffff; - if (sym->st_shndx == SHN_UNDEF) - val = s1->plt->sh_addr; -#ifdef DEBUG_RELOC - printf ("reloc %d: x=0x%x val=0x%x ", type, x, val); -#endif - (*(int *)ptr) &= 0xff000000; - if (x & 0x800000) - x -= 0x1000000; - x <<= 2; - blx_avail = (TCC_ARM_VERSION >= 5); - is_thumb = val & 1; - is_bl = (*(unsigned *) ptr) >> 24 == 0xeb; - is_call = (type == R_ARM_CALL || (type == R_ARM_PC24 && is_bl)); - x += val - addr; -#ifdef DEBUG_RELOC - printf (" newx=0x%x name=%s\n", x, - (char *) symtab_section->link->data + sym->st_name); -#endif - h = x & 2; - th_ko = (x & 3) && (!blx_avail || !is_call); - if (th_ko || x >= 0x2000000 || x < -0x2000000) - tcc_error("can't relocate value at %x,%d",addr, type); - x >>= 2; - x &= 0xffffff; - /* Only reached if blx is avail and it is a call */ - if (is_thumb) { - x |= h << 24; - (*(int *)ptr) = 0xfa << 24; /* bl -> blx */ - } - (*(int *) ptr) |= x; - } - break; - /* Since these relocations only concern Thumb-2 and blx instruction was - introduced before Thumb-2, we can assume blx is available and not - guard its use */ - case R_ARM_THM_PC22: - case R_ARM_THM_JUMP24: - { - int x, hi, lo, s, j1, j2, i1, i2, imm10, imm11; - int to_thumb, is_call, to_plt, blx_bit = 1 << 12; - Section *plt; - - /* weak reference */ - if (sym->st_shndx == SHN_UNDEF && - ELFW(ST_BIND)(sym->st_info) == STB_WEAK) - break; - - /* Get initial offset */ - hi = (*(uint16_t *)ptr); - lo = (*(uint16_t *)(ptr+2)); - s = (hi >> 10) & 1; - j1 = (lo >> 13) & 1; - j2 = (lo >> 11) & 1; - i1 = (j1 ^ s) ^ 1; - i2 = (j2 ^ s) ^ 1; - imm10 = hi & 0x3ff; - imm11 = lo & 0x7ff; - x = (s << 24) | (i1 << 23) | (i2 << 22) | - (imm10 << 12) | (imm11 << 1); - if (x & 0x01000000) - x -= 0x02000000; - - /* Relocation infos */ - to_thumb = val & 1; - plt = s1->plt; - to_plt = (val >= plt->sh_addr) && - (val < plt->sh_addr + plt->data_offset); - is_call = (type == R_ARM_THM_PC22); - - /* Compute final offset */ - if (to_plt && !is_call) /* Point to 1st instr of Thumb stub */ - x -= 4; - x += val - addr; - if (!to_thumb && is_call) { - blx_bit = 0; /* bl -> blx */ - x = (x + 3) & -4; /* Compute offset from aligned PC */ - } - - /* Check that relocation is possible - * offset must not be out of range - * if target is to be entered in arm mode: - - bit 1 must not set - - instruction must be a call (bl) or a jump to PLT */ - if (!to_thumb || x >= 0x1000000 || x < -0x1000000) - if (to_thumb || (val & 2) || (!is_call && !to_plt)) - tcc_error("can't relocate value at %x,%d",addr, type); - - /* Compute and store final offset */ - s = (x >> 24) & 1; - i1 = (x >> 23) & 1; - i2 = (x >> 22) & 1; - j1 = s ^ (i1 ^ 1); - j2 = s ^ (i2 ^ 1); - imm10 = (x >> 12) & 0x3ff; - imm11 = (x >> 1) & 0x7ff; - (*(uint16_t *)ptr) = (uint16_t) ((hi & 0xf800) | - (s << 10) | imm10); - (*(uint16_t *)(ptr+2)) = (uint16_t) ((lo & 0xc000) | - (j1 << 13) | blx_bit | (j2 << 11) | - imm11); - } - break; - case R_ARM_MOVT_ABS: - case R_ARM_MOVW_ABS_NC: - { - int x, imm4, imm12; - if (type == R_ARM_MOVT_ABS) - val >>= 16; - imm12 = val & 0xfff; - imm4 = (val >> 12) & 0xf; - x = (imm4 << 16) | imm12; - if (type == R_ARM_THM_MOVT_ABS) - *(int *)ptr |= x; - else - *(int *)ptr += x; - } - break; - case R_ARM_THM_MOVT_ABS: - case R_ARM_THM_MOVW_ABS_NC: - { - int x, i, imm4, imm3, imm8; - if (type == R_ARM_THM_MOVT_ABS) - val >>= 16; - imm8 = val & 0xff; - imm3 = (val >> 8) & 0x7; - i = (val >> 11) & 1; - imm4 = (val >> 12) & 0xf; - x = (imm3 << 28) | (imm8 << 16) | (i << 10) | imm4; - if (type == R_ARM_THM_MOVT_ABS) - *(int *)ptr |= x; - else - *(int *)ptr += x; - } - break; - case R_ARM_PREL31: - { - int x; - x = (*(int *)ptr) & 0x7fffffff; - (*(int *)ptr) &= 0x80000000; - x = (x * 2) / 2; - x += val - addr; - if((x^(x>>1))&0x40000000) - tcc_error("can't relocate value at %x,%d",addr, type); - (*(int *)ptr) |= x & 0x7fffffff; - } - case R_ARM_ABS32: - *(int *)ptr += val; - break; - case R_ARM_REL32: - *(int *)ptr += val - addr; - break; - case R_ARM_GOTPC: - *(int *)ptr += s1->got->sh_addr - addr; - break; - case R_ARM_GOTOFF: - *(int *)ptr += val - s1->got->sh_addr; - break; - case R_ARM_GOT32: - /* we load the got offset */ - *(int *)ptr += s1->sym_attrs[sym_index].got_offset; - break; - case R_ARM_COPY: - break; - case R_ARM_V4BX: - /* trade Thumb support for ARMv4 support */ - if ((0x0ffffff0 & *(int*)ptr) == 0x012FFF10) - *(int*)ptr ^= 0xE12FFF10 ^ 0xE1A0F000; /* BX Rm -> MOV PC, Rm */ - break; - case R_ARM_GLOB_DAT: - case R_ARM_JUMP_SLOT: - *(addr_t *)ptr = val; - break; - case R_ARM_NONE: - /* Nothing to do. Normally used to indicate a dependency - on a certain symbol (like for exception handling under EABI). */ - break; - default: - fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n", - type, (unsigned)addr, ptr, (unsigned)val); - break; -#elif defined(TCC_TARGET_ARM64) - case R_AARCH64_ABS64: - write64le(ptr, val); - break; - case R_AARCH64_ABS32: - write32le(ptr, val); - break; - case R_AARCH64_MOVW_UABS_G0_NC: - write32le(ptr, ((read32le(ptr) & 0xffe0001f) | - (val & 0xffff) << 5)); - break; - case R_AARCH64_MOVW_UABS_G1_NC: - write32le(ptr, ((read32le(ptr) & 0xffe0001f) | - (val >> 16 & 0xffff) << 5)); - break; - case R_AARCH64_MOVW_UABS_G2_NC: - write32le(ptr, ((read32le(ptr) & 0xffe0001f) | - (val >> 32 & 0xffff) << 5)); - break; - case R_AARCH64_MOVW_UABS_G3: - write32le(ptr, ((read32le(ptr) & 0xffe0001f) | - (val >> 48 & 0xffff) << 5)); - break; - case R_AARCH64_ADR_PREL_PG_HI21: { - uint64_t off = (val >> 12) - (addr >> 12); - if ((off + ((uint64_t)1 << 20)) >> 21) - tcc_error("R_AARCH64_ADR_PREL_PG_HI21 relocation failed"); - write32le(ptr, ((read32le(ptr) & 0x9f00001f) | - (off & 0x1ffffc) << 3 | (off & 3) << 29)); - break; - } - case R_AARCH64_ADD_ABS_LO12_NC: - write32le(ptr, ((read32le(ptr) & 0xffc003ff) | - (val & 0xfff) << 10)); - break; - case R_AARCH64_JUMP26: - case R_AARCH64_CALL26: - /* This check must match the one in build_got_entries, testing - if we really need a PLT slot. */ - if (sym->st_shndx == SHN_UNDEF) - /* We've put the PLT slot offset into r_addend when generating - it, and that's what we must use as relocation value (adjusted - by section offset of course). */ - val = s1->plt->sh_addr + rel->r_addend; -#ifdef DEBUG_RELOC - printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val, - (char *) symtab_section->link->data + sym->st_name); -#endif - if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc) - { - tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed (val=%lx, addr=%lx)", addr, val); - } - write32le(ptr, (0x14000000 | - (uint32_t)(type == R_AARCH64_CALL26) << 31 | - ((val - addr) >> 2 & 0x3ffffff))); - break; - case R_AARCH64_ADR_GOT_PAGE: { - uint64_t off = - (((s1->got->sh_addr + - s1->sym_attrs[sym_index].got_offset) >> 12) - (addr >> 12)); - if ((off + ((uint64_t)1 << 20)) >> 21) - tcc_error("R_AARCH64_ADR_GOT_PAGE relocation failed"); - write32le(ptr, ((read32le(ptr) & 0x9f00001f) | - (off & 0x1ffffc) << 3 | (off & 3) << 29)); - break; - } - case R_AARCH64_LD64_GOT_LO12_NC: - write32le(ptr, - ((read32le(ptr) & 0xfff803ff) | - ((s1->got->sh_addr + - s1->sym_attrs[sym_index].got_offset) & 0xff8) << 7)); - break; - case R_AARCH64_COPY: - break; - case R_AARCH64_GLOB_DAT: - case R_AARCH64_JUMP_SLOT: - /* They don't need addend */ -#ifdef DEBUG_RELOC - printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, - val - rel->r_addend, - (char *) symtab_section->link->data + sym->st_name); -#endif - write64le(ptr, val - rel->r_addend); - break; - default: - fprintf(stderr, "FIXME: handle reloc type %x at %x [%p] to %x\n", - type, (unsigned)addr, ptr, (unsigned)val); - break; -#elif defined(TCC_TARGET_C67) - case R_C60_32: - *(int *)ptr += val; - break; - case R_C60LO16: - { - uint32_t orig; - - /* put the low 16 bits of the absolute address - add to what is already there */ - - orig = ((*(int *)(ptr )) >> 7) & 0xffff; - orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16; - - /* patch both at once - assumes always in pairs Low - High */ - - *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7); - *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7); - } - break; - case R_C60HI16: - break; - default: - fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n", - type, (unsigned)addr, ptr, (unsigned)val); - break; -#elif defined(TCC_TARGET_X86_64) - case R_X86_64_64: - if (s1->output_type == TCC_OUTPUT_DLL) { - esym_index = s1->symtab_to_dynsym[sym_index]; - qrel->r_offset = rel->r_offset; - if (esym_index) { - qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_64); - qrel->r_addend = rel->r_addend; - qrel++; - break; - } else { - qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE); - qrel->r_addend = read64le(ptr) + val; - qrel++; - } - } - write64le(ptr, read64le(ptr) + val); - break; - case R_X86_64_32: - case R_X86_64_32S: - if (s1->output_type == TCC_OUTPUT_DLL) { - /* XXX: this logic may depend on TCC's codegen - now TCC uses R_X86_64_32 even for a 64bit pointer */ - qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE); - /* Use sign extension! */ - qrel->r_addend = (int)read32le(ptr) + val; - qrel++; - } - write32le(ptr, read32le(ptr) + val); - break; - - case R_X86_64_PC32: - if (s1->output_type == TCC_OUTPUT_DLL) { - /* DLL relocation */ - esym_index = s1->symtab_to_dynsym[sym_index]; - if (esym_index) { - qrel->r_offset = rel->r_offset; - qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32); - /* Use sign extension! */ - qrel->r_addend = (int)read32le(ptr); - qrel++; - break; - } - } - goto plt32pc32; - - case R_X86_64_PLT32: - /* We've put the PLT slot offset into r_addend when generating - it, and that's what we must use as relocation value (adjusted - by section offset of course). */ - val = s1->plt->sh_addr + rel->r_addend; - /* fallthrough. */ - - plt32pc32: - { - long long diff; - diff = (long long)val - addr; - if (diff < -2147483648LL || diff > 2147483647LL) { - tcc_error("internal error: relocation failed"); - } - write32le(ptr, read32le(ptr) + diff); - } - break; - case R_X86_64_GLOB_DAT: - case R_X86_64_JUMP_SLOT: - /* They don't need addend */ - write64le(ptr, val - rel->r_addend); - break; - case R_X86_64_GOTPCREL: - case R_X86_64_GOTPCRELX: - case R_X86_64_REX_GOTPCRELX: - write32le(ptr, read32le(ptr) + - (s1->got->sh_addr - addr + - s1->sym_attrs[sym_index].got_offset - 4)); - break; - case R_X86_64_GOTTPOFF: - write32le(ptr, read32le(ptr) + val - s1->got->sh_addr); - break; - case R_X86_64_GOT32: - /* we load the got offset */ - write32le(ptr, read32le(ptr) + s1->sym_attrs[sym_index].got_offset); - break; -#else -#error unsupported processor -#endif - } - } - /* if the relocation is allocated, we change its symbol table */ - if (sr->sh_flags & SHF_ALLOC) - sr->link = s1->dynsym; -} - -/* relocate relocation table in 'sr' */ -static void relocate_rel(TCCState *s1, Section *sr) -{ - Section *s; - ElfW_Rel *rel; - - s = s1->sections[sr->sh_info]; - for_each_elem(sr, 0, rel, ElfW_Rel) - rel->r_offset += s->sh_addr; -} - -/* count the number of dynamic relocations so that we can reserve - their space */ -static int prepare_dynamic_rel(TCCState *s1, Section *sr) -{ - ElfW_Rel *rel; - int sym_index, esym_index, type, count; - - count = 0; - for_each_elem(sr, 0, rel, ElfW_Rel) { - sym_index = ELFW(R_SYM)(rel->r_info); - type = ELFW(R_TYPE)(rel->r_info); - switch(type) { -#if defined(TCC_TARGET_I386) - case R_386_32: -#elif defined(TCC_TARGET_X86_64) - case R_X86_64_32: - case R_X86_64_32S: - case R_X86_64_64: -#endif - count++; - break; -#if defined(TCC_TARGET_I386) - case R_386_PC32: -#elif defined(TCC_TARGET_X86_64) - case R_X86_64_PC32: -#endif - esym_index = s1->symtab_to_dynsym[sym_index]; - if (esym_index) - count++; - break; - default: - break; - } - } - if (count) { - /* allocate the section */ - sr->sh_flags |= SHF_ALLOC; - sr->sh_size = count * sizeof(ElfW_Rel); - } - return count; -} - -static struct sym_attr *alloc_sym_attr(TCCState *s1, int index) -{ - int n; - struct sym_attr *tab; - - if (index >= s1->nb_sym_attrs) { - /* find immediately bigger power of 2 and reallocate array */ - n = 1; - while (index >= n) - n *= 2; - tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs)); - s1->sym_attrs = tab; - memset(s1->sym_attrs + s1->nb_sym_attrs, 0, - (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs)); - s1->nb_sym_attrs = n; - } - return &s1->sym_attrs[index]; -} - -static void build_got(TCCState *s1) -{ - unsigned char *ptr; - - /* if no got, then create it */ - s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); - s1->got->sh_entsize = 4; - add_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT), - 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_"); - ptr = section_ptr_add(s1->got, 3 * PTR_SIZE); -#if PTR_SIZE == 4 - /* keep space for _DYNAMIC pointer, if present */ - write32le(ptr, 0); - /* two dummy got entries */ - write32le(ptr + 4, 0); - write32le(ptr + 8, 0); -#else - /* keep space for _DYNAMIC pointer, if present */ - write32le(ptr, 0); - write32le(ptr + 4, 0); - /* two dummy got entries */ - write32le(ptr + 8, 0); - write32le(ptr + 12, 0); - write32le(ptr + 16, 0); - write32le(ptr + 20, 0); -#endif -} - -/* put a got or plt entry corresponding to a symbol in symtab_section. 'size' - and 'info' can be modifed if more precise info comes from the DLL. - Returns offset of GOT or PLT slot. */ -static unsigned long put_got_entry(TCCState *s1, - int reloc_type, unsigned long size, int info, - int sym_index) -{ - int index, need_plt_entry; - const char *name; - ElfW(Sym) *sym; - unsigned long offset; - int *ptr; - struct sym_attr *symattr; - - if (!s1->got) - build_got(s1); - - need_plt_entry = -#ifdef TCC_TARGET_X86_64 - (reloc_type == R_X86_64_JUMP_SLOT); -#elif defined(TCC_TARGET_I386) - (reloc_type == R_386_JMP_SLOT); -#elif defined(TCC_TARGET_ARM) - (reloc_type == R_ARM_JUMP_SLOT); -#elif defined(TCC_TARGET_ARM64) - (reloc_type == R_AARCH64_JUMP_SLOT); -#else - 0; -#endif - - if (need_plt_entry && !s1->plt) { - /* add PLT */ - s1->plt = new_section(s1, ".plt", SHT_PROGBITS, - SHF_ALLOC | SHF_EXECINSTR); - s1->plt->sh_entsize = 4; - } - - /* If a got/plt entry already exists for that symbol, no need to add one */ - if (sym_index < s1->nb_sym_attrs) { - if (need_plt_entry && s1->sym_attrs[sym_index].plt_offset) - return s1->sym_attrs[sym_index].plt_offset; - else if (!need_plt_entry && s1->sym_attrs[sym_index].got_offset) - return s1->sym_attrs[sym_index].got_offset; - } - - symattr = alloc_sym_attr(s1, sym_index); - - /* Only store the GOT offset if it's not generated for the PLT entry. */ - if (!need_plt_entry) - symattr->got_offset = s1->got->data_offset; - - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - name = (char *) symtab_section->link->data + sym->st_name; - offset = sym->st_value; -#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) - if (need_plt_entry) { - Section *plt; - uint8_t *p; - int modrm; - unsigned long relofs; - -#if defined(TCC_OUTPUT_DLL_WITH_PLT) - modrm = 0x25; -#else - /* if we build a DLL, we add a %ebx offset */ - if (s1->output_type == TCC_OUTPUT_DLL) - modrm = 0xa3; - else - modrm = 0x25; -#endif - - /* add a PLT entry */ - plt = s1->plt; - if (plt->data_offset == 0) { - /* first plt entry */ - p = section_ptr_add(plt, 16); - p[0] = 0xff; /* pushl got + PTR_SIZE */ - p[1] = modrm + 0x10; - write32le(p + 2, PTR_SIZE); - p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */ - p[7] = modrm; - write32le(p + 8, PTR_SIZE * 2); - } - - /* The PLT slot refers to the relocation entry it needs - via offset. The reloc entry is created below, so its - offset is the current data_offset. */ - relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0; - symattr->plt_offset = plt->data_offset; - p = section_ptr_add(plt, 16); - p[0] = 0xff; /* jmp *(got + x) */ - p[1] = modrm; - write32le(p + 2, s1->got->data_offset); - p[6] = 0x68; /* push $xxx */ -#ifdef TCC_TARGET_X86_64 - /* On x86-64, the relocation is referred to by _index_. */ - write32le(p + 7, relofs / sizeof (ElfW_Rel)); -#else - write32le(p + 7, relofs); -#endif - p[11] = 0xe9; /* jmp plt_start */ - write32le(p + 12, -(plt->data_offset)); - - /* If this was an UNDEF symbol set the offset in the - dynsymtab to the PLT slot, so that PC32 relocs to it - can be resolved. */ - if (sym->st_shndx == SHN_UNDEF) - offset = plt->data_offset - 16; - } -#elif defined(TCC_TARGET_ARM) - if (need_plt_entry) { - Section *plt; - uint8_t *p; - - /* if we build a DLL, we add a %ebx offset */ - if (s1->output_type == TCC_OUTPUT_DLL) - tcc_error("DLLs unimplemented!"); - - /* add a PLT entry */ - plt = s1->plt; - if (plt->data_offset == 0) { - /* first plt entry */ - p = section_ptr_add(plt, 16); - write32le(p, 0xe52de004); /* push {lr} */ - write32le(p+4, 0xe59fe010); /* ldr lr, [pc, #16] */ - write32le(p+8, 0xe08fe00e); /* add lr, pc, lr */ - write32le(p+12, 0xe5bef008); /* ldr pc, [lr, #8]! */ - } - - symattr->plt_offset = plt->data_offset; - if (symattr->plt_thumb_stub) { - p = section_ptr_add(plt, 20); - write32le(p, 0x4778); /* bx pc */ - write32le(p+2, 0x46c0); /* nop */ - p += 4; - } else - p = section_ptr_add(plt, 16); - write32le(p, 0xe59fc004); /* ldr ip, [pc, #4] ; GOT entry offset */ - write32le(p+4, 0xe08fc00c); /* add ip, pc, ip ; addr of GOT entry */ - write32le(p+8, 0xe59cf000); /* ldr pc, [ip] ; jump to GOT entry */ - write32le(p+12, s1->got->data_offset); /* GOT entry off once patched */ - - /* the symbol is modified so that it will be relocated to - the PLT */ - if (sym->st_shndx == SHN_UNDEF) - offset = plt->data_offset - 16; - } -#elif defined(TCC_TARGET_ARM64) - if (need_plt_entry) { - Section *plt; - uint8_t *p; - - if (s1->output_type == TCC_OUTPUT_DLL) - tcc_error("DLLs unimplemented!"); - - plt = s1->plt; - if (plt->data_offset == 0) - section_ptr_add(plt, 32); - symattr->plt_offset = plt->data_offset; - p = section_ptr_add(plt, 16); - write32le(p, s1->got->data_offset); - write32le(p + 4, (uint64_t)s1->got->data_offset >> 32); - - if (sym->st_shndx == SHN_UNDEF) - offset = plt->data_offset - 16; - } -#elif defined(TCC_TARGET_C67) - if (s1->dynsym) { - tcc_error("C67 got not implemented"); - } -#else -#error unsupported CPU -#endif - if (s1->dynsym) { - /* XXX This might generate multiple syms for name. */ - index = put_elf_sym(s1->dynsym, offset, - size, info, 0, sym->st_shndx, name); - /* Create the relocation (it's against the GOT for PLT - and GOT relocs). */ - put_elf_reloc(s1->dynsym, s1->got, - s1->got->data_offset, - reloc_type, index); - } else { - /* Without .dynsym (i.e. static link or memory output) we - still need relocs against the generated got, so as to fill - the entries with the symbol values (determined later). */ - put_elf_reloc(symtab_section, s1->got, - s1->got->data_offset, - reloc_type, sym_index); - } - /* And now create the GOT slot itself. */ - ptr = section_ptr_add(s1->got, PTR_SIZE); - *ptr = 0; - if (need_plt_entry) - return symattr->plt_offset; - else - return symattr->got_offset; -} - -/* build GOT and PLT entries */ -ST_FUNC void build_got_entries(TCCState *s1) -{ - Section *s; - ElfW_Rel *rel; - ElfW(Sym) *sym; - int i, type, reloc_type, sym_index; - - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; - if (s->sh_type != SHT_RELX) - continue; - /* no need to handle got relocations */ - if (s->link != symtab_section) - continue; - for_each_elem(s, 0, rel, ElfW_Rel) { - type = ELFW(R_TYPE)(rel->r_info); - switch(type) { -#if defined(TCC_TARGET_I386) - case R_386_GOT32: - case R_386_GOT32X: - case R_386_GOTOFF: - case R_386_GOTPC: - case R_386_PLT32: - if (!s1->got) - build_got(s1); - if (type == R_386_GOT32 || type == R_386_GOT32X || - type == R_386_PLT32) { - sym_index = ELFW(R_SYM)(rel->r_info); - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - /* look at the symbol got offset. If none, then add one */ - if (type == R_386_GOT32 || type == R_386_GOT32X) - reloc_type = R_386_GLOB_DAT; - else - reloc_type = R_386_JMP_SLOT; - put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, - sym_index); - } - break; -#elif defined(TCC_TARGET_ARM) - case R_ARM_PC24: - case R_ARM_CALL: - case R_ARM_JUMP24: - case R_ARM_GOT32: - case R_ARM_GOTOFF: - case R_ARM_GOTPC: - case R_ARM_PLT32: - if (!s1->got) - build_got(s1); - sym_index = ELFW(R_SYM)(rel->r_info); - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - if (type != R_ARM_GOTOFF && type != R_ARM_GOTPC - && sym->st_shndx == SHN_UNDEF) { - unsigned long ofs; - /* look at the symbol got offset. If none, then add one */ - if (type == R_ARM_GOT32) - reloc_type = R_ARM_GLOB_DAT; - else - reloc_type = R_ARM_JUMP_SLOT; - ofs = put_got_entry(s1, reloc_type, sym->st_size, - sym->st_info, sym_index); -#ifdef DEBUG_RELOC - printf ("maybegot: %s, %d, %d --> ofs=0x%x\n", - (char *) symtab_section->link->data + sym->st_name, - type, sym->st_shndx, ofs); -#endif - if (type != R_ARM_GOT32) { - addr_t *ptr = (addr_t*)(s1->sections[s->sh_info]->data - + rel->r_offset); - /* x must be signed! */ - int x = *ptr & 0xffffff; - x = (x << 8) >> 8; - x <<= 2; - x += ofs; - x >>= 2; -#ifdef DEBUG_RELOC - printf ("insn=0x%x --> 0x%x (x==0x%x)\n", *ptr, - (*ptr & 0xff000000) | x, x); -#endif - *ptr = (*ptr & 0xff000000) | x; - } - } - break; - case R_ARM_THM_JUMP24: - sym_index = ELFW(R_SYM)(rel->r_info); - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - /* We are relocating a jump from thumb code to arm code */ - if (sym->st_shndx != SHN_UNDEF && !(sym->st_value & 1)) { - int index; - uint8_t *p; - char *name, buf[1024]; - Section *text_section; - - name = (char *) symtab_section->link->data + sym->st_name; - text_section = s1->sections[sym->st_shndx]; - /* Modify reloc to target a thumb stub to switch to ARM */ - snprintf(buf, sizeof(buf), "%s_from_thumb", name); - index = put_elf_sym(symtab_section, - text_section->data_offset + 1, - sym->st_size, sym->st_info, 0, - sym->st_shndx, buf); - rel->r_info = ELFW(R_INFO)(index, type); - /* Create a thumb stub fonction to switch to ARM mode */ - put_elf_reloc(symtab_section, text_section, - text_section->data_offset + 4, R_ARM_JUMP24, - sym_index); - p = section_ptr_add(text_section, 8); - write32le(p, 0x4778); /* bx pc */ - write32le(p+2, 0x46c0); /* nop */ - write32le(p+4, 0xeafffffe); /* b $sym */ - } -#elif defined(TCC_TARGET_ARM64) - //xx Other cases may be required here: - case R_AARCH64_ADR_GOT_PAGE: - case R_AARCH64_LD64_GOT_LO12_NC: - if (!s1->got) - build_got(s1); - sym_index = ELFW(R_SYM)(rel->r_info); - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - reloc_type = R_AARCH64_GLOB_DAT; - put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, - sym_index); - break; - - case R_AARCH64_JUMP26: - case R_AARCH64_CALL26: - if (!s1->got) - build_got(s1); - sym_index = ELFW(R_SYM)(rel->r_info); - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - if (sym->st_shndx == SHN_UNDEF) { - unsigned long ofs; - reloc_type = R_AARCH64_JUMP_SLOT; - ofs = put_got_entry(s1, reloc_type, sym->st_size, - sym->st_info, sym_index); - /* We store the place of the generated PLT slot - in our addend. */ - rel->r_addend += ofs; - } - break; -#elif defined(TCC_TARGET_C67) - case R_C60_GOT32: - case R_C60_GOTOFF: - case R_C60_GOTPC: - case R_C60_PLT32: - if (!s1->got) - build_got(s1); - if (type == R_C60_GOT32 || type == R_C60_PLT32) { - sym_index = ELFW(R_SYM)(rel->r_info); - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - /* look at the symbol got offset. If none, then add one */ - if (type == R_C60_GOT32) - reloc_type = R_C60_GLOB_DAT; - else - reloc_type = R_C60_JMP_SLOT; - put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, - sym_index); - } - break; -#elif defined(TCC_TARGET_X86_64) - case R_X86_64_GOT32: - case R_X86_64_GOTTPOFF: - case R_X86_64_GOTPCREL: - case R_X86_64_GOTPCRELX: - case R_X86_64_REX_GOTPCRELX: - case R_X86_64_PLT32: - sym_index = ELFW(R_SYM)(rel->r_info); - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - if (type == R_X86_64_PLT32 && - ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT) - { - rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32); - break; - } - - if (!s1->got) { - build_got(s1); - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - } - if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL || - type == R_X86_64_GOTPCRELX || - type == R_X86_64_REX_GOTPCRELX || - type == R_X86_64_PLT32) { - unsigned long ofs; - /* look at the symbol got offset. If none, then add one */ - if (type == R_X86_64_PLT32) - reloc_type = R_X86_64_JUMP_SLOT; - else - reloc_type = R_X86_64_GLOB_DAT; - ofs = put_got_entry(s1, reloc_type, sym->st_size, - sym->st_info, sym_index); - if (type == R_X86_64_PLT32) - /* We store the place of the generated PLT slot - in our addend. */ - rel->r_addend += ofs; - } - break; -#else -#error unsupported CPU -#endif - default: - break; - } - } - } -} - -ST_FUNC Section *new_symtab(TCCState *s1, - const char *symtab_name, int sh_type, int sh_flags, - const char *strtab_name, - const char *hash_name, int hash_sh_flags) -{ - Section *symtab, *strtab, *hash; - int *ptr, nb_buckets; - - symtab = new_section(s1, symtab_name, sh_type, sh_flags); - symtab->sh_entsize = sizeof(ElfW(Sym)); - strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags); - put_elf_str(strtab, ""); - symtab->link = strtab; - put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL); - - nb_buckets = 1; - - hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags); - hash->sh_entsize = sizeof(int); - symtab->hash = hash; - hash->link = symtab; - - ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int)); - ptr[0] = nb_buckets; - ptr[1] = 1; - memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int)); - return symtab; -} - -/* put dynamic tag */ -static void put_dt(Section *dynamic, int dt, addr_t val) -{ - ElfW(Dyn) *dyn; - dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn))); - dyn->d_tag = dt; - dyn->d_un.d_val = val; -} - -static void add_init_array_defines(TCCState *s1, const char *section_name) -{ - Section *s; - long end_offset; - char sym_start[1024]; - char sym_end[1024]; - - snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1); - snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1); - - s = find_section(s1, section_name); - if (!s) { - end_offset = 0; - s = data_section; - } else { - end_offset = s->data_offset; - } - - add_elf_sym(symtab_section, - 0, 0, - ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, - s->sh_num, sym_start); - add_elf_sym(symtab_section, - end_offset, 0, - ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, - s->sh_num, sym_end); -} - -static int tcc_add_support(TCCState *s1, const char *filename) -{ - char buf[1024]; - snprintf(buf, sizeof(buf), "%s/%s/%s", s1->tcc_lib_path, - /* an cpu specific path inside tcc_lib_path, mainly for keeping libtcc1.a */ - #ifdef TCC_TARGET_I386 - "i386" - #endif - #ifdef TCC_TARGET_X86_64 - "x86-64" - #endif - #ifdef TCC_TARGET_ARM - "arm" - #endif - #ifdef TCC_TARGET_ARM64 - "arm64" - #endif - #ifdef TCC_TARGET_C67 - "C67" - #endif - ,filename); - - return tcc_add_file(s1, buf, TCC_FILETYPE_BINARY); -} - -ST_FUNC void tcc_add_bcheck(TCCState *s1) -{ -#ifdef CONFIG_TCC_BCHECK - addr_t *ptr; - - if (0 == s1->do_bounds_check) - return; - - /* XXX: add an object file to do that */ - ptr = section_ptr_add(bounds_section, sizeof(*ptr)); - *ptr = 0; - add_elf_sym(symtab_section, 0, 0, - ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, - bounds_section->sh_num, "__bounds_start"); - if (s1->output_type != TCC_OUTPUT_MEMORY) { - /* add 'call __bound_init()' in .init section */ - - /* XXX not called on MSYS, reason is unknown. For this - case a call to __bound_init is performed in bcheck.c - when __bound_ptr_add, __bound_new_region, - __bound_delete_region called */ - - int sym_index = find_elf_sym(symtab_section, "__bound_init"); - if (sym_index) { - Section *init_section = find_section(s1, ".init"); - unsigned char *pinit = section_ptr_add(init_section, 5); - pinit[0] = 0xe8; - write32le(pinit + 1, -4); - put_elf_reloc(symtab_section, init_section, - init_section->data_offset - 4, R_386_PC32, sym_index); - } - else - tcc_warning("__bound_init not defined"); - } -#endif -} - -/* add tcc runtime libraries */ -ST_FUNC void tcc_add_runtime(TCCState *s1) -{ - tcc_add_pragma_libs(s1); - - /* add libc */ - if (!s1->nostdlib) { - tcc_add_library(s1, "c"); -#ifdef CONFIG_USE_LIBGCC - if (!s1->static_link) { - tcc_add_file(s1, TCC_LIBGCC, TCC_FILETYPE_BINARY); - } -#endif - tcc_add_support(s1, "libtcc1.a"); - } - - /* tcc_add_bcheck tries to relocate a call to __bound_init in _init so - libtcc1.a must be loaded before for __bound_init to be defined and - crtn.o must be loaded after to not finalize _init too early. */ - tcc_add_bcheck(s1); - - if (!s1->nostdlib) { - /* add crt end if not memory output */ - if (s1->output_type != TCC_OUTPUT_MEMORY) - tcc_add_crt(s1, "crtn.o"); - } -} - -/* add various standard linker symbols (must be done after the - sections are filled (for example after allocating common - symbols)) */ -ST_FUNC void tcc_add_linker_symbols(TCCState *s1) -{ - char buf[1024]; - int i; - Section *s; - - add_elf_sym(symtab_section, - text_section->data_offset, 0, - ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, - text_section->sh_num, "_etext"); - add_elf_sym(symtab_section, - data_section->data_offset, 0, - ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, - data_section->sh_num, "_edata"); - add_elf_sym(symtab_section, - bss_section->data_offset, 0, - ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, - bss_section->sh_num, "_end"); - /* horrible new standard ldscript defines */ - add_init_array_defines(s1, ".preinit_array"); - add_init_array_defines(s1, ".init_array"); - add_init_array_defines(s1, ".fini_array"); - - /* add start and stop symbols for sections whose name can be - expressed in C */ - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; - if (s->sh_type == SHT_PROGBITS && - (s->sh_flags & SHF_ALLOC)) { - const char *p; - int ch; - - /* check if section name can be expressed in C */ - p = s->name; - for(;;) { - ch = *p; - if (!ch) - break; - if (!isid(ch) && !isnum(ch)) - goto next_sec; - p++; - } - snprintf(buf, sizeof(buf), "__start_%s", s->name); - add_elf_sym(symtab_section, - 0, 0, - ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, - s->sh_num, buf); - snprintf(buf, sizeof(buf), "__stop_%s", s->name); - add_elf_sym(symtab_section, - s->data_offset, 0, - ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, - s->sh_num, buf); - } - next_sec: ; - } -} - -static void tcc_output_binary(TCCState *s1, FILE *f, - const int *sec_order) -{ - Section *s; - int i, offset, size; - - offset = 0; - for(i=1;inb_sections;i++) { - s = s1->sections[sec_order[i]]; - if (s->sh_type != SHT_NOBITS && - (s->sh_flags & SHF_ALLOC)) { - while (offset < s->sh_offset) { - fputc(0, f); - offset++; - } - size = s->sh_size; - fwrite(s->data, 1, size, f); - offset += size; - } - } -} - -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -#define HAVE_PHDR 1 -#define EXTRA_RELITEMS 14 - -/* move the relocation value from .dynsym to .got */ -void patch_dynsym_undef(TCCState *s1, Section *s) -{ - uint32_t *gotd = (void *)s1->got->data; - ElfW(Sym) *sym; - - gotd += 3; /* dummy entries in .got */ - /* relocate symbols in .dynsym */ - for_each_elem(s, 1, sym, ElfW(Sym)) { - if (sym->st_shndx == SHN_UNDEF) { - *gotd++ = sym->st_value + 6; /* XXX 6 is magic ? */ - sym->st_value = 0; - } - } -} -#else -#define HAVE_PHDR 1 -#define EXTRA_RELITEMS 9 - -/* zero plt offsets of weak symbols in .dynsym */ -void patch_dynsym_undef(TCCState *s1, Section *s) -{ - ElfW(Sym) *sym; - - for_each_elem(s, 1, sym, ElfW(Sym)) - if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK) - sym->st_value = 0; -} -#endif - -ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel) -{ - int sym_index = ELFW(R_SYM) (rel->r_info); - ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index]; - unsigned long offset; - - if (sym_index >= s1->nb_sym_attrs) - return; - offset = s1->sym_attrs[sym_index].got_offset; - section_reserve(s1->got, offset + PTR_SIZE); -#ifdef TCC_TARGET_X86_64 - /* only works for x86-64 */ - write32le(s1->got->data + offset + 4, sym->st_value >> 32); -#endif - write32le(s1->got->data + offset, sym->st_value & 0xffffffff); -} - -/* Perform relocation to GOT or PLT entries */ -ST_FUNC void fill_got(TCCState *s1) -{ - Section *s; - ElfW_Rel *rel; - int i; - - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; - if (s->sh_type != SHT_RELX) - continue; - /* no need to handle got relocations */ - if (s->link != symtab_section) - continue; - for_each_elem(s, 0, rel, ElfW_Rel) { - switch (ELFW(R_TYPE) (rel->r_info)) { - case R_X86_64_GOT32: - case R_X86_64_GOTPCREL: - case R_X86_64_GOTPCRELX: - case R_X86_64_REX_GOTPCRELX: - case R_X86_64_PLT32: - fill_got_entry(s1, rel); - break; - } - } - } -} - -/* Bind symbols of executable: resolve undefined symbols from exported symbols - in shared libraries and export non local defined symbols to shared libraries - if -rdynamic switch was given on command line */ -static void bind_exe_dynsyms(TCCState *s1) -{ - const char *name; - int sym_index, index; - ElfW(Sym) *sym, *esym; - int type; - - /* Resolve undefined symbols from dynamic symbols. When there is a match: - - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT - - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */ - for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { - if (sym->st_shndx == SHN_UNDEF) { - name = (char *) symtab_section->link->data + sym->st_name; - sym_index = find_elf_sym(s1->dynsymtab_section, name); - if (sym_index) { - esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index]; - type = ELFW(ST_TYPE)(esym->st_info); - if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) { - /* Indirect functions shall have STT_FUNC type in executable - * dynsym section. Indeed, a dlsym call following a lazy - * resolution would pick the symbol value from the - * executable dynsym entry which would contain the address - * of the function wanted by the caller of dlsym instead of - * the address of the function that would return that - * address */ - put_got_entry(s1, R_JMP_SLOT, esym->st_size, - ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), - sym - (ElfW(Sym) *)symtab_section->data); - } else if (type == STT_OBJECT) { - unsigned long offset; - ElfW(Sym) *dynsym; - offset = bss_section->data_offset; - /* XXX: which alignment ? */ - offset = (offset + 16 - 1) & -16; - index = put_elf_sym(s1->dynsym, offset, esym->st_size, - esym->st_info, 0, bss_section->sh_num, - name); - /* Ensure R_COPY works for weak symbol aliases */ - if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) { - for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) { - if ((dynsym->st_value == esym->st_value) - && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) { - char *dynname = (char *) s1->dynsymtab_section->link->data - + dynsym->st_name; - put_elf_sym(s1->dynsym, offset, dynsym->st_size, - dynsym->st_info, 0, - bss_section->sh_num, dynname); - break; - } - } - } - put_elf_reloc(s1->dynsym, bss_section, - offset, R_COPY, index); - offset += esym->st_size; - bss_section->data_offset = offset; - } - } else { - /* STB_WEAK undefined symbols are accepted */ - /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */ - if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK || - !strcmp(name, "_fp_hw")) { - } else { - tcc_error_noabort("undefined symbol '%s'", name); - } - } - } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { - /* if -rdynamic option, then export all non local symbols */ - name = (char *) symtab_section->link->data + sym->st_name; - put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info, - 0, sym->st_shndx, name); - } - } -} - -/* Bind symbols of libraries: export non local symbols of executable that - resolve undefined symbols of shared libraries */ -static void bind_libs_dynsyms(TCCState *s1) -{ - const char *name; - int sym_index; - ElfW(Sym) *sym, *esym; - - /* now look at unresolved dynamic symbols and export - corresponding symbol */ - for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) { - name = (char *) s1->dynsymtab_section->link->data + esym->st_name; - sym_index = find_elf_sym(symtab_section, name); - if (sym_index) { - /* XXX: avoid adding a symbol if already present because of - -rdynamic ? */ - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - if (sym->st_shndx != SHN_UNDEF) - put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, - sym->st_info, 0, sym->st_shndx, name); - } else if (esym->st_shndx == SHN_UNDEF) { - /* weak symbols can stay undefined */ - if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK) - tcc_warning("undefined dynamic symbol '%s'", name); - } - } -} - -/* Export all non local symbols (for shared libraries) */ -static void export_global_syms(TCCState *s1) -{ - int nb_syms, dynindex, index; - const char *name; - ElfW(Sym) *sym; - - nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym)); - s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms); - for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { - if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { - name = (char *) symtab_section->link->data + sym->st_name; - dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, - sym->st_info, 0, sym->st_shndx, name); - index = sym - (ElfW(Sym) *) symtab_section->data; - s1->symtab_to_dynsym[index] = dynindex; - } - } -} - -/* relocate the PLT: compute addresses and offsets in the PLT now that final - address for PLT and GOT are known (see fill_program_header) */ -ST_FUNC void relocate_plt(TCCState *s1) -{ - uint8_t *p, *p_end; - - if (!s1->plt) - return; - - p = s1->plt->data; - p_end = p + s1->plt->data_offset; - if (p < p_end) { -#if defined(TCC_TARGET_I386) - write32le(p + 2, read32le(p + 2) + s1->got->sh_addr); - write32le(p + 8, read32le(p + 8) + s1->got->sh_addr); - p += 16; - while (p < p_end) { - write32le(p + 2, read32le(p + 2) + s1->got->sh_addr); - p += 16; - } -#elif defined(TCC_TARGET_X86_64) - int x = s1->got->sh_addr - s1->plt->sh_addr - 6; - write32le(p + 2, read32le(p + 2) + x); - write32le(p + 8, read32le(p + 8) + x - 6); - p += 16; - while (p < p_end) { - write32le(p + 2, read32le(p + 2) + x + s1->plt->data - p); - p += 16; - } -#elif defined(TCC_TARGET_ARM) - int x; - x=s1->got->sh_addr - s1->plt->sh_addr - 12; - p += 16; - while (p < p_end) { - if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */ - p += 4; - write32le(p + 12, x + read32le(p + 12) + s1->plt->data - p); - p += 16; - } -#elif defined(TCC_TARGET_ARM64) - uint64_t plt = s1->plt->sh_addr; - uint64_t got = s1->got->sh_addr; - uint64_t off = (got >> 12) - (plt >> 12); - if ((off + ((uint32_t)1 << 20)) >> 21) - tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off, got, plt); - write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]! - write32le(p + 4, (0x90000010 | // adrp x16,... - (off & 0x1ffffc) << 3 | (off & 3) << 29)); - write32le(p + 8, (0xf9400211 | // ldr x17,[x16,#...] - (got & 0xff8) << 7)); - write32le(p + 12, (0x91000210 | // add x16,x16,#... - (got & 0xfff) << 10)); - write32le(p + 16, 0xd61f0220); // br x17 - write32le(p + 20, 0xd503201f); // nop - write32le(p + 24, 0xd503201f); // nop - write32le(p + 28, 0xd503201f); // nop - p += 32; - while (p < p_end) { - uint64_t pc = plt + (p - s1->plt->data); - uint64_t addr = got + read64le(p); - uint64_t off = (addr >> 12) - (pc >> 12); - if ((off + ((uint32_t)1 << 20)) >> 21) - tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off, addr, pc); - write32le(p, (0x90000010 | // adrp x16,... - (off & 0x1ffffc) << 3 | (off & 3) << 29)); - write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...] - (addr & 0xff8) << 7)); - write32le(p + 8, (0x91000210 | // add x16,x16,#... - (addr & 0xfff) << 10)); - write32le(p + 12, 0xd61f0220); // br x17 - p += 16; - } -#elif defined(TCC_TARGET_C67) - /* XXX: TODO */ -#else -#error unsupported CPU -#endif - } -} - -/* Allocate strings for section names and decide if an unallocated section - should be output. - - NOTE: the strsec section comes last, so its size is also correct ! */ -static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec) -{ - int i; - Section *s; - - /* Allocate strings for section names */ - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; - s->sh_name = put_elf_str(strsec, s->name); - /* when generating a DLL, we include relocations but we may - patch them */ - if (file_type == TCC_OUTPUT_DLL && - s->sh_type == SHT_RELX && - !(s->sh_flags & SHF_ALLOC)) { - /* gr: avoid bogus relocs for empty (debug) sections */ - if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) - prepare_dynamic_rel(s1, s); - else if (s1->do_debug) - s->sh_size = s->data_offset; - } else if (s1->do_debug || - file_type == TCC_OUTPUT_OBJ || - file_type == TCC_OUTPUT_EXE || - (s->sh_flags & SHF_ALLOC) || - i == (s1->nb_sections - 1)) { - /* we output all sections if debug or object file */ - s->sh_size = s->data_offset; - } - } -} - -/* Info to be copied in dynamic section */ -struct dyn_inf { - Section *dynamic; - Section *dynstr; - unsigned long dyn_rel_off; - addr_t rel_addr; - addr_t rel_size; -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - addr_t bss_addr; - addr_t bss_size; -#endif -}; - -/* Assign sections to segments and decide how are sections laid out when loaded - in memory. This function also fills corresponding program headers. */ -static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, - Section *interp, Section* strsec, - struct dyn_inf *dyninf, int *sec_order) -{ - int i, j, k, file_type, sh_order_index, file_offset; - unsigned long s_align; - long long tmp; - addr_t addr; - ElfW(Phdr) *ph; - Section *s; - - file_type = s1->output_type; - sh_order_index = 1; - file_offset = 0; - if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) - file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr)); - s_align = ELF_PAGE_SIZE; - if (s1->section_align) - s_align = s1->section_align; - - if (phnum > 0) { - if (s1->has_text_addr) { - int a_offset, p_offset; - addr = s1->text_addr; - /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset % - ELF_PAGE_SIZE */ - a_offset = (int) (addr & (s_align - 1)); - p_offset = file_offset & (s_align - 1); - if (a_offset < p_offset) - a_offset += s_align; - file_offset += (a_offset - p_offset); - } else { - if (file_type == TCC_OUTPUT_DLL) - addr = 0; - else - addr = ELF_START_ADDR; - /* compute address after headers */ - addr += (file_offset & (s_align - 1)); - } - - ph = &phdr[0]; - /* Leave one program headers for the program interpreter and one for - the program header table itself if needed. These are done later as - they require section layout to be done first. */ - if (interp) - ph += 1 + HAVE_PHDR; - - /* dynamic relocation table information, for .dynamic section */ - dyninf->rel_addr = dyninf->rel_size = 0; -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - dyninf->bss_addr = dyninf->bss_size = 0; -#endif - - for(j = 0; j < 2; j++) { - ph->p_type = PT_LOAD; - if (j == 0) - ph->p_flags = PF_R | PF_X; - else - ph->p_flags = PF_R | PF_W; - ph->p_align = s_align; - - /* Decide the layout of sections loaded in memory. This must - be done before program headers are filled since they contain - info about the layout. We do the following ordering: interp, - symbol tables, relocations, progbits, nobits */ - /* XXX: do faster and simpler sorting */ - for(k = 0; k < 5; k++) { - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; - /* compute if section should be included */ - if (j == 0) { - if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != - SHF_ALLOC) - continue; - } else { - if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != - (SHF_ALLOC | SHF_WRITE)) - continue; - } - if (s == interp) { - if (k != 0) - continue; - } else if (s->sh_type == SHT_DYNSYM || - s->sh_type == SHT_STRTAB || - s->sh_type == SHT_HASH) { - if (k != 1) - continue; - } else if (s->sh_type == SHT_RELX) { - if (k != 2) - continue; - } else if (s->sh_type == SHT_NOBITS) { - if (k != 4) - continue; - } else { - if (k != 3) - continue; - } - sec_order[sh_order_index++] = i; - - /* section matches: we align it and add its size */ - tmp = addr; - addr = (addr + s->sh_addralign - 1) & - ~(s->sh_addralign - 1); - file_offset += (int) ( addr - tmp ); - s->sh_offset = file_offset; - s->sh_addr = addr; - - /* update program header infos */ - if (ph->p_offset == 0) { - ph->p_offset = file_offset; - ph->p_vaddr = addr; - ph->p_paddr = ph->p_vaddr; - } - /* update dynamic relocation infos */ - if (s->sh_type == SHT_RELX) { -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - if (!strcmp(strsec->data + s->sh_name, ".rel.got")) { - dyninf->rel_addr = addr; - dyninf->rel_size += s->sh_size; /* XXX only first rel. */ - } - if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) { - dyninf->bss_addr = addr; - dyninf->bss_size = s->sh_size; /* XXX only first rel. */ - } -#else - if (dyninf->rel_size == 0) - dyninf->rel_addr = addr; - dyninf->rel_size += s->sh_size; -#endif - } - addr += s->sh_size; - if (s->sh_type != SHT_NOBITS) - file_offset += s->sh_size; - } - } - if (j == 0) { - /* Make the first PT_LOAD segment include the program - headers itself (and the ELF header as well), it'll - come out with same memory use but will make various - tools like binutils strip work better. */ - ph->p_offset &= ~(ph->p_align - 1); - ph->p_vaddr &= ~(ph->p_align - 1); - ph->p_paddr &= ~(ph->p_align - 1); - } - ph->p_filesz = file_offset - ph->p_offset; - ph->p_memsz = addr - ph->p_vaddr; - ph++; - if (j == 0) { - if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) { - /* if in the middle of a page, we duplicate the page in - memory so that one copy is RX and the other is RW */ - if ((addr & (s_align - 1)) != 0) - addr += s_align; - } else { - addr = (addr + s_align - 1) & ~(s_align - 1); - file_offset = (file_offset + s_align - 1) & ~(s_align - 1); - } - } - } - } - - /* all other sections come after */ - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; - if (phnum > 0 && (s->sh_flags & SHF_ALLOC)) - continue; - sec_order[sh_order_index++] = i; - - file_offset = (file_offset + s->sh_addralign - 1) & - ~(s->sh_addralign - 1); - s->sh_offset = file_offset; - if (s->sh_type != SHT_NOBITS) - file_offset += s->sh_size; - } - - return file_offset; -} - -static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp, - Section *dynamic) -{ - ElfW(Phdr) *ph; - - /* if interpreter, then add corresponding program header */ - if (interp) { - ph = &phdr[0]; - - if (HAVE_PHDR) - { - int len = phnum * sizeof(ElfW(Phdr)); - - ph->p_type = PT_PHDR; - ph->p_offset = sizeof(ElfW(Ehdr)); - ph->p_vaddr = interp->sh_addr - len; - ph->p_paddr = ph->p_vaddr; - ph->p_filesz = ph->p_memsz = len; - ph->p_flags = PF_R | PF_X; - ph->p_align = 4; /* interp->sh_addralign; */ - ph++; - } - - ph->p_type = PT_INTERP; - ph->p_offset = interp->sh_offset; - ph->p_vaddr = interp->sh_addr; - ph->p_paddr = ph->p_vaddr; - ph->p_filesz = interp->sh_size; - ph->p_memsz = interp->sh_size; - ph->p_flags = PF_R; - ph->p_align = interp->sh_addralign; - } - - /* if dynamic section, then add corresponding program header */ - if (dynamic) { - ph = &phdr[phnum - 1]; - - ph->p_type = PT_DYNAMIC; - ph->p_offset = dynamic->sh_offset; - ph->p_vaddr = dynamic->sh_addr; - ph->p_paddr = ph->p_vaddr; - ph->p_filesz = dynamic->sh_size; - ph->p_memsz = dynamic->sh_size; - ph->p_flags = PF_R | PF_W; - ph->p_align = dynamic->sh_addralign; - } -} - -/* Fill the dynamic section with tags describing the address and size of - sections */ -static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf) -{ - Section *dynamic; - - dynamic = dyninf->dynamic; - - /* put dynamic section entries */ - dynamic->data_offset = dyninf->dyn_rel_off; - put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr); - put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr); - put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr); - put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset); - put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym))); -#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) - put_dt(dynamic, DT_RELA, dyninf->rel_addr); - put_dt(dynamic, DT_RELASZ, dyninf->rel_size); - put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel)); -#else -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr); - put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size); - put_dt(dynamic, DT_JMPREL, dyninf->rel_addr); - put_dt(dynamic, DT_PLTREL, DT_REL); - put_dt(dynamic, DT_REL, dyninf->bss_addr); - put_dt(dynamic, DT_RELSZ, dyninf->bss_size); -#else - put_dt(dynamic, DT_REL, dyninf->rel_addr); - put_dt(dynamic, DT_RELSZ, dyninf->rel_size); - put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel)); -#endif -#endif - if (s1->do_debug) - put_dt(dynamic, DT_DEBUG, 0); - put_dt(dynamic, DT_NULL, 0); -} - -/* Relocate remaining sections and symbols (that is those not related to - dynamic linking) */ -static int final_sections_reloc(TCCState *s1) -{ - int i; - Section *s; - - relocate_syms(s1, 0); - - if (s1->nb_errors != 0) - return -1; - - /* relocate sections */ - /* XXX: ignore sections with allocated relocations ? */ - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; -#ifdef TCC_TARGET_I386 - if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr - /* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC - checking is removed */ -#else - if (s->reloc && s != s1->got) - /* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */ -#endif - relocate_section(s1, s); - } - - /* relocate relocation entries if the relocation tables are - allocated in the executable */ - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; - if ((s->sh_flags & SHF_ALLOC) && - s->sh_type == SHT_RELX) { - relocate_rel(s1, s); - } - } - return 0; -} - -/* Create an ELF file on disk. - This function handle ELF specific layout requirements */ -static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, - int file_offset, int *sec_order) -{ - int i, shnum, offset, size, file_type; - Section *s; - ElfW(Ehdr) ehdr; - ElfW(Shdr) shdr, *sh; - - file_type = s1->output_type; - shnum = s1->nb_sections; - - memset(&ehdr, 0, sizeof(ehdr)); - - if (phnum > 0) { - ehdr.e_phentsize = sizeof(ElfW(Phdr)); - ehdr.e_phnum = phnum; - ehdr.e_phoff = sizeof(ElfW(Ehdr)); - } - - /* align to 4 */ - file_offset = (file_offset + 3) & -4; - - /* fill header */ - ehdr.e_ident[0] = ELFMAG0; - ehdr.e_ident[1] = ELFMAG1; - ehdr.e_ident[2] = ELFMAG2; - ehdr.e_ident[3] = ELFMAG3; - ehdr.e_ident[4] = ELFCLASSW; - ehdr.e_ident[5] = ELFDATA2LSB; - ehdr.e_ident[6] = EV_CURRENT; -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD; -#endif -#ifdef TCC_TARGET_ARM -#ifdef TCC_ARM_EABI - ehdr.e_ident[EI_OSABI] = 0; - ehdr.e_flags = EF_ARM_EABI_VER4; - if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL) - ehdr.e_flags |= EF_ARM_HASENTRY; - if (s1->float_abi == ARM_HARD_FLOAT) - ehdr.e_flags |= EF_ARM_VFP_FLOAT; - else - ehdr.e_flags |= EF_ARM_SOFT_FLOAT; -#else - ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM; -#endif -#endif - switch(file_type) { - default: - case TCC_OUTPUT_EXE: - ehdr.e_type = ET_EXEC; - ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1); - break; - case TCC_OUTPUT_DLL: - ehdr.e_type = ET_DYN; - ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */ - break; - case TCC_OUTPUT_OBJ: - ehdr.e_type = ET_REL; - break; - } - ehdr.e_machine = EM_TCC_TARGET; - ehdr.e_version = EV_CURRENT; - ehdr.e_shoff = file_offset; - ehdr.e_ehsize = sizeof(ElfW(Ehdr)); - ehdr.e_shentsize = sizeof(ElfW(Shdr)); - ehdr.e_shnum = shnum; - ehdr.e_shstrndx = shnum - 1; - - fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f); - fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f); - offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr)); - - sort_syms(s1, symtab_section); - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[sec_order[i]]; - if (s->sh_type != SHT_NOBITS) { - if (s->sh_type == SHT_DYNSYM) - patch_dynsym_undef(s1, s); - while (offset < s->sh_offset) { - fputc(0, f); - offset++; - } - size = s->sh_size; - if (size) - fwrite(s->data, 1, size, f); - offset += size; - } - } - - /* output section headers */ - while (offset < ehdr.e_shoff) { - fputc(0, f); - offset++; - } - - for(i = 0; i < s1->nb_sections; i++) { - sh = &shdr; - memset(sh, 0, sizeof(ElfW(Shdr))); - s = s1->sections[i]; - if (s) { - sh->sh_name = s->sh_name; - sh->sh_type = s->sh_type; - sh->sh_flags = s->sh_flags; - sh->sh_entsize = s->sh_entsize; - sh->sh_info = s->sh_info; - if (s->link) - sh->sh_link = s->link->sh_num; - sh->sh_addralign = s->sh_addralign; - sh->sh_addr = s->sh_addr; - sh->sh_offset = s->sh_offset; - sh->sh_size = s->sh_size; - } - fwrite(sh, 1, sizeof(ElfW(Shdr)), f); - } -} - -/* Write an elf, coff or "binary" file */ -static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum, - ElfW(Phdr) *phdr, int file_offset, int *sec_order) -{ - int fd, mode, file_type; - FILE *f; - - file_type = s1->output_type; - if (file_type == TCC_OUTPUT_OBJ) - mode = 0666; - else - mode = 0777; - unlink(filename); - fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode); - if (fd < 0) { - tcc_error_noabort("could not write '%s'", filename); - return -1; - } - f = fdopen(fd, "wb"); - if (s1->verbose) - printf("<- %s\n", filename); - -#ifdef TCC_TARGET_COFF - if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) - tcc_output_coff(s1, f); - else -#endif - if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) - tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order); - else - tcc_output_binary(s1, f, sec_order); - fclose(f); - - return 0; -} - -/* Output an elf, coff or binary file */ -/* XXX: suppress unneeded sections */ -static int elf_output_file(TCCState *s1, const char *filename) -{ - int i, ret, phnum, shnum, file_type, file_offset, *sec_order; - struct dyn_inf dyninf; - ElfW(Phdr) *phdr; - ElfW(Sym) *sym; - Section *strsec, *interp, *dynamic, *dynstr; - - file_type = s1->output_type; - s1->nb_errors = 0; - - /* if linking, also link in runtime libraries (libc, libgcc, etc.) */ - if (file_type != TCC_OUTPUT_OBJ) { - tcc_add_runtime(s1); - } - - phdr = NULL; - sec_order = NULL; - interp = dynamic = dynstr = NULL; /* avoid warning */ - dyninf.dyn_rel_off = 0; /* avoid warning */ - - if (file_type != TCC_OUTPUT_OBJ) { - relocate_common_syms(); - - tcc_add_linker_symbols(s1); - - if (!s1->static_link) { - if (file_type == TCC_OUTPUT_EXE) { - char *ptr; - /* allow override the dynamic loader */ - const char *elfint = getenv("LD_SO"); - if (elfint == NULL) - elfint = DEFAULT_ELFINTERP(s1); - /* add interpreter section only if executable */ - interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC); - interp->sh_addralign = 1; - ptr = section_ptr_add(interp, 1 + strlen(elfint)); - strcpy(ptr, elfint); - } - - /* add dynamic symbol table */ - s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC, - ".dynstr", - ".hash", SHF_ALLOC); - dynstr = s1->dynsym->link; - - /* add dynamic section */ - dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC, - SHF_ALLOC | SHF_WRITE); - dynamic->link = dynstr; - dynamic->sh_entsize = sizeof(ElfW(Dyn)); - - build_got(s1); - - if (file_type == TCC_OUTPUT_EXE) { - bind_exe_dynsyms(s1); - - if (s1->nb_errors) { - ret = -1; - goto the_end; - } - - bind_libs_dynsyms(s1); - } else /* shared library case: simply export all global symbols */ - export_global_syms(s1); - - build_got_entries(s1); - - /* add a list of needed dlls */ - for(i = 0; i < s1->nb_loaded_dlls; i++) { - DLLReference *dllref = s1->loaded_dlls[i]; - if (dllref->level == 0) - put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name)); - } - - if (s1->rpath) - put_dt(dynamic, DT_RPATH, put_elf_str(dynstr, s1->rpath)); - - /* XXX: currently, since we do not handle PIC code, we - must relocate the readonly segments */ - if (file_type == TCC_OUTPUT_DLL) { - if (s1->soname) - put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname)); - put_dt(dynamic, DT_TEXTREL, 0); - } - - if (s1->symbolic) - put_dt(dynamic, DT_SYMBOLIC, 0); - - /* add necessary space for other entries */ - dyninf.dyn_rel_off = dynamic->data_offset; - dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS; - } else { - /* still need to build got entries in case of static link */ - build_got_entries(s1); - } - } - - /* we add a section for symbols */ - strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0); - put_elf_str(strsec, ""); - - /* compute number of sections */ - shnum = s1->nb_sections; - - /* this array is used to reorder sections in the output file */ - sec_order = tcc_malloc(sizeof(int) * shnum); - sec_order[0] = 0; - - /* compute number of program headers */ - switch(file_type) { - default: - case TCC_OUTPUT_OBJ: - phnum = 0; - break; - case TCC_OUTPUT_EXE: - if (!s1->static_link) - phnum = 4 + HAVE_PHDR; - else - phnum = 2; - break; - case TCC_OUTPUT_DLL: - phnum = 3; - break; - } - - /* Allocate strings for section names */ - alloc_sec_names(s1, file_type, strsec); - - /* allocate program segment headers */ - phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr))); - - /* compute section to program header mapping */ - file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf, - sec_order); - - /* Fill remaining program header and finalize relocation related to dynamic - linking. */ - if (phnum > 0) { - fill_unloadable_phdr(phdr, phnum, interp, dynamic); - if (dynamic) { - dyninf.dynamic = dynamic; - dyninf.dynstr = dynstr; - - fill_dynamic(s1, &dyninf); - - /* put in GOT the dynamic section address and relocate PLT */ - write32le(s1->got->data, dynamic->sh_addr); - if (file_type == TCC_OUTPUT_EXE -#if defined(TCC_OUTPUT_DLL_WITH_PLT) - || file_type == TCC_OUTPUT_DLL -#endif - ) - relocate_plt(s1); - - /* relocate symbols in .dynsym now that final addresses are known */ - for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) { - if (sym->st_shndx == SHN_UNDEF) { - /* relocate to PLT if symbol corresponds to a PLT entry, - but not if it's a weak symbol */ - if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK) - sym->st_value = 0; - else if (sym->st_value) - sym->st_value += s1->plt->sh_addr; - } else if (sym->st_shndx < SHN_LORESERVE) { - /* do symbol relocation */ - sym->st_value += s1->sections[sym->st_shndx]->sh_addr; - } - } - } - } - - /* if building executable or DLL, then relocate each section - except the GOT which is already relocated */ - if (file_type != TCC_OUTPUT_OBJ) { - ret = final_sections_reloc(s1); - if (ret) - goto the_end; - } - - /* Perform relocation to GOT or PLT entries */ - if (file_type == TCC_OUTPUT_EXE && s1->static_link) - fill_got(s1); - - /* Create the ELF file with name 'filename' */ - ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order); - if (s1->do_strip) { - int rc; - const char *strip_cmd = "sstrip "; // super strip utility from ELFkickers - const char *null_dev = " 2> /dev/null"; - char buf[1050]; - snprintf(buf, sizeof(buf), "%s%s%s", strip_cmd, filename, null_dev); - rc = system(buf); - if (rc) - system(buf+1); // call a strip utility from binutils - } - the_end: - tcc_free(s1->symtab_to_dynsym); - tcc_free(sec_order); - tcc_free(phdr); - tcc_free(s1->sym_attrs); - s1->sym_attrs = NULL; - return ret; -} - -LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename) -{ - int ret; -#ifdef TCC_TARGET_PE - if (s->output_type != TCC_OUTPUT_OBJ) { - ret = pe_output_file(s, filename); - } else -#endif - ret = elf_output_file(s, filename); - return ret; -} - -static void *load_data(int fd, unsigned long file_offset, unsigned long size) -{ - void *data; - - data = tcc_malloc(size); - lseek(fd, file_offset, SEEK_SET); - read(fd, data, size); - return data; -} - -typedef struct SectionMergeInfo { - Section *s; /* corresponding existing section */ - unsigned long offset; /* offset of the new section in the existing section */ - uint8_t new_section; /* true if section 's' was added */ - uint8_t link_once; /* true if link once section */ -} SectionMergeInfo; - -/* load an object file and merge it with current files */ -/* XXX: handle correctly stab (debug) info */ -ST_FUNC int tcc_load_object_file(TCCState *s1, - int fd, unsigned long file_offset) -{ - ElfW(Ehdr) ehdr; - ElfW(Shdr) *shdr, *sh; - int size, i, j, offset, offseti, nb_syms, sym_index, ret; - unsigned char *strsec, *strtab; - int *old_to_new_syms; - char *sh_name, *name; - SectionMergeInfo *sm_table, *sm; - ElfW(Sym) *sym, *symtab; - ElfW_Rel *rel; - Section *s; - - int stab_index; - int stabstr_index; - - stab_index = stabstr_index = 0; - - if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) - goto fail1; - if (ehdr.e_ident[0] != ELFMAG0 || - ehdr.e_ident[1] != ELFMAG1 || - ehdr.e_ident[2] != ELFMAG2 || - ehdr.e_ident[3] != ELFMAG3) - goto fail1; - /* test if object file */ - if (ehdr.e_type != ET_REL) - goto fail1; - /* test CPU specific stuff */ - if (ehdr.e_ident[5] != ELFDATA2LSB || - ehdr.e_machine != EM_TCC_TARGET) { - fail1: - tcc_error_noabort("invalid object file"); - return -1; - } - /* read sections */ - shdr = load_data(fd, file_offset + ehdr.e_shoff, - sizeof(ElfW(Shdr)) * ehdr.e_shnum); - sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum); - - /* load section names */ - sh = &shdr[ehdr.e_shstrndx]; - strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size); - - /* load symtab and strtab */ - old_to_new_syms = NULL; - symtab = NULL; - strtab = NULL; - nb_syms = 0; - for(i = 1; i < ehdr.e_shnum; i++) { - sh = &shdr[i]; - if (sh->sh_type == SHT_SYMTAB) { - if (symtab) { - tcc_error_noabort("object must contain only one symtab"); - fail: - ret = -1; - goto the_end; - } - nb_syms = sh->sh_size / sizeof(ElfW(Sym)); - symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size); - sm_table[i].s = symtab_section; - - /* now load strtab */ - sh = &shdr[sh->sh_link]; - strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size); - } - } - - /* now examine each section and try to merge its content with the - ones in memory */ - for(i = 1; i < ehdr.e_shnum; i++) { - /* no need to examine section name strtab */ - if (i == ehdr.e_shstrndx) - continue; - sh = &shdr[i]; - sh_name = (char *) strsec + sh->sh_name; - /* ignore sections types we do not handle */ - if (sh->sh_type != SHT_PROGBITS && - sh->sh_type != SHT_RELX && -#ifdef TCC_ARM_EABI - sh->sh_type != SHT_ARM_EXIDX && -#endif - sh->sh_type != SHT_NOBITS && - sh->sh_type != SHT_PREINIT_ARRAY && - sh->sh_type != SHT_INIT_ARRAY && - sh->sh_type != SHT_FINI_ARRAY && - strcmp(sh_name, ".stabstr") - ) - continue; - if (sh->sh_addralign < 1) - sh->sh_addralign = 1; - /* find corresponding section, if any */ - for(j = 1; j < s1->nb_sections;j++) { - s = s1->sections[j]; - if (!strcmp(s->name, sh_name)) { - if (!strncmp(sh_name, ".gnu.linkonce", - sizeof(".gnu.linkonce") - 1)) { - /* if a 'linkonce' section is already present, we - do not add it again. It is a little tricky as - symbols can still be defined in - it. */ - sm_table[i].link_once = 1; - goto next; - } else { - goto found; - } - } - } - /* not found: create new section */ - s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags); - /* take as much info as possible from the section. sh_link and - sh_info will be updated later */ - s->sh_addralign = sh->sh_addralign; - s->sh_entsize = sh->sh_entsize; - sm_table[i].new_section = 1; - found: - if (sh->sh_type != s->sh_type) { - tcc_error_noabort("invalid section type"); - goto fail; - } - - /* align start of section */ - offset = s->data_offset; - - if (0 == strcmp(sh_name, ".stab")) { - stab_index = i; - goto no_align; - } - if (0 == strcmp(sh_name, ".stabstr")) { - stabstr_index = i; - goto no_align; - } - - size = sh->sh_addralign - 1; - offset = (offset + size) & ~size; - if (sh->sh_addralign > s->sh_addralign) - s->sh_addralign = sh->sh_addralign; - s->data_offset = offset; - no_align: - sm_table[i].offset = offset; - sm_table[i].s = s; - /* concatenate sections */ - size = sh->sh_size; - if (sh->sh_type != SHT_NOBITS) { - unsigned char *ptr; - lseek(fd, file_offset + sh->sh_offset, SEEK_SET); - ptr = section_ptr_add(s, size); - read(fd, ptr, size); - } else { - s->data_offset += size; - } - next: ; - } - - /* gr relocate stab strings */ - if (stab_index && stabstr_index) { - Stab_Sym *a, *b; - unsigned o; - s = sm_table[stab_index].s; - a = (Stab_Sym *)(s->data + sm_table[stab_index].offset); - b = (Stab_Sym *)(s->data + s->data_offset); - o = sm_table[stabstr_index].offset; - while (a < b) - a->n_strx += o, a++; - } - - /* second short pass to update sh_link and sh_info fields of new - sections */ - for(i = 1; i < ehdr.e_shnum; i++) { - s = sm_table[i].s; - if (!s || !sm_table[i].new_section) - continue; - sh = &shdr[i]; - if (sh->sh_link > 0) - s->link = sm_table[sh->sh_link].s; - if (sh->sh_type == SHT_RELX) { - s->sh_info = sm_table[sh->sh_info].s->sh_num; - /* update backward link */ - s1->sections[s->sh_info]->reloc = s; - } - } - sm = sm_table; - - /* resolve symbols */ - old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int)); - - sym = symtab + 1; - for(i = 1; i < nb_syms; i++, sym++) { - if (sym->st_shndx != SHN_UNDEF && - sym->st_shndx < SHN_LORESERVE) { - sm = &sm_table[sym->st_shndx]; - if (sm->link_once) { - /* if a symbol is in a link once section, we use the - already defined symbol. It is very important to get - correct relocations */ - if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { - name = (char *) strtab + sym->st_name; - sym_index = find_elf_sym(symtab_section, name); - if (sym_index) - old_to_new_syms[i] = sym_index; - } - continue; - } - /* if no corresponding section added, no need to add symbol */ - if (!sm->s) - continue; - /* convert section number */ - sym->st_shndx = sm->s->sh_num; - /* offset value */ - sym->st_value += sm->offset; - } - /* add symbol */ - name = (char *) strtab + sym->st_name; - sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size, - sym->st_info, sym->st_other, - sym->st_shndx, name); - old_to_new_syms[i] = sym_index; - } - - /* third pass to patch relocation entries */ - for(i = 1; i < ehdr.e_shnum; i++) { - s = sm_table[i].s; - if (!s) - continue; - sh = &shdr[i]; - offset = sm_table[i].offset; - switch(s->sh_type) { - case SHT_RELX: - /* take relocation offset information */ - offseti = sm_table[sh->sh_info].offset; - for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) { - int type; - unsigned sym_index; - /* convert symbol index */ - type = ELFW(R_TYPE)(rel->r_info); - sym_index = ELFW(R_SYM)(rel->r_info); - /* NOTE: only one symtab assumed */ - if (sym_index >= nb_syms) - goto invalid_reloc; - sym_index = old_to_new_syms[sym_index]; - /* ignore link_once in rel section. */ - if (!sym_index && !sm->link_once -#ifdef TCC_TARGET_ARM - && type != R_ARM_V4BX -#endif - ) { - invalid_reloc: - tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x", - i, strsec + sh->sh_name, rel->r_offset); - goto fail; - } - rel->r_info = ELFW(R_INFO)(sym_index, type); - /* offset the relocation offset */ - rel->r_offset += offseti; -#ifdef TCC_TARGET_ARM - /* Jumps and branches from a Thumb code to a PLT entry need - special handling since PLT entries are ARM code. - Unconditional bl instructions referencing PLT entries are - handled by converting these instructions into blx - instructions. Other case of instructions referencing a PLT - entry require to add a Thumb stub before the PLT entry to - switch to ARM mode. We set bit plt_thumb_stub of the - attribute of a symbol to indicate such a case. */ - if (type == R_ARM_THM_JUMP24) - alloc_sym_attr(s1, sym_index)->plt_thumb_stub = 1; -#endif - } - break; - default: - break; - } - } - - ret = 0; - the_end: - tcc_free(symtab); - tcc_free(strtab); - tcc_free(old_to_new_syms); - tcc_free(sm_table); - tcc_free(strsec); - tcc_free(shdr); - return ret; -} - -typedef struct ArchiveHeader { - char ar_name[16]; /* name of this member */ - char ar_date[12]; /* file mtime */ - char ar_uid[6]; /* owner uid; printed as decimal */ - char ar_gid[6]; /* owner gid; printed as decimal */ - char ar_mode[8]; /* file mode, printed as octal */ - char ar_size[10]; /* file size, printed as decimal */ - char ar_fmag[2]; /* should contain ARFMAG */ -} ArchiveHeader; - -static int get_be32(const uint8_t *b) -{ - return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24); -} - -/* load only the objects which resolve undefined symbols */ -static int tcc_load_alacarte(TCCState *s1, int fd, int size) -{ - int i, bound, nsyms, sym_index, off, ret; - uint8_t *data; - const char *ar_names, *p; - const uint8_t *ar_index; - ElfW(Sym) *sym; - - data = tcc_malloc(size); - if (read(fd, data, size) != size) - goto fail; - nsyms = get_be32(data); - ar_index = data + 4; - ar_names = (char *) ar_index + nsyms * 4; - - do { - bound = 0; - for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) { - sym_index = find_elf_sym(symtab_section, p); - if(sym_index) { - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - if(sym->st_shndx == SHN_UNDEF) { - off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader); - ++bound; - lseek(fd, off, SEEK_SET); - if(tcc_load_object_file(s1, fd, off) < 0) { - fail: - ret = -1; - goto the_end; - } - } - } - } - } while(bound); - ret = 0; - the_end: - tcc_free(data); - return ret; -} - -/* load a '.a' file */ -ST_FUNC int tcc_load_archive(TCCState *s1, int fd) -{ - ArchiveHeader hdr; - char ar_size[11]; - char ar_name[17]; - char magic[8]; - int size, len, i; - unsigned long file_offset; - - /* skip magic which was already checked */ - read(fd, magic, sizeof(magic)); - - for(;;) { - len = read(fd, &hdr, sizeof(hdr)); - if (len == 0) - break; - if (len != sizeof(hdr)) { - tcc_error_noabort("invalid archive"); - return -1; - } - memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size)); - ar_size[sizeof(hdr.ar_size)] = '\0'; - size = strtol(ar_size, NULL, 0); - memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name)); - for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) { - if (ar_name[i] != ' ') - break; - } - ar_name[i + 1] = '\0'; - file_offset = lseek(fd, 0, SEEK_CUR); - /* align to even */ - size = (size + 1) & ~1; - if (!strcmp(ar_name, "/")) { - /* coff symbol table : we handle it */ - if(s1->alacarte_link) - return tcc_load_alacarte(s1, fd, size); - } else if (!strcmp(ar_name, "//") || - !strcmp(ar_name, "__.SYMDEF") || - !strcmp(ar_name, "__.SYMDEF/") || - !strcmp(ar_name, "ARFILENAMES/")) { - /* skip symbol table or archive names */ - } else { - if (tcc_load_object_file(s1, fd, file_offset) < 0) - return -1; - } - lseek(fd, file_offset + size, SEEK_SET); - } - return 0; -} - -#ifndef TCC_TARGET_PE -/* load a DLL and all referenced DLLs. 'level = 0' means that the DLL - is referenced by the user (so it should be added as DT_NEEDED in - the generated ELF file) */ -ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) -{ - ElfW(Ehdr) ehdr; - ElfW(Shdr) *shdr, *sh, *sh1; - int i, j, nb_syms, nb_dts, sym_bind, ret; - ElfW(Sym) *sym, *dynsym; - ElfW(Dyn) *dt, *dynamic; - unsigned char *dynstr; - const char *name, *soname; - DLLReference *dllref; - - read(fd, &ehdr, sizeof(ehdr)); - - /* test CPU specific stuff */ - if (ehdr.e_ident[5] != ELFDATA2LSB || - ehdr.e_machine != EM_TCC_TARGET) { - tcc_error_noabort("bad architecture"); - return -1; - } - - /* read sections */ - shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum); - - /* load dynamic section and dynamic symbols */ - nb_syms = 0; - nb_dts = 0; - dynamic = NULL; - dynsym = NULL; /* avoid warning */ - dynstr = NULL; /* avoid warning */ - for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) { - switch(sh->sh_type) { - case SHT_DYNAMIC: - nb_dts = sh->sh_size / sizeof(ElfW(Dyn)); - dynamic = load_data(fd, sh->sh_offset, sh->sh_size); - break; - case SHT_DYNSYM: - nb_syms = sh->sh_size / sizeof(ElfW(Sym)); - dynsym = load_data(fd, sh->sh_offset, sh->sh_size); - sh1 = &shdr[sh->sh_link]; - dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size); - break; - default: - break; - } - } - - /* compute the real library name */ - soname = tcc_basename(filename); - - for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) { - if (dt->d_tag == DT_SONAME) { - soname = (char *) dynstr + dt->d_un.d_val; - } - } - - /* if the dll is already loaded, do not load it */ - for(i = 0; i < s1->nb_loaded_dlls; i++) { - dllref = s1->loaded_dlls[i]; - if (!strcmp(soname, dllref->name)) { - /* but update level if needed */ - if (level < dllref->level) - dllref->level = level; - ret = 0; - goto the_end; - } - } - - /* add the dll and its level */ - dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname)); - dllref->level = level; - strcpy(dllref->name, soname); - dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref); - - /* add dynamic symbols in dynsym_section */ - for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) { - sym_bind = ELFW(ST_BIND)(sym->st_info); - if (sym_bind == STB_LOCAL) - continue; - name = (char *) dynstr + sym->st_name; - add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size, - sym->st_info, sym->st_other, sym->st_shndx, name); - } - - /* load all referenced DLLs */ - for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) { - switch(dt->d_tag) { - case DT_NEEDED: - name = (char *) dynstr + dt->d_un.d_val; - for(j = 0; j < s1->nb_loaded_dlls; j++) { - dllref = s1->loaded_dlls[j]; - if (!strcmp(name, dllref->name)) - goto already_loaded; - } - if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) { - tcc_error_noabort("referenced dll '%s' not found", name); - ret = -1; - goto the_end; - } - already_loaded: - break; - } - } - ret = 0; - the_end: - tcc_free(dynstr); - tcc_free(dynsym); - tcc_free(dynamic); - tcc_free(shdr); - return ret; -} - -#define LD_TOK_NAME 256 -#define LD_TOK_EOF (-1) - -/* return next ld script token */ -static int ld_next(TCCState *s1, char *name, int name_size) -{ - int c; - char *q; - - redo: - switch(ch) { - case ' ': - case '\t': - case '\f': - case '\v': - case '\r': - case '\n': - inp(); - goto redo; - case '/': - minp(); - if (ch == '*') { - file->buf_ptr = parse_comment(file->buf_ptr); - ch = file->buf_ptr[0]; - goto redo; - } else { - q = name; - *q++ = '/'; - goto parse_name; - } - break; - case '\\': - ch = handle_eob(); - if (ch != '\\') - goto redo; - /* fall through */ - /* case 'a' ... 'z': */ - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - case 'g': - case 'h': - case 'i': - case 'j': - case 'k': - case 'l': - case 'm': - case 'n': - case 'o': - case 'p': - case 'q': - case 'r': - case 's': - case 't': - case 'u': - case 'v': - case 'w': - case 'x': - case 'y': - case 'z': - /* case 'A' ... 'z': */ - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - case 'G': - case 'H': - case 'I': - case 'J': - case 'K': - case 'L': - case 'M': - case 'N': - case 'O': - case 'P': - case 'Q': - case 'R': - case 'S': - case 'T': - case 'U': - case 'V': - case 'W': - case 'X': - case 'Y': - case 'Z': - case '_': - case '.': - case '$': - case '~': - q = name; - parse_name: - for(;;) { - if (!((ch >= 'a' && ch <= 'z') || - (ch >= 'A' && ch <= 'Z') || - (ch >= '0' && ch <= '9') || - strchr("/.-_+=$:\\,~", ch))) - break; - if ((q - name) < name_size - 1) { - *q++ = ch; - } - minp(); - } - *q = '\0'; - c = LD_TOK_NAME; - break; - case CH_EOF: - c = LD_TOK_EOF; - break; - default: - c = ch; - inp(); - break; - } - return c; -} - -static int ld_add_file(TCCState *s1, const char filename[]) -{ - int ret; - - ret = tcc_add_file_internal(s1, filename, 0, TCC_FILETYPE_BINARY); - if (ret) - ret = tcc_add_dll(s1, filename, 0); - return ret; -} - -static inline int new_undef_syms(void) -{ - int ret = 0; - ret = new_undef_sym; - new_undef_sym = 0; - return ret; -} - -static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed) -{ - char filename[1024], libname[1024]; - int t, group, nblibs = 0, ret = 0; - char **libs = NULL; - - group = !strcmp(cmd, "GROUP"); - if (!as_needed) - new_undef_syms(); - t = ld_next(s1, filename, sizeof(filename)); - if (t != '(') - expect("("); - t = ld_next(s1, filename, sizeof(filename)); - for(;;) { - libname[0] = '\0'; - if (t == LD_TOK_EOF) { - tcc_error_noabort("unexpected end of file"); - ret = -1; - goto lib_parse_error; - } else if (t == ')') { - break; - } else if (t == '-') { - t = ld_next(s1, filename, sizeof(filename)); - if ((t != LD_TOK_NAME) || (filename[0] != 'l')) { - tcc_error_noabort("library name expected"); - ret = -1; - goto lib_parse_error; - } - pstrcpy(libname, sizeof libname, &filename[1]); - if (s1->static_link) { - snprintf(filename, sizeof filename, "lib%s.a", libname); - } else { - snprintf(filename, sizeof filename, "lib%s.so", libname); - } - } else if (t != LD_TOK_NAME) { - tcc_error_noabort("filename expected"); - ret = -1; - goto lib_parse_error; - } - if (!strcmp(filename, "AS_NEEDED")) { - ret = ld_add_file_list(s1, cmd, 1); - if (ret) - goto lib_parse_error; - } else { - /* TODO: Implement AS_NEEDED support. Ignore it for now */ - if (!as_needed) { - ret = ld_add_file(s1, filename); - if (ret) - goto lib_parse_error; - if (group) { - /* Add the filename *and* the libname to avoid future conversions */ - dynarray_add((void ***) &libs, &nblibs, tcc_strdup(filename)); - if (libname[0] != '\0') - dynarray_add((void ***) &libs, &nblibs, tcc_strdup(libname)); - } - } - } - t = ld_next(s1, filename, sizeof(filename)); - if (t == ',') { - t = ld_next(s1, filename, sizeof(filename)); - } - } - if (group && !as_needed) { - while (new_undef_syms()) { - int i; - - for (i = 0; i < nblibs; i ++) - ld_add_file(s1, libs[i]); - } - } -lib_parse_error: - dynarray_reset(&libs, &nblibs); - return ret; -} - -/* interpret a subset of GNU ldscripts to handle the dummy libc.so - files */ -ST_FUNC int tcc_load_ldscript(TCCState *s1) -{ - char cmd[64]; - char filename[1024]; - int t, ret; - - ch = handle_eob(); - for(;;) { - t = ld_next(s1, cmd, sizeof(cmd)); - if (t == LD_TOK_EOF) - return 0; - else if (t != LD_TOK_NAME) - return -1; - if (!strcmp(cmd, "INPUT") || - !strcmp(cmd, "GROUP")) { - ret = ld_add_file_list(s1, cmd, 0); - if (ret) - return ret; - } else if (!strcmp(cmd, "OUTPUT_FORMAT") || - !strcmp(cmd, "TARGET")) { - /* ignore some commands */ - t = ld_next(s1, cmd, sizeof(cmd)); - if (t != '(') - expect("("); - for(;;) { - t = ld_next(s1, filename, sizeof(filename)); - if (t == LD_TOK_EOF) { - tcc_error_noabort("unexpected end of file"); - return -1; - } else if (t == ')') { - break; - } - } - } else { - return -1; - } - } - return 0; -} -#endif /* !TCC_TARGET_PE */ diff --git a/external/TCC/tccgen.c b/external/TCC/tccgen.c deleted file mode 100644 index 7be2f2f5..00000000 --- a/external/TCC/tccgen.c +++ /dev/null @@ -1,6454 +0,0 @@ -/* - * TCC - Tiny C Compiler - * - * Copyright (c) 2001-2004 Fabrice Bellard - * - * 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "tcc.h" - -/********************************************************/ -/* global variables */ - -/* loc : local variable index - ind : output code index - rsym: return symbol - anon_sym: anonymous symbol index -*/ -ST_DATA int rsym, anon_sym, ind, loc; - -ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */ -ST_DATA Section *cur_text_section; /* current section where function code is generated */ -#ifdef CONFIG_TCC_ASM -ST_DATA Section *last_text_section; /* to handle .previous asm directive */ -#endif -#ifdef CONFIG_TCC_BCHECK -/* bound check related sections */ -ST_DATA Section *bounds_section; /* contains global data bound description */ -ST_DATA Section *lbounds_section; /* contains local data bound description */ -#endif -/* symbol sections */ -ST_DATA Section *symtab_section, *strtab_section; -/* debug sections */ -ST_DATA Section *stab_section, *stabstr_section; -ST_DATA Sym *sym_free_first; -ST_DATA void **sym_pools; -ST_DATA int nb_sym_pools; - -ST_DATA Sym *global_stack; -ST_DATA Sym *local_stack; -ST_DATA Sym *scope_stack_bottom; -ST_DATA Sym *define_stack; -ST_DATA Sym *global_label_stack; -ST_DATA Sym *local_label_stack; - -ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */ -ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */ -ST_DATA int vla_sp_loc; /* Pointer to variable holding location to store stack pointer on the stack when modifying stack pointer */ - -ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop, *pvtop; - -ST_DATA int const_wanted; /* true if constant wanted */ -ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */ -ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */ -ST_DATA CType func_vt; /* current function return type (used by return instruction) */ -ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */ -ST_DATA int func_vc; -ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */ -ST_DATA const char *funcname; - -ST_DATA CType char_pointer_type, func_old_type, int_type, size_type; - -/* ------------------------------------------------------------------------- */ -static void gen_cast(CType *type); -static inline CType *pointed_type(CType *type); -static int is_compatible_types(CType *type1, CType *type2); -static int parse_btype(CType *type, AttributeDef *ad); -static void type_decl(CType *type, AttributeDef *ad, int *v, int td); -static void parse_expr_type(CType *type); -static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only); -static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr); -static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope); -static int decl0(int l, int is_for_loop_init); -static void expr_eq(void); -static void unary_type(CType *type); -static void vla_runtime_type_size(CType *type, int *a); -static void vla_sp_restore(void); -static void vla_sp_restore_root(void); -static int is_compatible_parameter_types(CType *type1, CType *type2); -static void expr_type(CType *type); -ST_FUNC void vpush64(int ty, unsigned long long v); -ST_FUNC void vpush(CType *type); -ST_FUNC int gvtst(int inv, int t); -ST_FUNC int is_btype_size(int bt); - -ST_INLN int is_float(int t) -{ - int bt; - bt = t & VT_BTYPE; - return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT; -} - -/* we use our own 'finite' function to avoid potential problems with - non standard math libs */ -/* XXX: endianness dependent */ -ST_FUNC int ieee_finite(double d) -{ - int p[4]; - memcpy(p, &d, sizeof(double)); - return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31; -} - -ST_FUNC void test_lvalue(void) -{ - if (!(vtop->r & VT_LVAL)) - expect("lvalue"); -} - -ST_FUNC void check_vstack(void) -{ - if (pvtop != vtop) - tcc_error("internal compiler error: vstack leak (%d)", vtop - pvtop); -} - -/* ------------------------------------------------------------------------- */ -/* symbol allocator */ -static Sym *__sym_malloc(void) -{ - Sym *sym_pool, *sym, *last_sym; - int i; - - sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym)); - dynarray_add(&sym_pools, &nb_sym_pools, sym_pool); - - last_sym = sym_free_first; - sym = sym_pool; - for(i = 0; i < SYM_POOL_NB; i++) { - sym->next = last_sym; - last_sym = sym; - sym++; - } - sym_free_first = last_sym; - return last_sym; -} - -static inline Sym *sym_malloc(void) -{ - Sym *sym; - sym = sym_free_first; - if (!sym) - sym = __sym_malloc(); - sym_free_first = sym->next; - return sym; -} - -ST_INLN void sym_free(Sym *sym) -{ - sym->next = sym_free_first; - sym_free_first = sym; -} - -/* push, without hashing */ -ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c) -{ - Sym *s; - if (ps == &local_stack) { - for (s = *ps; s && s != scope_stack_bottom; s = s->prev) - if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM && s->v == v) - tcc_error("incompatible types for redefinition of '%s'", - get_tok_str(v, NULL)); - } - s = sym_malloc(); - s->asm_label = 0; - s->v = v; - s->type.t = t; - s->type.ref = NULL; -#ifdef _WIN64 - s->d = NULL; -#endif - s->c = c; - s->next = NULL; - /* add in stack */ - s->prev = *ps; - *ps = s; - return s; -} - -/* find a symbol and return its associated structure. 's' is the top - of the symbol stack */ -ST_FUNC Sym *sym_find2(Sym *s, int v) -{ - while (s) { - if (s->v == v) - return s; - else if (s->v == -1) - return NULL; - s = s->prev; - } - return NULL; -} - -/* structure lookup */ -ST_INLN Sym *struct_find(int v) -{ - v -= TOK_IDENT; - if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) - return NULL; - return table_ident[v]->sym_struct; -} - -/* find an identifier */ -ST_INLN Sym *sym_find(int v) -{ - v -= TOK_IDENT; - if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) - return NULL; - return table_ident[v]->sym_identifier; -} - -/* push a given symbol on the symbol stack */ -ST_FUNC Sym *sym_push(int v, CType *type, int r, int c) -{ - Sym *s, **ps; - TokenSym *ts; - - if (local_stack) - ps = &local_stack; - else - ps = &global_stack; - s = sym_push2(ps, v, type->t, c); - s->type.ref = type->ref; - s->r = r; - /* don't record fields or anonymous symbols */ - /* XXX: simplify */ - if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) { - /* record symbol in token array */ - ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT]; - if (v & SYM_STRUCT) - ps = &ts->sym_struct; - else - ps = &ts->sym_identifier; - s->prev_tok = *ps; - *ps = s; - } - return s; -} - -/* push a global identifier */ -ST_FUNC Sym *global_identifier_push(int v, int t, int c) -{ - Sym *s, **ps; - s = sym_push2(&global_stack, v, t, c); - /* don't record anonymous symbol */ - if (v < SYM_FIRST_ANOM) { - ps = &table_ident[v - TOK_IDENT]->sym_identifier; - /* modify the top most local identifier, so that - sym_identifier will point to 's' when popped */ - while (*ps != NULL) - ps = &(*ps)->prev_tok; - s->prev_tok = NULL; - *ps = s; - } - return s; -} - -/* pop symbols until top reaches 'b' */ -ST_FUNC void sym_pop(Sym **ptop, Sym *b) -{ - Sym *s, *ss, **ps; - TokenSym *ts; - int v; - - s = *ptop; - while(s != b) { - ss = s->prev; - v = s->v; - /* remove symbol in token array */ - /* XXX: simplify */ - if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) { - ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT]; - if (v & SYM_STRUCT) - ps = &ts->sym_struct; - else - ps = &ts->sym_identifier; - *ps = s->prev_tok; - } - sym_free(s); - s = ss; - } - *ptop = b; -} - -static void weaken_symbol(Sym *sym) -{ - sym->type.t |= VT_WEAK; - if (sym->c > 0) { - int esym_type; - ElfW(Sym) *esym; - - esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; - esym_type = ELFW(ST_TYPE)(esym->st_info); - esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type); - } -} - -static void apply_visibility(Sym *sym, CType *type) -{ - int vis = sym->type.t & VT_VIS_MASK; - int vis2 = type->t & VT_VIS_MASK; - if (vis == (STV_DEFAULT << VT_VIS_SHIFT)) - vis = vis2; - else if (vis2 == (STV_DEFAULT << VT_VIS_SHIFT)) - ; - else - vis = (vis < vis2) ? vis : vis2; - sym->type.t &= ~VT_VIS_MASK; - sym->type.t |= vis; - - if (sym->c > 0) { - ElfW(Sym) *esym; - - esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; - vis >>= VT_VIS_SHIFT; - esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | vis; - } -} - -/* ------------------------------------------------------------------------- */ - -ST_FUNC void swap(int *p, int *q) -{ - int t; - t = *p; - *p = *q; - *q = t; -} - -static void vsetc(CType *type, int r, CValue *vc) -{ - int v; - - if (vtop >= vstack + (VSTACK_SIZE - 1)) - tcc_error("memory full (vstack)"); - /* cannot let cpu flags if other instruction are generated. Also - avoid leaving VT_JMP anywhere except on the top of the stack - because it would complicate the code generator. */ - if (vtop >= vstack) { - v = vtop->r & VT_VALMASK; - if (v == VT_CMP || (v & ~1) == VT_JMP) - gv(RC_INT); - } - vtop++; - vtop->type = *type; - vtop->r = r; - vtop->r2 = VT_CONST; - vtop->c = *vc; -} - -/* push constant of type "type" with useless value */ -ST_FUNC void vpush(CType *type) -{ - CValue cval; - vsetc(type, VT_CONST, &cval); -} - -/* push integer constant */ -ST_FUNC void vpushi(int v) -{ - CValue cval; - cval.i = v; - vsetc(&int_type, VT_CONST, &cval); -} - -/* push a pointer sized constant */ -static void vpushs(addr_t v) -{ - CValue cval; - cval.i = v; - vsetc(&size_type, VT_CONST, &cval); -} - -/* push arbitrary 64bit constant */ -ST_FUNC void vpush64(int ty, unsigned long long v) -{ - CValue cval; - CType ctype; - ctype.t = ty; - ctype.ref = NULL; - cval.i = v; - vsetc(&ctype, VT_CONST, &cval); -} - -/* push long long constant */ -static inline void vpushll(long long v) -{ - vpush64(VT_LLONG, v); -} - -/* push a symbol value of TYPE */ -static inline void vpushsym(CType *type, Sym *sym) -{ - CValue cval; - cval.i = 0; - vsetc(type, VT_CONST | VT_SYM, &cval); - vtop->sym = sym; -} - -/* Return a static symbol pointing to a section */ -ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size) -{ - int v; - Sym *sym; - - v = anon_sym++; - sym = global_identifier_push(v, type->t | VT_STATIC, 0); - sym->type.ref = type->ref; - sym->r = VT_CONST | VT_SYM; - put_extern_sym(sym, sec, offset, size); - return sym; -} - -/* push a reference to a section offset by adding a dummy symbol */ -static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size) -{ - vpushsym(type, get_sym_ref(type, sec, offset, size)); -} - -/* define a new external reference to a symbol 'v' of type 'u' */ -ST_FUNC Sym *external_global_sym(int v, CType *type, int r) -{ - Sym *s; - - s = sym_find(v); - if (!s) { - /* push forward reference */ - s = global_identifier_push(v, type->t | VT_EXTERN, 0); - s->type.ref = type->ref; - s->r = r | VT_CONST | VT_SYM; - } - return s; -} - -/* define a new external reference to a symbol 'v' */ -static Sym *external_sym(int v, CType *type, int r) -{ - Sym *s; - - s = sym_find(v); - if (!s) { - /* push forward reference */ - s = sym_push(v, type, r | VT_CONST | VT_SYM, 0); - s->type.t |= VT_EXTERN; - } else if (s->type.ref == func_old_type.ref) { - s->type.ref = type->ref; - s->r = r | VT_CONST | VT_SYM; - s->type.t |= VT_EXTERN; - } else if (!is_compatible_types(&s->type, type)) { - tcc_error("incompatible types for redefinition of '%s'", - get_tok_str(v, NULL)); - } - /* Merge some storage attributes. */ - if (type->t & VT_WEAK) - weaken_symbol(s); - - if (type->t & VT_VIS_MASK) - apply_visibility(s, type); - - return s; -} - -/* push a reference to global symbol v */ -ST_FUNC void vpush_global_sym(CType *type, int v) -{ - vpushsym(type, external_global_sym(v, type, 0)); -} - -ST_FUNC void vset(CType *type, int r, int v) -{ - CValue cval; - - cval.i = v; - vsetc(type, r, &cval); -} - -static void vseti(int r, int v) -{ - CType type; - type.t = VT_INT; - type.ref = 0; - vset(&type, r, v); -} - -ST_FUNC void vswap(void) -{ - SValue tmp; - /* cannot let cpu flags if other instruction are generated. Also - avoid leaving VT_JMP anywhere except on the top of the stack - because it would complicate the code generator. */ - if (vtop >= vstack) { - int v = vtop->r & VT_VALMASK; - if (v == VT_CMP || (v & ~1) == VT_JMP) - gv(RC_INT); - } - tmp = vtop[0]; - vtop[0] = vtop[-1]; - vtop[-1] = tmp; - -/* XXX: +2% overall speed possible with optimized memswap - * - * memswap(&vtop[0], &vtop[1], sizeof *vtop); - */ -} - -ST_FUNC void vpushv(SValue *v) -{ - if (vtop >= vstack + (VSTACK_SIZE - 1)) - tcc_error("memory full (vstack)"); - vtop++; - *vtop = *v; -} - -static void vdup(void) -{ - vpushv(vtop); -} - -/* save r to the memory stack, and mark it as being free */ -ST_FUNC void save_reg(int r) -{ - int l, saved, size, align; - SValue *p, sv; - CType *type; - - /* modify all stack values */ - saved = 0; - l = 0; - for(p=vstack;p<=vtop;p++) { - if ((p->r & VT_VALMASK) == r || - ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) { - /* must save value on stack if not already done */ - if (!saved) { - /* NOTE: must reload 'r' because r might be equal to r2 */ - r = p->r & VT_VALMASK; - /* store register in the stack */ - type = &p->type; - if ((p->r & VT_LVAL) || - (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG)) -#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) - type = &char_pointer_type; -#else - type = &int_type; -#endif - size = type_size(type, &align); - loc = (loc - size) & -align; - sv.type.t = type->t; - sv.r = VT_LOCAL | VT_LVAL; - sv.c.i = loc; - store(r, &sv); -#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) - /* x86 specific: need to pop fp register ST0 if saved */ - if (r == TREG_ST0) { - o(0xd8dd); /* fstp %st(0) */ - } -#endif -#if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64) - /* special long long case */ - if ((type->t & VT_BTYPE) == VT_LLONG) { - sv.c.i += 4; - store(p->r2, &sv); - } -#endif - l = loc; - saved = 1; - } - /* mark that stack entry as being saved on the stack */ - if (p->r & VT_LVAL) { - /* also clear the bounded flag because the - relocation address of the function was stored in - p->c.i */ - p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL; - } else { - p->r = lvalue_type(p->type.t) | VT_LOCAL; - } - p->r2 = VT_CONST; - p->c.i = l; - } - } -} - -#ifdef TCC_TARGET_ARM -/* find a register of class 'rc2' with at most one reference on stack. - * If none, call get_reg(rc) */ -ST_FUNC int get_reg_ex(int rc, int rc2) -{ - int r; - SValue *p; - - for(r=0;rr & VT_VALMASK) == r || - (p->r2 & VT_VALMASK) == r) - n++; - } - if (n <= 1) - return r; - } - } - return get_reg(rc); -} -#endif - -/* find a free register of class 'rc'. If none, save one register */ -ST_FUNC int get_reg(int rc) -{ - int r; - SValue *p; - - /* find a free register */ - for(r=0;rr & VT_VALMASK) == r || - (p->r2 & VT_VALMASK) == r) - goto notfound; - } - return r; - } - notfound: ; - } - - /* no register left : free the first one on the stack (VERY - IMPORTANT to start from the bottom to ensure that we don't - spill registers used in gen_opi()) */ - for(p=vstack;p<=vtop;p++) { - /* look at second register (if long long) */ - r = p->r2 & VT_VALMASK; - if (r < VT_CONST && (reg_classes[r] & rc)) - goto save_found; - r = p->r & VT_VALMASK; - if (r < VT_CONST && (reg_classes[r] & rc)) { - save_found: - save_reg(r); - return r; - } - } - /* Should never comes here */ - return -1; -} - -/* save registers up to (vtop - n) stack entry */ -ST_FUNC void save_regs(int n) -{ - int r; - SValue *p, *p1; - p1 = vtop - n; - for(p = vstack;p <= p1; p++) { - r = p->r & VT_VALMASK; - if (r < VT_CONST) { - save_reg(r); - } - } -} - -/* move register 's' (of type 't') to 'r', and flush previous value of r to memory - if needed */ -static void move_reg(int r, int s, int t) -{ - SValue sv; - - if (r != s) { - save_reg(r); - sv.type.t = t; - sv.type.ref = NULL; - sv.r = s; - sv.c.i = 0; - load(r, &sv); - } -} - -/* get address of vtop (vtop MUST BE an lvalue) */ -ST_FUNC void gaddrof(void) -{ - if (vtop->r & VT_REF && !nocode_wanted) - gv(RC_INT); - vtop->r &= ~VT_LVAL; - /* tricky: if saved lvalue, then we can go back to lvalue */ - if ((vtop->r & VT_VALMASK) == VT_LLOCAL) - vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL; - - -} - -#ifdef CONFIG_TCC_BCHECK -/* generate lvalue bound code */ -static void gbound(void) -{ - int lval_type; - CType type1; - - vtop->r &= ~VT_MUSTBOUND; - /* if lvalue, then use checking code before dereferencing */ - if (vtop->r & VT_LVAL) { - /* if not VT_BOUNDED value, then make one */ - if (!(vtop->r & VT_BOUNDED)) { - lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL); - /* must save type because we must set it to int to get pointer */ - type1 = vtop->type; - vtop->type.t = VT_PTR; - gaddrof(); - vpushi(0); - gen_bounded_ptr_add(); - vtop->r |= lval_type; - vtop->type = type1; - } - /* then check for dereferencing */ - gen_bounded_ptr_deref(); - } -} -#endif - -/* store vtop a register belonging to class 'rc'. lvalues are - converted to values. Cannot be used if cannot be converted to - register value (such as structures). */ -ST_FUNC int gv(int rc) -{ - int r, bit_pos, bit_size, size, align, i; - int rc2; - - /* NOTE: get_reg can modify vstack[] */ - if (vtop->type.t & VT_BITFIELD) { - CType type; - int bits = 32; - bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f; - bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f; - /* remove bit field info to avoid loops */ - vtop->type.t &= ~VT_BITFIELD & ((1 << VT_STRUCT_SHIFT) - 1); - /* cast to int to propagate signedness in following ops */ - if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { - type.t = VT_LLONG; - bits = 64; - } else - type.t = VT_INT; - if((vtop->type.t & VT_UNSIGNED) || - (vtop->type.t & VT_BTYPE) == VT_BOOL) - type.t |= VT_UNSIGNED; - gen_cast(&type); - /* generate shifts */ - vpushi(bits - (bit_pos + bit_size)); - gen_op(TOK_SHL); - vpushi(bits - bit_size); - /* NOTE: transformed to SHR if unsigned */ - gen_op(TOK_SAR); - r = gv(rc); - } else { - if (is_float(vtop->type.t) && - (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { - Sym *sym; - int *ptr; - unsigned long offset; -#if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP) - CValue check; -#endif - - /* XXX: unify with initializers handling ? */ - /* CPUs usually cannot use float constants, so we store them - generically in data segment */ - size = type_size(&vtop->type, &align); - offset = (data_section->data_offset + align - 1) & -align; - data_section->data_offset = offset; - /* XXX: not portable yet */ -#if defined(__i386__) || defined(__x86_64__) - /* Zero pad x87 tenbyte long doubles */ - if (size == LDOUBLE_SIZE) { - vtop->c.tab[2] &= 0xffff; -#if LDOUBLE_SIZE == 16 - vtop->c.tab[3] = 0; -#endif - } -#endif - ptr = section_ptr_add(data_section, size); - size = size >> 2; -#if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP) - check.d = 1; - if(check.tab[0]) - for(i=0;ic.tab[size-1-i]; - else -#endif - for(i=0;ic.tab[i]; - sym = get_sym_ref(&vtop->type, data_section, offset, size << 2); - vtop->r |= VT_LVAL | VT_SYM; - vtop->sym = sym; - vtop->c.i = 0; - } -#ifdef CONFIG_TCC_BCHECK - if (vtop->r & VT_MUSTBOUND) - gbound(); -#endif - - r = vtop->r & VT_VALMASK; - rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT; -#ifndef TCC_TARGET_ARM64 - if (rc == RC_IRET) - rc2 = RC_LRET; -#ifdef TCC_TARGET_X86_64 - else if (rc == RC_FRET) - rc2 = RC_QRET; -#endif -#endif - - /* need to reload if: - - constant - - lvalue (need to dereference pointer) - - already a register, but not in the right class */ - if (r >= VT_CONST - || (vtop->r & VT_LVAL) - || !(reg_classes[r] & rc) -#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) - || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2)) - || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2)) -#else - || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2)) -#endif - ) - { - r = get_reg(rc); -#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) - if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) { - int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE; -#else - if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { - int addr_type = VT_INT, load_size = 4, load_type = VT_INT; - unsigned long long ll; -#endif - int r2, original_type; - original_type = vtop->type.t; - /* two register type load : expand to two words - temporarily */ -#if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64) - if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { - /* load constant */ - ll = vtop->c.i; - vtop->c.i = ll; /* first word */ - load(r, vtop); - vtop->r = r; /* save register value */ - vpushi(ll >> 32); /* second word */ - } else -#endif - if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */ - (vtop->r & VT_LVAL)) { - /* We do not want to modifier the long long - pointer here, so the safest (and less - efficient) is to save all the other registers - in the stack. XXX: totally inefficient. */ - save_regs(1); - /* load from memory */ - vtop->type.t = load_type; - load(r, vtop); - vdup(); - vtop[-1].r = r; /* save register value */ - /* increment pointer to get second word */ - vtop->type.t = addr_type; - gaddrof(); - vpushi(load_size); - gen_op('+'); - vtop->r |= VT_LVAL; - vtop->type.t = load_type; - } else { - /* move registers */ - load(r, vtop); - vdup(); - vtop[-1].r = r; /* save register value */ - vtop->r = vtop[-1].r2; - } - /* Allocate second register. Here we rely on the fact that - get_reg() tries first to free r2 of an SValue. */ - r2 = get_reg(rc2); - load(r2, vtop); - vpop(); - /* write second register */ - vtop->r2 = r2; - vtop->type.t = original_type; - } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) { - int t1, t; - /* lvalue of scalar type : need to use lvalue type - because of possible cast */ - t = vtop->type.t; - t1 = t; - /* compute memory access type */ - if (vtop->r & VT_REF) -#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) - t = VT_PTR; -#else - t = VT_INT; -#endif - else if (vtop->r & VT_LVAL_BYTE) - t = VT_BYTE; - else if (vtop->r & VT_LVAL_SHORT) - t = VT_SHORT; - if (vtop->r & VT_LVAL_UNSIGNED) - t |= VT_UNSIGNED; - vtop->type.t = t; - load(r, vtop); - /* restore wanted type */ - vtop->type.t = t1; - } else { - /* one register type load */ - load(r, vtop); - } - } - vtop->r = r; -#ifdef TCC_TARGET_C67 - /* uses register pairs for doubles */ - if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) - vtop->r2 = r+1; -#endif - } - return r; -} - -/* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */ -ST_FUNC void gv2(int rc1, int rc2) -{ - int v; - - /* generate more generic register first. But VT_JMP or VT_CMP - values must be generated first in all cases to avoid possible - reload errors */ - v = vtop[0].r & VT_VALMASK; - if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) { - vswap(); - gv(rc1); - vswap(); - gv(rc2); - /* test if reload is needed for first register */ - if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) { - vswap(); - gv(rc1); - vswap(); - } - } else { - gv(rc2); - vswap(); - gv(rc1); - vswap(); - /* test if reload is needed for first register */ - if ((vtop[0].r & VT_VALMASK) >= VT_CONST) { - gv(rc2); - } - } -} - -#ifndef TCC_TARGET_ARM64 -/* wrapper around RC_FRET to return a register by type */ -static int rc_fret(int t) -{ -#ifdef TCC_TARGET_X86_64 - if (t == VT_LDOUBLE) { - return RC_ST0; - } -#endif - return RC_FRET; -} -#endif - -/* wrapper around REG_FRET to return a register by type */ -static int reg_fret(int t) -{ -#ifdef TCC_TARGET_X86_64 - if (t == VT_LDOUBLE) { - return TREG_ST0; - } -#endif - return REG_FRET; -} - -/* expand long long on stack in two int registers */ -static void lexpand(void) -{ - int u; - - u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED); - gv(RC_INT); - vdup(); - vtop[0].r = vtop[-1].r2; - vtop[0].r2 = VT_CONST; - vtop[-1].r2 = VT_CONST; - vtop[0].type.t = VT_INT | u; - vtop[-1].type.t = VT_INT | u; -} - -#ifdef TCC_TARGET_ARM -/* expand long long on stack */ -ST_FUNC void lexpand_nr(void) -{ - int u,v; - - u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED); - vdup(); - vtop->r2 = VT_CONST; - vtop->type.t = VT_INT | u; - v=vtop[-1].r & (VT_VALMASK | VT_LVAL); - if (v == VT_CONST) { - vtop[-1].c.i = vtop->c.i; - vtop->c.i = vtop->c.i >> 32; - vtop->r = VT_CONST; - } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) { - vtop->c.i += 4; - vtop->r = vtop[-1].r; - } else if (v > VT_CONST) { - vtop--; - lexpand(); - } else - vtop->r = vtop[-1].r2; - vtop[-1].r2 = VT_CONST; - vtop[-1].type.t = VT_INT | u; -} -#endif - -/* build a long long from two ints */ -static void lbuild(int t) -{ - gv2(RC_INT, RC_INT); - vtop[-1].r2 = vtop[0].r; - vtop[-1].type.t = t; - vpop(); -} - -/* rotate n first stack elements to the bottom - I1 ... In -> I2 ... In I1 [top is right] -*/ -ST_FUNC void vrotb(int n) -{ - int i; - SValue tmp; - - tmp = vtop[-n + 1]; - for(i=-n+1;i!=0;i++) - vtop[i] = vtop[i+1]; - vtop[0] = tmp; -} - -/* rotate the n elements before entry e towards the top - I1 ... In ... -> In I1 ... I(n-1) ... [top is right] - */ -ST_FUNC void vrote(SValue *e, int n) -{ - int i; - SValue tmp; - - tmp = *e; - for(i = 0;i < n - 1; i++) - e[-i] = e[-i - 1]; - e[-n + 1] = tmp; -} - -/* rotate n first stack elements to the top - I1 ... In -> In I1 ... I(n-1) [top is right] - */ -ST_FUNC void vrott(int n) -{ - vrote(vtop, n); -} - -/* pop stack value */ -ST_FUNC void vpop(void) -{ - int v; - v = vtop->r & VT_VALMASK; -#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) - /* for x86, we need to pop the FP stack */ - if (v == TREG_ST0 && !nocode_wanted) { - o(0xd8dd); /* fstp %st(0) */ - } else -#endif - if (v == VT_JMP || v == VT_JMPI) { - /* need to put correct jump if && or || without test */ - gsym(vtop->c.i); - } - vtop--; -} - -/* convert stack entry to register and duplicate its value in another - register */ -static void gv_dup(void) -{ - int rc, t, r, r1; - SValue sv; - - t = vtop->type.t; - if ((t & VT_BTYPE) == VT_LLONG) { - lexpand(); - gv_dup(); - vswap(); - vrotb(3); - gv_dup(); - vrotb(4); - /* stack: H L L1 H1 */ - lbuild(t); - vrotb(3); - vrotb(3); - vswap(); - lbuild(t); - vswap(); - } else { - /* duplicate value */ - rc = RC_INT; - sv.type.t = VT_INT; - if (is_float(t)) { - rc = RC_FLOAT; -#ifdef TCC_TARGET_X86_64 - if ((t & VT_BTYPE) == VT_LDOUBLE) { - rc = RC_ST0; - } -#endif - sv.type.t = t; - } - r = gv(rc); - r1 = get_reg(rc); - sv.r = r; - sv.c.i = 0; - load(r1, &sv); /* move r to r1 */ - vdup(); - /* duplicates value */ - if (r != r1) - vtop->r = r1; - } -} - -/* Generate value test - * - * Generate a test for any value (jump, comparison and integers) */ -ST_FUNC int gvtst(int inv, int t) -{ - int v = vtop->r & VT_VALMASK; - if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) { - vpushi(0); - gen_op(TOK_NE); - } - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - /* constant jmp optimization */ - if ((vtop->c.i != 0) != inv) - t = gjmp(t); - vtop--; - return t; - } - return gtst(inv, t); -} - -#if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64) -/* generate CPU independent (unsigned) long long operations */ -static void gen_opl(int op) -{ - int t, a, b, op1, c, i; - int func; - unsigned short reg_iret = REG_IRET; - unsigned short reg_lret = REG_LRET; - SValue tmp; - - switch(op) { - case '/': - case TOK_PDIV: - func = TOK___divdi3; - goto gen_func; - case TOK_UDIV: - func = TOK___udivdi3; - goto gen_func; - case '%': - func = TOK___moddi3; - goto gen_mod_func; - case TOK_UMOD: - func = TOK___umoddi3; - gen_mod_func: -#ifdef TCC_ARM_EABI - reg_iret = TREG_R2; - reg_lret = TREG_R3; -#endif - gen_func: - /* call generic long long function */ - vpush_global_sym(&func_old_type, func); - vrott(3); - gfunc_call(2); - vpushi(0); - vtop->r = reg_iret; - vtop->r2 = reg_lret; - break; - case '^': - case '&': - case '|': - case '*': - case '+': - case '-': - t = vtop->type.t; - vswap(); - lexpand(); - vrotb(3); - lexpand(); - /* stack: L1 H1 L2 H2 */ - tmp = vtop[0]; - vtop[0] = vtop[-3]; - vtop[-3] = tmp; - tmp = vtop[-2]; - vtop[-2] = vtop[-3]; - vtop[-3] = tmp; - vswap(); - /* stack: H1 H2 L1 L2 */ - if (op == '*') { - vpushv(vtop - 1); - vpushv(vtop - 1); - gen_op(TOK_UMULL); - lexpand(); - /* stack: H1 H2 L1 L2 ML MH */ - for(i=0;i<4;i++) - vrotb(6); - /* stack: ML MH H1 H2 L1 L2 */ - tmp = vtop[0]; - vtop[0] = vtop[-2]; - vtop[-2] = tmp; - /* stack: ML MH H1 L2 H2 L1 */ - gen_op('*'); - vrotb(3); - vrotb(3); - gen_op('*'); - /* stack: ML MH M1 M2 */ - gen_op('+'); - gen_op('+'); - } else if (op == '+' || op == '-') { - /* XXX: add non carry method too (for MIPS or alpha) */ - if (op == '+') - op1 = TOK_ADDC1; - else - op1 = TOK_SUBC1; - gen_op(op1); - /* stack: H1 H2 (L1 op L2) */ - vrotb(3); - vrotb(3); - gen_op(op1 + 1); /* TOK_xxxC2 */ - } else { - gen_op(op); - /* stack: H1 H2 (L1 op L2) */ - vrotb(3); - vrotb(3); - /* stack: (L1 op L2) H1 H2 */ - gen_op(op); - /* stack: (L1 op L2) (H1 op H2) */ - } - /* stack: L H */ - lbuild(t); - break; - case TOK_SAR: - case TOK_SHR: - case TOK_SHL: - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - t = vtop[-1].type.t; - vswap(); - lexpand(); - vrotb(3); - /* stack: L H shift */ - c = (int)vtop->c.i; - /* constant: simpler */ - /* NOTE: all comments are for SHL. the other cases are - done by swaping words */ - vpop(); - if (op != TOK_SHL) - vswap(); - if (c >= 32) { - /* stack: L H */ - vpop(); - if (c > 32) { - vpushi(c - 32); - gen_op(op); - } - if (op != TOK_SAR) { - vpushi(0); - } else { - gv_dup(); - vpushi(31); - gen_op(TOK_SAR); - } - vswap(); - } else { - vswap(); - gv_dup(); - /* stack: H L L */ - vpushi(c); - gen_op(op); - vswap(); - vpushi(32 - c); - if (op == TOK_SHL) - gen_op(TOK_SHR); - else - gen_op(TOK_SHL); - vrotb(3); - /* stack: L L H */ - vpushi(c); - if (op == TOK_SHL) - gen_op(TOK_SHL); - else - gen_op(TOK_SHR); - gen_op('|'); - } - if (op != TOK_SHL) - vswap(); - lbuild(t); - } else { - /* XXX: should provide a faster fallback on x86 ? */ - switch(op) { - case TOK_SAR: - func = TOK___ashrdi3; - goto gen_func; - case TOK_SHR: - func = TOK___lshrdi3; - goto gen_func; - case TOK_SHL: - func = TOK___ashldi3; - goto gen_func; - } - } - break; - default: - /* compare operations */ - t = vtop->type.t; - vswap(); - lexpand(); - vrotb(3); - lexpand(); - /* stack: L1 H1 L2 H2 */ - tmp = vtop[-1]; - vtop[-1] = vtop[-2]; - vtop[-2] = tmp; - /* stack: L1 L2 H1 H2 */ - /* compare high */ - op1 = op; - /* when values are equal, we need to compare low words. since - the jump is inverted, we invert the test too. */ - if (op1 == TOK_LT) - op1 = TOK_LE; - else if (op1 == TOK_GT) - op1 = TOK_GE; - else if (op1 == TOK_ULT) - op1 = TOK_ULE; - else if (op1 == TOK_UGT) - op1 = TOK_UGE; - a = 0; - b = 0; - gen_op(op1); - if (op1 != TOK_NE) { - a = gvtst(1, 0); - } - if (op != TOK_EQ) { - /* generate non equal test */ - /* XXX: NOT PORTABLE yet */ - if (a == 0) { - b = gvtst(0, 0); - } else { -#if defined(TCC_TARGET_I386) - b = psym(0x850f, 0); -#elif defined(TCC_TARGET_ARM) - b = ind; - o(0x1A000000 | encbranch(ind, 0, 1)); -#elif defined(TCC_TARGET_C67) || defined(TCC_TARGET_ARM64) - tcc_error("not implemented"); -#else -#error not supported -#endif - } - } - /* compare low. Always unsigned */ - op1 = op; - if (op1 == TOK_LT) - op1 = TOK_ULT; - else if (op1 == TOK_LE) - op1 = TOK_ULE; - else if (op1 == TOK_GT) - op1 = TOK_UGT; - else if (op1 == TOK_GE) - op1 = TOK_UGE; - gen_op(op1); - a = gvtst(1, a); - gsym(b); - vseti(VT_JMPI, a); - break; - } -} -#endif - -static uint64_t gen_opic_sdiv(uint64_t a, uint64_t b) -{ - uint64_t x = (a >> 63 ? -a : a) / (b >> 63 ? -b : b); - return (a ^ b) >> 63 ? -x : x; -} - -static int gen_opic_lt(uint64_t a, uint64_t b) -{ - return (a ^ (uint64_t)1 << 63) < (b ^ (uint64_t)1 << 63); -} - -/* handle integer constant optimizations and various machine - independent opt */ -static void gen_opic(int op) -{ - SValue *v1 = vtop - 1; - SValue *v2 = vtop; - int t1 = v1->type.t & VT_BTYPE; - int t2 = v2->type.t & VT_BTYPE; - int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; - int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; - uint64_t l1 = c1 ? v1->c.i : 0; - uint64_t l2 = c2 ? v2->c.i : 0; - int shm = (t1 == VT_LLONG) ? 63 : 31; - - if (t1 != VT_LLONG) - l1 = ((uint32_t)l1 | - (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000))); - if (t2 != VT_LLONG) - l2 = ((uint32_t)l2 | - (v2->type.t & VT_UNSIGNED ? 0 : -(l2 & 0x80000000))); - - if (c1 && c2) { - switch(op) { - case '+': l1 += l2; break; - case '-': l1 -= l2; break; - case '&': l1 &= l2; break; - case '^': l1 ^= l2; break; - case '|': l1 |= l2; break; - case '*': l1 *= l2; break; - - case TOK_PDIV: - case '/': - case '%': - case TOK_UDIV: - case TOK_UMOD: - /* if division by zero, generate explicit division */ - if (l2 == 0) { - if (const_wanted) - tcc_error("division by zero in constant"); - goto general_case; - } - switch(op) { - default: l1 = gen_opic_sdiv(l1, l2); break; - case '%': l1 = l1 - l2 * gen_opic_sdiv(l1, l2); break; - case TOK_UDIV: l1 = l1 / l2; break; - case TOK_UMOD: l1 = l1 % l2; break; - } - break; - case TOK_SHL: l1 <<= (l2 & shm); break; - case TOK_SHR: l1 >>= (l2 & shm); break; - case TOK_SAR: - l1 = (l1 >> 63) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm); - break; - /* tests */ - case TOK_ULT: l1 = l1 < l2; break; - case TOK_UGE: l1 = l1 >= l2; break; - case TOK_EQ: l1 = l1 == l2; break; - case TOK_NE: l1 = l1 != l2; break; - case TOK_ULE: l1 = l1 <= l2; break; - case TOK_UGT: l1 = l1 > l2; break; - case TOK_LT: l1 = gen_opic_lt(l1, l2); break; - case TOK_GE: l1 = !gen_opic_lt(l1, l2); break; - case TOK_LE: l1 = !gen_opic_lt(l2, l1); break; - case TOK_GT: l1 = gen_opic_lt(l2, l1); break; - /* logical */ - case TOK_LAND: l1 = l1 && l2; break; - case TOK_LOR: l1 = l1 || l2; break; - default: - goto general_case; - } - v1->c.i = l1; - vtop--; - } else { - /* if commutative ops, put c2 as constant */ - if (c1 && (op == '+' || op == '&' || op == '^' || - op == '|' || op == '*')) { - vswap(); - c2 = c1; //c = c1, c1 = c2, c2 = c; - l2 = l1; //l = l1, l1 = l2, l2 = l; - } - if (!const_wanted && - c1 && ((l1 == 0 && - (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) || - (l1 == -1 && op == TOK_SAR))) { - /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */ - vtop--; - } else if (!const_wanted && - c2 && ((l2 == 0 && (op == '&' || op == '*')) || - (l2 == -1 && op == '|') || - (l2 == 0xffffffff && t2 != VT_LLONG && op == '|') || - (l2 == 1 && (op == '%' || op == TOK_UMOD)))) { - /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */ - if (l2 == 1) - vtop->c.i = 0; - vswap(); - vtop--; - } else if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV || - op == TOK_PDIV) && - l2 == 1) || - ((op == '+' || op == '-' || op == '|' || op == '^' || - op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) && - l2 == 0) || - (op == '&' && - l2 == -1))) { - /* filter out NOP operations like x*1, x-0, x&-1... */ - vtop--; - } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) { - /* try to use shifts instead of muls or divs */ - if (l2 > 0 && (l2 & (l2 - 1)) == 0) { - int n = -1; - while (l2) { - l2 >>= 1; - n++; - } - vtop->c.i = n; - if (op == '*') - op = TOK_SHL; - else if (op == TOK_PDIV) - op = TOK_SAR; - else - op = TOK_SHR; - } - goto general_case; - } else if (c2 && (op == '+' || op == '-') && - (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM)) - || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) { - /* symbol + constant case */ - if (op == '-') - l2 = -l2; - vtop--; - vtop->c.i += l2; - } else { - general_case: - if (!nocode_wanted) { - /* call low level op generator */ - if (t1 == VT_LLONG || t2 == VT_LLONG || - (PTR_SIZE == 8 && (t1 == VT_PTR || t2 == VT_PTR))) - gen_opl(op); - else - gen_opi(op); - } else { - vtop--; - } - } - } -} - -/* generate a floating point operation with constant propagation */ -static void gen_opif(int op) -{ - int c1, c2; - SValue *v1, *v2; - long double f1, f2; - - v1 = vtop - 1; - v2 = vtop; - /* currently, we cannot do computations with forward symbols */ - c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; - c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; - if (c1 && c2) { - if (v1->type.t == VT_FLOAT) { - f1 = v1->c.f; - f2 = v2->c.f; - } else if (v1->type.t == VT_DOUBLE) { - f1 = v1->c.d; - f2 = v2->c.d; - } else { - f1 = v1->c.ld; - f2 = v2->c.ld; - } - - /* NOTE: we only do constant propagation if finite number (not - NaN or infinity) (ANSI spec) */ - if (!ieee_finite(f1) || !ieee_finite(f2)) - goto general_case; - - switch(op) { - case '+': f1 += f2; break; - case '-': f1 -= f2; break; - case '*': f1 *= f2; break; - case '/': - if (f2 == 0.0) { - if (const_wanted) - tcc_error("division by zero in constant"); - goto general_case; - } - f1 /= f2; - break; - /* XXX: also handles tests ? */ - default: - goto general_case; - } - /* XXX: overflow test ? */ - if (v1->type.t == VT_FLOAT) { - v1->c.f = f1; - } else if (v1->type.t == VT_DOUBLE) { - v1->c.d = f1; - } else { - v1->c.ld = f1; - } - vtop--; - } else { - general_case: - if (!nocode_wanted) { - gen_opf(op); - } else { - vtop--; - } - } -} - -static int pointed_size(CType *type) -{ - int align; - return type_size(pointed_type(type), &align); -} - -static void vla_runtime_pointed_size(CType *type) -{ - int align; - vla_runtime_type_size(pointed_type(type), &align); -} - -static inline int is_null_pointer(SValue *p) -{ - if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) - return 0; - return ((p->type.t & VT_BTYPE) == VT_INT && (uint32_t)p->c.i == 0) || - ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.i == 0) || - ((p->type.t & VT_BTYPE) == VT_PTR && - (PTR_SIZE == 4 ? (uint32_t)p->c.i == 0 : p->c.i == 0)); -} - -static inline int is_integer_btype(int bt) -{ - return (bt == VT_BYTE || bt == VT_SHORT || - bt == VT_INT || bt == VT_LLONG); -} - -/* check types for comparison or subtraction of pointers */ -static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op) -{ - CType *type1, *type2, tmp_type1, tmp_type2; - int bt1, bt2; - - /* null pointers are accepted for all comparisons as gcc */ - if (is_null_pointer(p1) || is_null_pointer(p2)) - return; - type1 = &p1->type; - type2 = &p2->type; - bt1 = type1->t & VT_BTYPE; - bt2 = type2->t & VT_BTYPE; - /* accept comparison between pointer and integer with a warning */ - if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') { - if (op != TOK_LOR && op != TOK_LAND ) - tcc_warning("comparison between pointer and integer"); - return; - } - - /* both must be pointers or implicit function pointers */ - if (bt1 == VT_PTR) { - type1 = pointed_type(type1); - } else if (bt1 != VT_FUNC) - goto invalid_operands; - - if (bt2 == VT_PTR) { - type2 = pointed_type(type2); - } else if (bt2 != VT_FUNC) { - invalid_operands: - tcc_error("invalid operands to binary %s", get_tok_str(op, NULL)); - } - if ((type1->t & VT_BTYPE) == VT_VOID || - (type2->t & VT_BTYPE) == VT_VOID) - return; - tmp_type1 = *type1; - tmp_type2 = *type2; - tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); - tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); - if (!is_compatible_types(&tmp_type1, &tmp_type2)) { - /* gcc-like error if '-' is used */ - if (op == '-') - goto invalid_operands; - else - tcc_warning("comparison of distinct pointer types lacks a cast"); - } -} - -/* generic gen_op: handles types problems */ -ST_FUNC void gen_op(int op) -{ - int u, t1, t2, bt1, bt2, t; - CType type1; - - t1 = vtop[-1].type.t; - t2 = vtop[0].type.t; - bt1 = t1 & VT_BTYPE; - bt2 = t2 & VT_BTYPE; - - if (bt1 == VT_PTR || bt2 == VT_PTR) { - /* at least one operand is a pointer */ - /* relationnal op: must be both pointers */ - if (op >= TOK_ULT && op <= TOK_LOR) { - check_comparison_pointer_types(vtop - 1, vtop, op); - /* pointers are handled are unsigned */ -#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) - t = VT_LLONG | VT_UNSIGNED; -#else - t = VT_INT | VT_UNSIGNED; -#endif - goto std_op; - } - /* if both pointers, then it must be the '-' op */ - if (bt1 == VT_PTR && bt2 == VT_PTR) { - if (op != '-') - tcc_error("cannot use pointers here"); - check_comparison_pointer_types(vtop - 1, vtop, op); - /* XXX: check that types are compatible */ - if (vtop[-1].type.t & VT_VLA) { - vla_runtime_pointed_size(&vtop[-1].type); - } else { - vpushi(pointed_size(&vtop[-1].type)); - } - vrott(3); - gen_opic(op); - /* set to integer type */ -#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) - vtop->type.t = VT_LLONG; -#else - vtop->type.t = VT_INT; -#endif - vswap(); - gen_op(TOK_PDIV); - } else { - /* exactly one pointer : must be '+' or '-'. */ - if (op != '-' && op != '+') - tcc_error("cannot use pointers here"); - /* Put pointer as first operand */ - if (bt2 == VT_PTR) { - vswap(); - swap(&t1, &t2); - } - type1 = vtop[-1].type; - type1.t &= ~VT_ARRAY; - if (vtop[-1].type.t & VT_VLA) - vla_runtime_pointed_size(&vtop[-1].type); - else { - u = pointed_size(&vtop[-1].type); - if (u < 0) - tcc_error("unknown array element size"); -#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) - vpushll(u); -#else - /* XXX: cast to int ? (long long case) */ - vpushi(u); -#endif - } - gen_op('*'); -#if 0 -/* #ifdef CONFIG_TCC_BCHECK - The main reason to removing this code: - #include - int main () - { - int v[10]; - int i = 10; - int j = 9; - fprintf(stderr, "v+i-j = %p\n", v+i-j); - fprintf(stderr, "v+(i-j) = %p\n", v+(i-j)); - } - When this code is on. then the output looks like - v+i-j = 0xfffffffe - v+(i-j) = 0xbff84000 - */ - /* if evaluating constant expression, no code should be - generated, so no bound check */ - if (tcc_state->do_bounds_check && !const_wanted) { - /* if bounded pointers, we generate a special code to - test bounds */ - if (op == '-') { - vpushi(0); - vswap(); - gen_op('-'); - } - gen_bounded_ptr_add(); - } else -#endif - { - gen_opic(op); - } - /* put again type if gen_opic() swaped operands */ - vtop->type = type1; - } - } else if (is_float(bt1) || is_float(bt2)) { - /* compute bigger type and do implicit casts */ - if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) { - t = VT_LDOUBLE; - } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) { - t = VT_DOUBLE; - } else { - t = VT_FLOAT; - } - /* floats can only be used for a few operations */ - if (op != '+' && op != '-' && op != '*' && op != '/' && - (op < TOK_ULT || op > TOK_GT)) - tcc_error("invalid operands for binary operation"); - goto std_op; - } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) { - t = bt1 == VT_LLONG ? VT_LLONG : VT_INT; - if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (t | VT_UNSIGNED)) - t |= VT_UNSIGNED; - goto std_op; - } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) { - /* cast to biggest op */ - t = VT_LLONG; - /* convert to unsigned if it does not fit in a long long */ - if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) || - (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED)) - t |= VT_UNSIGNED; - goto std_op; - } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) { - tcc_error("comparison of struct"); - } else { - /* integer operations */ - t = VT_INT; - /* convert to unsigned if it does not fit in an integer */ - if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) || - (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED)) - t |= VT_UNSIGNED; - std_op: - /* XXX: currently, some unsigned operations are explicit, so - we modify them here */ - if (t & VT_UNSIGNED) { - if (op == TOK_SAR) - op = TOK_SHR; - else if (op == '/') - op = TOK_UDIV; - else if (op == '%') - op = TOK_UMOD; - else if (op == TOK_LT) - op = TOK_ULT; - else if (op == TOK_GT) - op = TOK_UGT; - else if (op == TOK_LE) - op = TOK_ULE; - else if (op == TOK_GE) - op = TOK_UGE; - } - vswap(); - type1.t = t; - gen_cast(&type1); - vswap(); - /* special case for shifts and long long: we keep the shift as - an integer */ - if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) - type1.t = VT_INT; - gen_cast(&type1); - if (is_float(t)) - gen_opif(op); - else - gen_opic(op); - if (op >= TOK_ULT && op <= TOK_GT) { - /* relationnal op: the result is an int */ - vtop->type.t = VT_INT; - } else { - vtop->type.t = t; - } - } - // Make sure that we have converted to an rvalue: - if (vtop->r & VT_LVAL && !nocode_wanted) - gv(is_float(vtop->type.t & VT_BTYPE) ? RC_FLOAT : RC_INT); -} - -#ifndef TCC_TARGET_ARM -/* generic itof for unsigned long long case */ -static void gen_cvt_itof1(int t) -{ -#ifdef TCC_TARGET_ARM64 - gen_cvt_itof(t); -#else - if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == - (VT_LLONG | VT_UNSIGNED)) { - - if (t == VT_FLOAT) - vpush_global_sym(&func_old_type, TOK___floatundisf); -#if LDOUBLE_SIZE != 8 - else if (t == VT_LDOUBLE) - vpush_global_sym(&func_old_type, TOK___floatundixf); -#endif - else - vpush_global_sym(&func_old_type, TOK___floatundidf); - vrott(2); - gfunc_call(1); - vpushi(0); - vtop->r = reg_fret(t); - } else { - gen_cvt_itof(t); - } -#endif -} -#endif - -/* generic ftoi for unsigned long long case */ -static void gen_cvt_ftoi1(int t) -{ -#ifdef TCC_TARGET_ARM64 - gen_cvt_ftoi(t); -#else - int st; - - if (t == (VT_LLONG | VT_UNSIGNED)) { - /* not handled natively */ - st = vtop->type.t & VT_BTYPE; - if (st == VT_FLOAT) - vpush_global_sym(&func_old_type, TOK___fixunssfdi); -#if LDOUBLE_SIZE != 8 - else if (st == VT_LDOUBLE) - vpush_global_sym(&func_old_type, TOK___fixunsxfdi); -#endif - else - vpush_global_sym(&func_old_type, TOK___fixunsdfdi); - vrott(2); - gfunc_call(1); - vpushi(0); - vtop->r = REG_IRET; - vtop->r2 = REG_LRET; - } else { - gen_cvt_ftoi(t); - } -#endif -} - -/* force char or short cast */ -static void force_charshort_cast(int t) -{ - int bits, dbt; - dbt = t & VT_BTYPE; - /* XXX: add optimization if lvalue : just change type and offset */ - if (dbt == VT_BYTE) - bits = 8; - else - bits = 16; - if (t & VT_UNSIGNED) { - vpushi((1 << bits) - 1); - gen_op('&'); - } else { - bits = 32 - bits; - vpushi(bits); - gen_op(TOK_SHL); - /* result must be signed or the SAR is converted to an SHL - This was not the case when "t" was a signed short - and the last value on the stack was an unsigned int */ - vtop->type.t &= ~VT_UNSIGNED; - vpushi(bits); - gen_op(TOK_SAR); - } -} - -/* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */ -static void gen_cast(CType *type) -{ - int sbt, dbt, sf, df, c, p; - - /* special delayed cast for char/short */ - /* XXX: in some cases (multiple cascaded casts), it may still - be incorrect */ - if (vtop->r & VT_MUSTCAST) { - vtop->r &= ~VT_MUSTCAST; - force_charshort_cast(vtop->type.t); - } - - /* bitfields first get cast to ints */ - if (vtop->type.t & VT_BITFIELD && !nocode_wanted) { - gv(RC_INT); - } - - dbt = type->t & (VT_BTYPE | VT_UNSIGNED); - sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED); - - if (sbt != dbt) { - sf = is_float(sbt); - df = is_float(dbt); - c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; - p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM); - if (c) { - /* constant case: we can do it now */ - /* XXX: in ISOC, cannot do it if error in convert */ - if (sbt == VT_FLOAT) - vtop->c.ld = vtop->c.f; - else if (sbt == VT_DOUBLE) - vtop->c.ld = vtop->c.d; - - if (df) { - if ((sbt & VT_BTYPE) == VT_LLONG) { - if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 63)) - vtop->c.ld = vtop->c.i; - else - vtop->c.ld = -(long double)-vtop->c.i; - } else if(!sf) { - if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 31)) - vtop->c.ld = (uint32_t)vtop->c.i; - else - vtop->c.ld = -(long double)-(uint32_t)vtop->c.i; - } - - if (dbt == VT_FLOAT) - vtop->c.f = (float)vtop->c.ld; - else if (dbt == VT_DOUBLE) - vtop->c.d = (double)vtop->c.ld; - } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) { - vtop->c.i = vtop->c.ld; - } else if (sf && dbt == VT_BOOL) { - vtop->c.i = (vtop->c.ld != 0); - } else { - if(sf) - vtop->c.i = vtop->c.ld; - else if (sbt == (VT_LLONG|VT_UNSIGNED)) - ; - else if (sbt & VT_UNSIGNED) - vtop->c.i = (uint32_t)vtop->c.i; -#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) - else if (sbt == VT_PTR) - ; -#endif - else if (sbt != VT_LLONG) - vtop->c.i = ((uint32_t)vtop->c.i | - -(vtop->c.i & 0x80000000)); - - if (dbt == (VT_LLONG|VT_UNSIGNED)) - ; - else if (dbt == VT_BOOL) - vtop->c.i = (vtop->c.i != 0); -#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) - else if (dbt == VT_PTR) - ; -#endif - else if (dbt != VT_LLONG) { - uint32_t m = ((dbt & VT_BTYPE) == VT_BYTE ? 0xff : - (dbt & VT_BTYPE) == VT_SHORT ? 0xffff : - 0xffffffff); - vtop->c.i &= m; - if (!(dbt & VT_UNSIGNED)) - vtop->c.i |= -(vtop->c.i & ((m >> 1) + 1)); - } - } - } else if (p && dbt == VT_BOOL) { - vtop->r = VT_CONST; - vtop->c.i = 1; - } else if (!nocode_wanted) { - /* non constant case: generate code */ - if (sf && df) { - /* convert from fp to fp */ - gen_cvt_ftof(dbt); - } else if (df) { - /* convert int to fp */ - gen_cvt_itof1(dbt); - } else if (sf) { - /* convert fp to int */ - if (dbt == VT_BOOL) { - vpushi(0); - gen_op(TOK_NE); - } else { - /* we handle char/short/etc... with generic code */ - if (dbt != (VT_INT | VT_UNSIGNED) && - dbt != (VT_LLONG | VT_UNSIGNED) && - dbt != VT_LLONG) - dbt = VT_INT; - gen_cvt_ftoi1(dbt); - if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) { - /* additional cast for char/short... */ - vtop->type.t = dbt; - gen_cast(type); - } - } -#if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64) - } else if ((dbt & VT_BTYPE) == VT_LLONG) { - if ((sbt & VT_BTYPE) != VT_LLONG && !nocode_wanted) { - /* scalar to long long */ - /* machine independent conversion */ - gv(RC_INT); - /* generate high word */ - if (sbt == (VT_INT | VT_UNSIGNED)) { - vpushi(0); - gv(RC_INT); - } else { - if (sbt == VT_PTR) { - /* cast from pointer to int before we apply - shift operation, which pointers don't support*/ - gen_cast(&int_type); - } - gv_dup(); - vpushi(31); - gen_op(TOK_SAR); - } - /* patch second register */ - vtop[-1].r2 = vtop->r; - vpop(); - } -#else - } else if ((dbt & VT_BTYPE) == VT_LLONG || - (dbt & VT_BTYPE) == VT_PTR || - (dbt & VT_BTYPE) == VT_FUNC) { - if ((sbt & VT_BTYPE) != VT_LLONG && - (sbt & VT_BTYPE) != VT_PTR && - (sbt & VT_BTYPE) != VT_FUNC && !nocode_wanted) { - /* need to convert from 32bit to 64bit */ - gv(RC_INT); - if (sbt != (VT_INT | VT_UNSIGNED)) { -#if defined(TCC_TARGET_ARM64) - gen_cvt_sxtw(); -#elif defined(TCC_TARGET_X86_64) - int r = gv(RC_INT); - /* x86_64 specific: movslq */ - o(0x6348); - o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r)); -#else -#error -#endif - } - } -#endif - } else if (dbt == VT_BOOL) { - /* scalar to bool */ - vpushi(0); - gen_op(TOK_NE); - } else if ((dbt & VT_BTYPE) == VT_BYTE || - (dbt & VT_BTYPE) == VT_SHORT) { - if (sbt == VT_PTR) { - vtop->type.t = VT_INT; - tcc_warning("nonportable conversion from pointer to char/short"); - } - force_charshort_cast(dbt); - } else if ((dbt & VT_BTYPE) == VT_INT) { - /* scalar to int */ - if (sbt == VT_LLONG && !nocode_wanted) { - /* from long long: just take low order word */ - lexpand(); - vpop(); - } - /* if lvalue and single word type, nothing to do because - the lvalue already contains the real type size (see - VT_LVAL_xxx constants) */ - } - } - } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) { - /* if we are casting between pointer types, - we must update the VT_LVAL_xxx size */ - vtop->r = (vtop->r & ~VT_LVAL_TYPE) - | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE); - } - vtop->type = *type; -} - -/* return type size as known at compile time. Put alignment at 'a' */ -ST_FUNC int type_size(CType *type, int *a) -{ - Sym *s; - int bt; - - bt = type->t & VT_BTYPE; - if (bt == VT_STRUCT) { - /* struct/union */ - s = type->ref; - *a = s->r; - return s->c; - } else if (bt == VT_PTR) { - if (type->t & VT_ARRAY) { - int ts; - - s = type->ref; - ts = type_size(&s->type, a); - - if (ts < 0 && s->c < 0) - ts = -ts; - - return ts * s->c; - } else { - *a = PTR_SIZE; - return PTR_SIZE; - } - } else if (bt == VT_LDOUBLE) { - *a = LDOUBLE_ALIGN; - return LDOUBLE_SIZE; - } else if (bt == VT_DOUBLE || bt == VT_LLONG) { -#ifdef TCC_TARGET_I386 -#ifdef TCC_TARGET_PE - *a = 8; -#else - *a = 4; -#endif -#elif defined(TCC_TARGET_ARM) -#ifdef TCC_ARM_EABI - *a = 8; -#else - *a = 4; -#endif -#else - *a = 8; -#endif - return 8; - } else if (bt == VT_INT || bt == VT_FLOAT) { - *a = 4; - return 4; - } else if (bt == VT_SHORT) { - *a = 2; - return 2; - } else if (bt == VT_QLONG || bt == VT_QFLOAT) { - *a = 8; - return 16; - } else if (bt == VT_ENUM) { - *a = 4; - /* Enums might be incomplete, so don't just return '4' here. */ - return type->ref->c; - } else { - /* char, void, function, _Bool */ - *a = 1; - return 1; - } -} - -/* push type size as known at runtime time on top of value stack. Put - alignment at 'a' */ -ST_FUNC void vla_runtime_type_size(CType *type, int *a) -{ - if (type->t & VT_VLA) { - vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c); - } else { - vpushi(type_size(type, a)); - } -} - -static void vla_sp_restore(void) { - if (vlas_in_scope) { - gen_vla_sp_restore(vla_sp_loc); - } -} - -static void vla_sp_restore_root(void) { - if (vlas_in_scope) { - gen_vla_sp_restore(vla_sp_root_loc); - } -} - -/* return the pointed type of t */ -static inline CType *pointed_type(CType *type) -{ - return &type->ref->type; -} - -/* modify type so that its it is a pointer to type. */ -ST_FUNC void mk_pointer(CType *type) -{ - Sym *s; - s = sym_push(SYM_FIELD, type, 0, -1); - type->t = VT_PTR | (type->t & ~VT_TYPE); - type->ref = s; -} - -/* compare function types. OLD functions match any new functions */ -static int is_compatible_func(CType *type1, CType *type2) -{ - Sym *s1, *s2; - - s1 = type1->ref; - s2 = type2->ref; - if (!is_compatible_types(&s1->type, &s2->type)) - return 0; - /* check func_call */ - if (s1->a.func_call != s2->a.func_call) - return 0; - /* XXX: not complete */ - if (s1->c == FUNC_OLD || s2->c == FUNC_OLD) - return 1; - if (s1->c != s2->c) - return 0; - while (s1 != NULL) { - if (s2 == NULL) - return 0; - if (!is_compatible_parameter_types(&s1->type, &s2->type)) - return 0; - s1 = s1->next; - s2 = s2->next; - } - if (s2) - return 0; - return 1; -} - -/* return true if type1 and type2 are the same. If unqualified is - true, qualifiers on the types are ignored. - - - enums are not checked as gcc __builtin_types_compatible_p () - */ -static int compare_types(CType *type1, CType *type2, int unqualified) -{ - int bt1, t1, t2; - - t1 = type1->t & VT_TYPE; - t2 = type2->t & VT_TYPE; - if (unqualified) { - /* strip qualifiers before comparing */ - t1 &= ~(VT_CONSTANT | VT_VOLATILE); - t2 &= ~(VT_CONSTANT | VT_VOLATILE); - } - /* Default Vs explicit signedness only matters for char */ - if ((t1 & VT_BTYPE) != VT_BYTE) { - t1 &= ~VT_DEFSIGN; - t2 &= ~VT_DEFSIGN; - } - /* XXX: bitfields ? */ - if (t1 != t2) - return 0; - /* test more complicated cases */ - bt1 = t1 & VT_BTYPE; - if (bt1 == VT_PTR) { - type1 = pointed_type(type1); - type2 = pointed_type(type2); - return is_compatible_types(type1, type2); - } else if (bt1 == VT_STRUCT) { - return (type1->ref == type2->ref); - } else if (bt1 == VT_FUNC) { - return is_compatible_func(type1, type2); - } else { - return 1; - } -} - -/* return true if type1 and type2 are exactly the same (including - qualifiers). -*/ -static int is_compatible_types(CType *type1, CType *type2) -{ - return compare_types(type1,type2,0); -} - -/* return true if type1 and type2 are the same (ignoring qualifiers). -*/ -static int is_compatible_parameter_types(CType *type1, CType *type2) -{ - return compare_types(type1,type2,1); -} - -/* print a type. If 'varstr' is not NULL, then the variable is also - printed in the type */ -/* XXX: union */ -/* XXX: add array and function pointers */ -static void type_to_str(char *buf, int buf_size, - CType *type, const char *varstr) -{ - int bt, v, t; - Sym *s, *sa; - char buf1[256]; - const char *tstr; - - t = type->t & VT_TYPE; - bt = t & VT_BTYPE; - buf[0] = '\0'; - if (t & VT_CONSTANT) - pstrcat(buf, buf_size, "const "); - if (t & VT_VOLATILE) - pstrcat(buf, buf_size, "volatile "); - if ((t & (VT_DEFSIGN | VT_UNSIGNED)) == (VT_DEFSIGN | VT_UNSIGNED)) - pstrcat(buf, buf_size, "unsigned "); - else if (t & VT_DEFSIGN) - pstrcat(buf, buf_size, "signed "); - switch(bt) { - case VT_VOID: - tstr = "void"; - goto add_tstr; - case VT_BOOL: - tstr = "_Bool"; - goto add_tstr; - case VT_BYTE: - tstr = "char"; - goto add_tstr; - case VT_SHORT: - tstr = "short"; - goto add_tstr; - case VT_INT: - tstr = "int"; - goto add_tstr; - case VT_LONG: - tstr = "long"; - goto add_tstr; - case VT_LLONG: - tstr = "long long"; - goto add_tstr; - case VT_FLOAT: - tstr = "float"; - goto add_tstr; - case VT_DOUBLE: - tstr = "double"; - goto add_tstr; - case VT_LDOUBLE: - tstr = "long double"; - add_tstr: - pstrcat(buf, buf_size, tstr); - break; - case VT_ENUM: - case VT_STRUCT: - if (bt == VT_STRUCT) - tstr = "struct "; - else - tstr = "enum "; - pstrcat(buf, buf_size, tstr); - v = type->ref->v & ~SYM_STRUCT; - if (v >= SYM_FIRST_ANOM) - pstrcat(buf, buf_size, ""); - else - pstrcat(buf, buf_size, get_tok_str(v, NULL)); - break; - case VT_FUNC: - s = type->ref; - type_to_str(buf, buf_size, &s->type, varstr); - pstrcat(buf, buf_size, "("); - sa = s->next; - while (sa != NULL) { - type_to_str(buf1, sizeof(buf1), &sa->type, NULL); - pstrcat(buf, buf_size, buf1); - sa = sa->next; - if (sa) - pstrcat(buf, buf_size, ", "); - } - pstrcat(buf, buf_size, ")"); - goto no_var; - case VT_PTR: - s = type->ref; - if (t & VT_ARRAY) { - snprintf(buf1, sizeof(buf1), "%s[%ld]", varstr ? varstr : "", s->c); - type_to_str(buf, buf_size, &s->type, buf1); - goto no_var; - } - pstrcpy(buf1, sizeof(buf1), "*"); - if (t & VT_CONSTANT) - pstrcat(buf1, buf_size, "const "); - if (t & VT_VOLATILE) - pstrcat(buf1, buf_size, "volatile "); - if (varstr) - pstrcat(buf1, sizeof(buf1), varstr); - type_to_str(buf, buf_size, &s->type, buf1); - goto no_var; - } - if (varstr) { - pstrcat(buf, buf_size, " "); - pstrcat(buf, buf_size, varstr); - } - no_var: ; -} - -/* verify type compatibility to store vtop in 'dt' type, and generate - casts if needed. */ -static void gen_assign_cast(CType *dt) -{ - CType *st, *type1, *type2, tmp_type1, tmp_type2; - char buf1[256], buf2[256]; - int dbt, sbt; - - st = &vtop->type; /* source type */ - dbt = dt->t & VT_BTYPE; - sbt = st->t & VT_BTYPE; - if (sbt == VT_VOID || dbt == VT_VOID) { - if (sbt == VT_VOID && dbt == VT_VOID) - ; /* - It is Ok if both are void - A test program: - void func1() {} - void func2() { - return func1(); - } - gcc accepts this program - */ - else - tcc_error("cannot cast from/to void"); - } - if (dt->t & VT_CONSTANT) - tcc_warning("assignment of read-only location"); - switch(dbt) { - case VT_PTR: - /* special cases for pointers */ - /* '0' can also be a pointer */ - if (is_null_pointer(vtop)) - goto type_ok; - /* accept implicit pointer to integer cast with warning */ - if (is_integer_btype(sbt)) { - tcc_warning("assignment makes pointer from integer without a cast"); - goto type_ok; - } - type1 = pointed_type(dt); - /* a function is implicitely a function pointer */ - if (sbt == VT_FUNC) { - if ((type1->t & VT_BTYPE) != VT_VOID && - !is_compatible_types(pointed_type(dt), st)) - tcc_warning("assignment from incompatible pointer type"); - goto type_ok; - } - if (sbt != VT_PTR) - goto error; - type2 = pointed_type(st); - if ((type1->t & VT_BTYPE) == VT_VOID || - (type2->t & VT_BTYPE) == VT_VOID) { - /* void * can match anything */ - } else { - /* exact type match, except for unsigned */ - tmp_type1 = *type1; - tmp_type2 = *type2; - tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | - VT_VOLATILE); - tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | - VT_VOLATILE); - if (!is_compatible_types(&tmp_type1, &tmp_type2)) - tcc_warning("assignment from incompatible pointer type"); - } - /* check const and volatile */ - if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) || - (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE))) - tcc_warning("assignment discards qualifiers from pointer target type"); - break; - case VT_BYTE: - case VT_SHORT: - case VT_INT: - case VT_LLONG: - if (sbt == VT_PTR || sbt == VT_FUNC) { - tcc_warning("assignment makes integer from pointer without a cast"); - } - /* XXX: more tests */ - break; - case VT_STRUCT: - tmp_type1 = *dt; - tmp_type2 = *st; - tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE); - tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE); - if (!is_compatible_types(&tmp_type1, &tmp_type2)) { - error: - type_to_str(buf1, sizeof(buf1), st, NULL); - type_to_str(buf2, sizeof(buf2), dt, NULL); - tcc_error("cannot cast '%s' to '%s'", buf1, buf2); - } - break; - } - type_ok: - gen_cast(dt); -} - -/* store vtop in lvalue pushed on stack */ -ST_FUNC void vstore(void) -{ - int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast; - - ft = vtop[-1].type.t; - sbt = vtop->type.t & VT_BTYPE; - dbt = ft & VT_BTYPE; - if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) || - (sbt == VT_INT && dbt == VT_SHORT)) - && !(vtop->type.t & VT_BITFIELD)) { - /* optimize char/short casts */ - delayed_cast = VT_MUSTCAST; - vtop->type.t = (ft & VT_TYPE & ~VT_BITFIELD & - ((1 << VT_STRUCT_SHIFT) - 1)); - /* XXX: factorize */ - if (ft & VT_CONSTANT) - tcc_warning("assignment of read-only location"); - } else { - delayed_cast = 0; - if (!(ft & VT_BITFIELD)) - gen_assign_cast(&vtop[-1].type); - } - - if (sbt == VT_STRUCT) { - /* if structure, only generate pointer */ - /* structure assignment : generate memcpy */ - /* XXX: optimize if small size */ - if (!nocode_wanted) { - size = type_size(&vtop->type, &align); - - /* destination */ - vswap(); - vtop->type.t = VT_PTR; - gaddrof(); - - /* address of memcpy() */ -#ifdef TCC_ARM_EABI - if(!(align & 7)) - vpush_global_sym(&func_old_type, TOK_memcpy8); - else if(!(align & 3)) - vpush_global_sym(&func_old_type, TOK_memcpy4); - else -#endif - /* Use memmove, rather than memcpy, as dest and src may be same: */ - vpush_global_sym(&func_old_type, TOK_memmove); - - vswap(); - /* source */ - vpushv(vtop - 2); - vtop->type.t = VT_PTR; - gaddrof(); - /* type size */ - vpushi(size); - gfunc_call(3); - } else { - vswap(); - vpop(); - } - /* leave source on stack */ - } else if (ft & VT_BITFIELD) { - /* bitfield store handling */ - - /* save lvalue as expression result (example: s.b = s.a = n;) */ - vdup(), vtop[-1] = vtop[-2]; - - bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f; - bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f; - /* remove bit field info to avoid loops */ - vtop[-1].type.t = ft & ~VT_BITFIELD & ((1 << VT_STRUCT_SHIFT) - 1); - - if((ft & VT_BTYPE) == VT_BOOL) { - gen_cast(&vtop[-1].type); - vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED); - } - - /* duplicate destination */ - vdup(); - vtop[-1] = vtop[-2]; - - /* mask and shift source */ - if((ft & VT_BTYPE) != VT_BOOL) { - if((ft & VT_BTYPE) == VT_LLONG) { - vpushll((1ULL << bit_size) - 1ULL); - } else { - vpushi((1 << bit_size) - 1); - } - gen_op('&'); - } - vpushi(bit_pos); - gen_op(TOK_SHL); - /* load destination, mask and or with source */ - vswap(); - if((ft & VT_BTYPE) == VT_LLONG) { - vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos)); - } else { - vpushi(~(((1 << bit_size) - 1) << bit_pos)); - } - gen_op('&'); - gen_op('|'); - /* store result */ - vstore(); - /* ... and discard */ - vpop(); - - } else { - if (!nocode_wanted) { -#ifdef CONFIG_TCC_BCHECK - /* bound check case */ - if (vtop[-1].r & VT_MUSTBOUND) { - vswap(); - gbound(); - vswap(); - } -#endif - rc = RC_INT; - if (is_float(ft)) { - rc = RC_FLOAT; -#ifdef TCC_TARGET_X86_64 - if ((ft & VT_BTYPE) == VT_LDOUBLE) { - rc = RC_ST0; - } else if ((ft & VT_BTYPE) == VT_QFLOAT) { - rc = RC_FRET; - } -#endif - } - r = gv(rc); /* generate value */ - /* if lvalue was saved on stack, must read it */ - if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) { - SValue sv; - t = get_reg(RC_INT); -#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) - sv.type.t = VT_PTR; -#else - sv.type.t = VT_INT; -#endif - sv.r = VT_LOCAL | VT_LVAL; - sv.c.i = vtop[-1].c.i; - load(t, &sv); - vtop[-1].r = t | VT_LVAL; - } - /* two word case handling : store second register at word + 4 (or +8 for x86-64) */ -#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) - if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) { - int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE; -#else - if ((ft & VT_BTYPE) == VT_LLONG) { - int addr_type = VT_INT, load_size = 4, load_type = VT_INT; -#endif - vtop[-1].type.t = load_type; - store(r, vtop - 1); - vswap(); - /* convert to int to increment easily */ - vtop->type.t = addr_type; - gaddrof(); - vpushi(load_size); - gen_op('+'); - vtop->r |= VT_LVAL; - vswap(); - vtop[-1].type.t = load_type; - /* XXX: it works because r2 is spilled last ! */ - store(vtop->r2, vtop - 1); - } else { - store(r, vtop - 1); - } - } - vswap(); - vtop--; /* NOT vpop() because on x86 it would flush the fp stack */ - vtop->r |= delayed_cast; - } -} - -/* post defines POST/PRE add. c is the token ++ or -- */ -ST_FUNC void inc(int post, int c) -{ - test_lvalue(); - vdup(); /* save lvalue */ - if (post) { - if (!nocode_wanted) - gv_dup(); /* duplicate value */ - else - vdup(); /* duplicate value */ - vrotb(3); - vrotb(3); - } - /* add constant */ - vpushi(c - TOK_MID); - gen_op('+'); - vstore(); /* store value */ - if (post) - vpop(); /* if post op, return saved value */ -} - -/* Parse GNUC __attribute__ extension. Currently, the following - extensions are recognized: - - aligned(n) : set data/function alignment. - - packed : force data alignment to 1 - - section(x) : generate data/code in this section. - - unused : currently ignored, but may be used someday. - - regparm(n) : pass function parameters in registers (i386 only) - */ -static void parse_attribute(AttributeDef *ad) -{ - int t, n; - - while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) { - next(); - skip('('); - skip('('); - while (tok != ')') { - if (tok < TOK_IDENT) - expect("attribute name"); - t = tok; - next(); - switch(t) { - case TOK_SECTION1: - case TOK_SECTION2: - skip('('); - if (tok != TOK_STR) - expect("section name"); - ad->section = find_section(tcc_state, (char *)tokc.str.data); - next(); - skip(')'); - break; - case TOK_ALIAS1: - case TOK_ALIAS2: - skip('('); - if (tok != TOK_STR) - expect("alias(\"target\")"); - ad->alias_target = /* save string as token, for later */ - tok_alloc((char*)tokc.str.data, tokc.str.size-1)->tok; - next(); - skip(')'); - break; - case TOK_VISIBILITY1: - case TOK_VISIBILITY2: - skip('('); - if (tok != TOK_STR) - expect("visibility(\"default|hidden|internal|protected\")"); - if (!strcmp (tokc.str.data, "default")) - ad->a.visibility = STV_DEFAULT; - else if (!strcmp (tokc.str.data, "hidden")) - ad->a.visibility = STV_HIDDEN; - else if (!strcmp (tokc.str.data, "internal")) - ad->a.visibility = STV_INTERNAL; - else if (!strcmp (tokc.str.data, "protected")) - ad->a.visibility = STV_PROTECTED; - else - expect("visibility(\"default|hidden|internal|protected\")"); - next(); - skip(')'); - break; - case TOK_ALIGNED1: - case TOK_ALIGNED2: - if (tok == '(') { - next(); - n = expr_const(); - if (n <= 0 || (n & (n - 1)) != 0) - tcc_error("alignment must be a positive power of two"); - skip(')'); - } else { - n = MAX_ALIGN; - } - ad->a.aligned = n; - break; - case TOK_PACKED1: - case TOK_PACKED2: - ad->a.packed = 1; - break; - case TOK_WEAK1: - case TOK_WEAK2: - ad->a.weak = 1; - break; - case TOK_UNUSED1: - case TOK_UNUSED2: - /* currently, no need to handle it because tcc does not - track unused objects */ - break; - case TOK_NORETURN1: - case TOK_NORETURN2: - /* currently, no need to handle it because tcc does not - track unused objects */ - break; - case TOK_CDECL1: - case TOK_CDECL2: - case TOK_CDECL3: - ad->a.func_call = FUNC_CDECL; - break; - case TOK_STDCALL1: - case TOK_STDCALL2: - case TOK_STDCALL3: - ad->a.func_call = FUNC_STDCALL; - break; -#ifdef TCC_TARGET_I386 - case TOK_REGPARM1: - case TOK_REGPARM2: - skip('('); - n = expr_const(); - if (n > 3) - n = 3; - else if (n < 0) - n = 0; - if (n > 0) - ad->a.func_call = FUNC_FASTCALL1 + n - 1; - skip(')'); - break; - case TOK_FASTCALL1: - case TOK_FASTCALL2: - case TOK_FASTCALL3: - ad->a.func_call = FUNC_FASTCALLW; - break; -#endif - case TOK_MODE: - skip('('); - switch(tok) { - case TOK_MODE_DI: - ad->a.mode = VT_LLONG + 1; - break; - case TOK_MODE_HI: - ad->a.mode = VT_SHORT + 1; - break; - case TOK_MODE_SI: - ad->a.mode = VT_INT + 1; - break; - default: - tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL)); - break; - } - next(); - skip(')'); - break; - case TOK_DLLEXPORT: - ad->a.func_export = 1; - break; - case TOK_DLLIMPORT: - ad->a.func_import = 1; - break; - default: - if (tcc_state->warn_unsupported) - tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL)); - /* skip parameters */ - if (tok == '(') { - int parenthesis = 0; - do { - if (tok == '(') - parenthesis++; - else if (tok == ')') - parenthesis--; - next(); - } while (parenthesis && tok != -1); - } - break; - } - if (tok != ',') - break; - next(); - } - skip(')'); - skip(')'); - } -} - -/* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */ -static void struct_decl(CType *type, int u) -{ - int a, v, size, align, maxalign, c, offset, flexible; - int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt; - Sym *s, *ss, *ass, **ps; - AttributeDef ad; - CType type1, btype; - - a = tok; /* save decl type */ - next(); - if (tok != '{') { - v = tok; - next(); - /* struct already defined ? return it */ - if (v < TOK_IDENT) - expect("struct/union/enum name"); - s = struct_find(v); - if (s) { - if (s->type.t != a) - tcc_error("invalid type"); - goto do_decl; - } - } else { - v = anon_sym++; - } - type1.t = a; - type1.ref = NULL; - /* we put an undefined size for struct/union */ - s = sym_push(v | SYM_STRUCT, &type1, 0, -1); - s->r = 0; /* default alignment is zero as gcc */ - /* put struct/union/enum name in type */ - do_decl: - type->t = u; - type->ref = s; - - if (tok == '{') { - next(); - if (s->c != -1) - tcc_error("struct/union/enum already defined"); - /* cannot be empty */ - c = 0; - /* non empty enums are not allowed */ - if (a == TOK_ENUM) { - for(;;) { - v = tok; - if (v < TOK_UIDENT) - expect("identifier"); - ss = sym_find(v); - if (ss && !local_stack) - tcc_error("redefinition of enumerator '%s'", - get_tok_str(v, NULL)); - next(); - if (tok == '=') { - next(); - c = expr_const(); - } - /* enum symbols have static storage */ - ss = sym_push(v, &int_type, VT_CONST, c); - ss->type.t |= VT_STATIC; - if (tok != ',') - break; - next(); - c++; - /* NOTE: we accept a trailing comma */ - if (tok == '}') - break; - } - s->c = type_size(&int_type, &align); - skip('}'); - } else { - maxalign = 1; - ps = &s->next; - prevbt = VT_INT; - bit_pos = 0; - offset = 0; - flexible = 0; - while (tok != '}') { - parse_btype(&btype, &ad); - while (1) { - if (flexible) - tcc_error("flexible array member '%s' not at the end of struct", - get_tok_str(v, NULL)); - bit_size = -1; - v = 0; - type1 = btype; - if (tok != ':') { - type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT); - if (v == 0) { - if ((type1.t & VT_BTYPE) != VT_STRUCT) - expect("identifier"); - else { - int v = btype.ref->v; - if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) { - if (tcc_state->ms_extensions == 0) - expect("identifier"); - } - } - } - if (type_size(&type1, &align) < 0) { - if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY) && c) - flexible = 1; - else - tcc_error("field '%s' has incomplete type", - get_tok_str(v, NULL)); - } - if ((type1.t & VT_BTYPE) == VT_FUNC || - (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE))) - tcc_error("invalid type for '%s'", - get_tok_str(v, NULL)); - } - if (tok == ':') { - next(); - bit_size = expr_const(); - /* XXX: handle v = 0 case for messages */ - if (bit_size < 0) - tcc_error("negative width in bit-field '%s'", - get_tok_str(v, NULL)); - if (v && bit_size == 0) - tcc_error("zero width for bit-field '%s'", - get_tok_str(v, NULL)); - } - size = type_size(&type1, &align); - if (ad.a.aligned) { - if (align < ad.a.aligned) - align = ad.a.aligned; - } else if (ad.a.packed) { - align = 1; - } else if (*tcc_state->pack_stack_ptr) { - if (align > *tcc_state->pack_stack_ptr) - align = *tcc_state->pack_stack_ptr; - } - lbit_pos = 0; - if (bit_size >= 0) { - bt = type1.t & VT_BTYPE; - if (bt != VT_INT && - bt != VT_BYTE && - bt != VT_SHORT && - bt != VT_BOOL && - bt != VT_ENUM && - bt != VT_LLONG) - tcc_error("bitfields must have scalar type"); - bsize = size * 8; - if (bit_size > bsize) { - tcc_error("width of '%s' exceeds its type", - get_tok_str(v, NULL)); - } else if (bit_size == bsize) { - /* no need for bit fields */ - bit_pos = 0; - } else if (bit_size == 0) { - /* XXX: what to do if only padding in a - structure ? */ - /* zero size: means to pad */ - bit_pos = 0; - } else { - /* we do not have enough room ? - did the type change? - is it a union? */ - if ((bit_pos + bit_size) > bsize || - bt != prevbt || a == TOK_UNION) - bit_pos = 0; - lbit_pos = bit_pos; - /* XXX: handle LSB first */ - type1.t |= VT_BITFIELD | - (bit_pos << VT_STRUCT_SHIFT) | - (bit_size << (VT_STRUCT_SHIFT + 6)); - bit_pos += bit_size; - } - prevbt = bt; - } else { - bit_pos = 0; - } - if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) { - /* add new memory data only if starting - bit field */ - if (lbit_pos == 0) { - if (a == TOK_STRUCT) { - c = (c + align - 1) & -align; - offset = c; - if (size > 0) - c += size; - } else { - offset = 0; - if (size > c) - c = size; - } - if (align > maxalign) - maxalign = align; - } -#if 0 - printf("add field %s offset=%d", - get_tok_str(v, NULL), offset); - if (type1.t & VT_BITFIELD) { - printf(" pos=%d size=%d", - (type1.t >> VT_STRUCT_SHIFT) & 0x3f, - (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f); - } - printf("\n"); -#endif - } - if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) { - ass = type1.ref; - while ((ass = ass->next) != NULL) { - ss = sym_push(ass->v, &ass->type, 0, offset + ass->c); - *ps = ss; - ps = &ss->next; - } - } else if (v) { - ss = sym_push(v | SYM_FIELD, &type1, 0, offset); - *ps = ss; - ps = &ss->next; - } - if (tok == ';' || tok == TOK_EOF) - break; - skip(','); - } - skip(';'); - } - skip('}'); - /* store size and alignment */ - s->c = (c + maxalign - 1) & -maxalign; - s->r = maxalign; - } - } -} - -/* return 1 if basic type is a type size (short, long, long long) */ -ST_FUNC int is_btype_size(int bt) -{ - return bt == VT_SHORT || bt == VT_LONG || bt == VT_LLONG; -} - -/* Add type qualifiers to a type. If the type is an array then the qualifiers - are added to the element type, copied because it could be a typedef. */ -static void parse_btype_qualify(CType *type, int qualifiers) -{ - while (type->t & VT_ARRAY) { - type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c); - type = &type->ref->type; - } - type->t |= qualifiers; -} - -/* return 0 if no type declaration. otherwise, return the basic type - and skip it. - */ -static int parse_btype(CType *type, AttributeDef *ad) -{ - int t, u, bt_size, complete, type_found, typespec_found; - Sym *s; - CType type1; - - memset(ad, 0, sizeof(AttributeDef)); - complete = 0; - type_found = 0; - typespec_found = 0; - t = 0; - while(1) { - switch(tok) { - case TOK_EXTENSION: - /* currently, we really ignore extension */ - next(); - continue; - - /* basic types */ - case TOK_CHAR: - u = VT_BYTE; - basic_type: - next(); - basic_type1: - if (complete) - tcc_error("too many basic types"); - t |= u; - bt_size = is_btype_size (u & VT_BTYPE); - if (u == VT_INT || (!bt_size && !(t & VT_TYPEDEF))) - complete = 1; - typespec_found = 1; - break; - case TOK_VOID: - u = VT_VOID; - goto basic_type; - case TOK_SHORT: - u = VT_SHORT; - goto basic_type; - case TOK_INT: - u = VT_INT; - goto basic_type; - case TOK_LONG: - next(); - if ((t & VT_BTYPE) == VT_DOUBLE) { -#ifndef TCC_TARGET_PE - t = (t & ~VT_BTYPE) | VT_LDOUBLE; -#endif - } else if ((t & VT_BTYPE) == VT_LONG) { - t = (t & ~VT_BTYPE) | VT_LLONG; - } else { - u = VT_LONG; - goto basic_type1; - } - break; -#ifdef TCC_TARGET_ARM64 - case TOK_UINT128: - /* GCC's __uint128_t appears in some Linux header files. Make it a - synonym for long double to get the size and alignment right. */ - u = VT_LDOUBLE; - goto basic_type; -#endif - case TOK_BOOL: - u = VT_BOOL; - goto basic_type; - case TOK_FLOAT: - u = VT_FLOAT; - goto basic_type; - case TOK_DOUBLE: - next(); - if ((t & VT_BTYPE) == VT_LONG) { -#ifdef TCC_TARGET_PE - t = (t & ~VT_BTYPE) | VT_DOUBLE; -#else - t = (t & ~VT_BTYPE) | VT_LDOUBLE; -#endif - } else { - u = VT_DOUBLE; - goto basic_type1; - } - break; - case TOK_ENUM: - struct_decl(&type1, VT_ENUM); - basic_type2: - u = type1.t; - type->ref = type1.ref; - goto basic_type1; - case TOK_STRUCT: - case TOK_UNION: - struct_decl(&type1, VT_STRUCT); - goto basic_type2; - - /* type modifiers */ - case TOK_CONST1: - case TOK_CONST2: - case TOK_CONST3: - type->t = t; - parse_btype_qualify(type, VT_CONSTANT); - t = type->t; - next(); - break; - case TOK_VOLATILE1: - case TOK_VOLATILE2: - case TOK_VOLATILE3: - type->t = t; - parse_btype_qualify(type, VT_VOLATILE); - t = type->t; - next(); - break; - case TOK_SIGNED1: - case TOK_SIGNED2: - case TOK_SIGNED3: - if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED)) - tcc_error("signed and unsigned modifier"); - typespec_found = 1; - t |= VT_DEFSIGN; - next(); - break; - case TOK_REGISTER: - case TOK_AUTO: - case TOK_RESTRICT1: - case TOK_RESTRICT2: - case TOK_RESTRICT3: - next(); - break; - case TOK_UNSIGNED: - if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN) - tcc_error("signed and unsigned modifier"); - t |= VT_DEFSIGN | VT_UNSIGNED; - next(); - typespec_found = 1; - break; - - /* storage */ - case TOK_EXTERN: - t |= VT_EXTERN; - next(); - break; - case TOK_STATIC: - t |= VT_STATIC; - next(); - break; - case TOK_TYPEDEF: - t |= VT_TYPEDEF; - next(); - break; - case TOK_INLINE1: - case TOK_INLINE2: - case TOK_INLINE3: - t |= VT_INLINE; - next(); - break; - - /* GNUC attribute */ - case TOK_ATTRIBUTE1: - case TOK_ATTRIBUTE2: - parse_attribute(ad); - if (ad->a.mode) { - u = ad->a.mode -1; - t = (t & ~VT_BTYPE) | u; - } - break; - /* GNUC typeof */ - case TOK_TYPEOF1: - case TOK_TYPEOF2: - case TOK_TYPEOF3: - next(); - parse_expr_type(&type1); - /* remove all storage modifiers except typedef */ - type1.t &= ~(VT_STORAGE&~VT_TYPEDEF); - goto basic_type2; - default: - if (typespec_found) - goto the_end; - s = sym_find(tok); - if (!s || !(s->type.t & VT_TYPEDEF)) - goto the_end; - - type->t = ((s->type.t & ~VT_TYPEDEF) | - (t & ~(VT_CONSTANT | VT_VOLATILE))); - type->ref = s->type.ref; - if (t & (VT_CONSTANT | VT_VOLATILE)) - parse_btype_qualify(type, t & (VT_CONSTANT | VT_VOLATILE)); - t = type->t; - - if (s->r) { - /* get attributes from typedef */ - if (0 == ad->a.aligned) - ad->a.aligned = s->a.aligned; - if (0 == ad->a.func_call) - ad->a.func_call = s->a.func_call; - ad->a.packed |= s->a.packed; - } - next(); - typespec_found = 1; - break; - } - type_found = 1; - } -the_end: - if (tcc_state->char_is_unsigned) { - if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE) - t |= VT_UNSIGNED; - } - - /* long is never used as type */ - if ((t & VT_BTYPE) == VT_LONG) -#if (!defined TCC_TARGET_X86_64 && !defined TCC_TARGET_ARM64) || \ - defined TCC_TARGET_PE - t = (t & ~VT_BTYPE) | VT_INT; -#else - t = (t & ~VT_BTYPE) | VT_LLONG; -#endif - type->t = t; - return type_found; -} - -/* convert a function parameter type (array to pointer and function to - function pointer) */ -static inline void convert_parameter_type(CType *pt) -{ - /* remove const and volatile qualifiers (XXX: const could be used - to indicate a const function parameter */ - pt->t &= ~(VT_CONSTANT | VT_VOLATILE); - /* array must be transformed to pointer according to ANSI C */ - pt->t &= ~VT_ARRAY; - if ((pt->t & VT_BTYPE) == VT_FUNC) { - mk_pointer(pt); - } -} - -ST_FUNC void parse_asm_str(CString *astr) -{ - skip('('); - /* read the string */ - if (tok != TOK_STR) - expect("string constant"); - cstr_new(astr); - while (tok == TOK_STR) { - /* XXX: add \0 handling too ? */ - cstr_cat(astr, tokc.str.data); - next(); - } - cstr_ccat(astr, '\0'); -} - -/* Parse an asm label and return the token */ -static int asm_label_instr(void) -{ - int v; - CString astr; - - next(); - parse_asm_str(&astr); - skip(')'); -#ifdef ASM_DEBUG - printf("asm_alias: \"%s\"\n", (char *)astr.data); -#endif - v = tok_alloc(astr.data, astr.size - 1)->tok; - cstr_free(&astr); - return v; -} - -static void post_type(CType *type, AttributeDef *ad) -{ - int n, l, t1, arg_size, align; - Sym **plast, *s, *first; - AttributeDef ad1; - CType pt; - - if (tok == '(') { - /* function declaration */ - next(); - l = 0; - first = NULL; - plast = &first; - arg_size = 0; - if (tok != ')') { - for(;;) { - /* read param name and compute offset */ - if (l != FUNC_OLD) { - if (!parse_btype(&pt, &ad1)) { - if (l) { - tcc_error("invalid type"); - } else { - l = FUNC_OLD; - goto old_proto; - } - } - l = FUNC_NEW; - if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')') - break; - type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT); - if ((pt.t & VT_BTYPE) == VT_VOID) - tcc_error("parameter declared as void"); - arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE; - } else { - old_proto: - n = tok; - if (n < TOK_UIDENT) - expect("identifier"); - pt.t = VT_INT; - next(); - } - convert_parameter_type(&pt); - s = sym_push(n | SYM_FIELD, &pt, 0, 0); - *plast = s; - plast = &s->next; - if (tok == ')') - break; - skip(','); - if (l == FUNC_NEW && tok == TOK_DOTS) { - l = FUNC_ELLIPSIS; - next(); - break; - } - } - } - /* if no parameters, then old type prototype */ - if (l == 0) - l = FUNC_OLD; - skip(')'); - /* NOTE: const is ignored in returned type as it has a special - meaning in gcc / C++ */ - type->t &= ~VT_CONSTANT; - /* some ancient pre-K&R C allows a function to return an array - and the array brackets to be put after the arguments, such - that "int c()[]" means something like "int[] c()" */ - if (tok == '[') { - next(); - skip(']'); /* only handle simple "[]" */ - type->t |= VT_PTR; - } - /* we push a anonymous symbol which will contain the function prototype */ - ad->a.func_args = arg_size; - s = sym_push(SYM_FIELD, type, 0, l); - s->a = ad->a; - s->next = first; - type->t = VT_FUNC; - type->ref = s; - } else if (tok == '[') { - /* array definition */ - next(); - if (tok == TOK_RESTRICT1) - next(); - n = -1; - t1 = 0; - if (tok != ']') { - if (!local_stack || nocode_wanted) - vpushi(expr_const()); - else gexpr(); - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - n = vtop->c.i; - if (n < 0) - tcc_error("invalid array size"); - } else { - if (!is_integer_btype(vtop->type.t & VT_BTYPE)) - tcc_error("size of variable length array should be an integer"); - t1 = VT_VLA; - } - } - skip(']'); - /* parse next post type */ - post_type(type, ad); - if (type->t == VT_FUNC) - tcc_error("declaration of an array of functions"); - t1 |= type->t & VT_VLA; - - if (t1 & VT_VLA) { - loc -= type_size(&int_type, &align); - loc &= -align; - n = loc; - - vla_runtime_type_size(type, &align); - gen_op('*'); - vset(&int_type, VT_LOCAL|VT_LVAL, n); - vswap(); - vstore(); - } - if (n != -1) - vpop(); - - /* we push an anonymous symbol which will contain the array - element type */ - s = sym_push(SYM_FIELD, type, 0, n); - type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR; - type->ref = s; - } -} - -/* Parse a type declaration (except basic type), and return the type - in 'type'. 'td' is a bitmask indicating which kind of type decl is - expected. 'type' should contain the basic type. 'ad' is the - attribute definition of the basic type. It can be modified by - type_decl(). - */ -static void type_decl(CType *type, AttributeDef *ad, int *v, int td) -{ - Sym *s; - CType type1, *type2; - int qualifiers, storage; - - while (tok == '*') { - qualifiers = 0; - redo: - next(); - switch(tok) { - case TOK_CONST1: - case TOK_CONST2: - case TOK_CONST3: - qualifiers |= VT_CONSTANT; - goto redo; - case TOK_VOLATILE1: - case TOK_VOLATILE2: - case TOK_VOLATILE3: - qualifiers |= VT_VOLATILE; - goto redo; - case TOK_RESTRICT1: - case TOK_RESTRICT2: - case TOK_RESTRICT3: - goto redo; - } - mk_pointer(type); - type->t |= qualifiers; - } - - /* XXX: clarify attribute handling */ - if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) - parse_attribute(ad); - - /* recursive type */ - /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */ - type1.t = 0; /* XXX: same as int */ - if (tok == '(') { - next(); - /* XXX: this is not correct to modify 'ad' at this point, but - the syntax is not clear */ - if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) - parse_attribute(ad); - type_decl(&type1, ad, v, td); - skip(')'); - } else { - /* type identifier */ - if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) { - *v = tok; - next(); - } else { - if (!(td & TYPE_ABSTRACT)) - expect("identifier"); - *v = 0; - } - } - storage = type->t & VT_STORAGE; - type->t &= ~VT_STORAGE; - if (storage & VT_STATIC) { - int saved_nocode_wanted = nocode_wanted; - nocode_wanted = 1; - post_type(type, ad); - nocode_wanted = saved_nocode_wanted; - } else - post_type(type, ad); - type->t |= storage; - if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) - parse_attribute(ad); - - if (!type1.t) - return; - /* append type at the end of type1 */ - type2 = &type1; - for(;;) { - s = type2->ref; - type2 = &s->type; - if (!type2->t) { - *type2 = *type; - break; - } - } - *type = type1; -} - -/* compute the lvalue VT_LVAL_xxx needed to match type t. */ -ST_FUNC int lvalue_type(int t) -{ - int bt, r; - r = VT_LVAL; - bt = t & VT_BTYPE; - if (bt == VT_BYTE || bt == VT_BOOL) - r |= VT_LVAL_BYTE; - else if (bt == VT_SHORT) - r |= VT_LVAL_SHORT; - else - return r; - if (t & VT_UNSIGNED) - r |= VT_LVAL_UNSIGNED; - return r; -} - -/* indirection with full error checking and bound check */ -ST_FUNC void indir(void) -{ - if ((vtop->type.t & VT_BTYPE) != VT_PTR) { - if ((vtop->type.t & VT_BTYPE) == VT_FUNC) - return; - expect("pointer"); - } - if ((vtop->r & VT_LVAL) && !nocode_wanted) - gv(RC_INT); - vtop->type = *pointed_type(&vtop->type); - /* Arrays and functions are never lvalues */ - if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA) - && (vtop->type.t & VT_BTYPE) != VT_FUNC) { - vtop->r |= lvalue_type(vtop->type.t); - /* if bound checking, the referenced pointer must be checked */ -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check) - vtop->r |= VT_MUSTBOUND; -#endif - } -} - -/* pass a parameter to a function and do type checking and casting */ -static void gfunc_param_typed(Sym *func, Sym *arg) -{ - int func_type; - CType type; - - func_type = func->c; - if (func_type == FUNC_OLD || - (func_type == FUNC_ELLIPSIS && arg == NULL)) { - /* default casting : only need to convert float to double */ - if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) { - type.t = VT_DOUBLE; - gen_cast(&type); - } else if (vtop->type.t & VT_BITFIELD) { - type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED); - gen_cast(&type); - } - } else if (arg == NULL) { - tcc_error("too many arguments to function"); - } else { - type = arg->type; - type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */ - gen_assign_cast(&type); - } -} - -/* parse an expression of the form '(type)' or '(expr)' and return its - type */ -static void parse_expr_type(CType *type) -{ - int n; - AttributeDef ad; - - skip('('); - if (parse_btype(type, &ad)) { - type_decl(type, &ad, &n, TYPE_ABSTRACT); - } else { - expr_type(type); - } - skip(')'); -} - -static void parse_type(CType *type) -{ - AttributeDef ad; - int n; - - if (!parse_btype(type, &ad)) { - expect("type"); - } - type_decl(type, &ad, &n, TYPE_ABSTRACT); -} - -static void vpush_tokc(int t) -{ - CType type; - type.t = t; - type.ref = 0; - vsetc(&type, VT_CONST, &tokc); -} - -ST_FUNC void unary(void) -{ - int n, t, align, size, r, sizeof_caller; - CType type; - Sym *s; - AttributeDef ad; - static int in_sizeof = 0; - - sizeof_caller = in_sizeof; - in_sizeof = 0; - /* XXX: GCC 2.95.3 does not generate a table although it should be - better here */ - tok_next: - switch(tok) { - case TOK_EXTENSION: - next(); - goto tok_next; - case TOK_CINT: - case TOK_CCHAR: - case TOK_LCHAR: - vpushi(tokc.i); - next(); - break; - case TOK_CUINT: - vpush_tokc(VT_INT | VT_UNSIGNED); - next(); - break; - case TOK_CLLONG: - vpush_tokc(VT_LLONG); - next(); - break; - case TOK_CULLONG: - vpush_tokc(VT_LLONG | VT_UNSIGNED); - next(); - break; - case TOK_CFLOAT: - vpush_tokc(VT_FLOAT); - next(); - break; - case TOK_CDOUBLE: - vpush_tokc(VT_DOUBLE); - next(); - break; - case TOK_CLDOUBLE: - vpush_tokc(VT_LDOUBLE); - next(); - break; - case TOK___FUNCTION__: - if (!gnu_ext) - goto tok_identifier; - /* fall thru */ - case TOK___FUNC__: - { - void *ptr; - int len; - /* special function name identifier */ - len = strlen(funcname) + 1; - /* generate char[len] type */ - type.t = VT_BYTE; - mk_pointer(&type); - type.t |= VT_ARRAY; - type.ref->c = len; - vpush_ref(&type, data_section, data_section->data_offset, len); - ptr = section_ptr_add(data_section, len); - memcpy(ptr, funcname, len); - next(); - } - break; - case TOK_LSTR: -#ifdef TCC_TARGET_PE - t = VT_SHORT | VT_UNSIGNED; -#else - t = VT_INT; -#endif - goto str_init; - case TOK_STR: - /* string parsing */ - t = VT_BYTE; - str_init: - if (tcc_state->warn_write_strings) - t |= VT_CONSTANT; - type.t = t; - mk_pointer(&type); - type.t |= VT_ARRAY; - memset(&ad, 0, sizeof(AttributeDef)); - decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0); - break; - case '(': - next(); - /* cast ? */ - if (parse_btype(&type, &ad)) { - type_decl(&type, &ad, &n, TYPE_ABSTRACT); - skip(')'); - /* check ISOC99 compound literal */ - if (tok == '{') { - /* data is allocated locally by default */ - if (global_expr) - r = VT_CONST; - else - r = VT_LOCAL; - /* all except arrays are lvalues */ - if (!(type.t & VT_ARRAY)) - r |= lvalue_type(type.t); - memset(&ad, 0, sizeof(AttributeDef)); - decl_initializer_alloc(&type, &ad, r, 1, 0, 0); - } else { - if (sizeof_caller) { - vpush(&type); - return; - } - unary(); - gen_cast(&type); - } - } else if (tok == '{') { - if (const_wanted) - tcc_error("expected constant"); - /* save all registers */ - save_regs(0); - /* statement expression : we do not accept break/continue - inside as GCC does */ - block(NULL, NULL, NULL, NULL, 0, 1); - skip(')'); - } else { - gexpr(); - skip(')'); - } - break; - case '*': - next(); - unary(); - indir(); - break; - case '&': - next(); - unary(); - /* functions names must be treated as function pointers, - except for unary '&' and sizeof. Since we consider that - functions are not lvalues, we only have to handle it - there and in function calls. */ - /* arrays can also be used although they are not lvalues */ - if ((vtop->type.t & VT_BTYPE) != VT_FUNC && - !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL)) - test_lvalue(); - mk_pointer(&vtop->type); - gaddrof(); - break; - case '!': - next(); - unary(); - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - CType boolean; - boolean.t = VT_BOOL; - gen_cast(&boolean); - vtop->c.i = !vtop->c.i; - } else if ((vtop->r & VT_VALMASK) == VT_CMP) - vtop->c.i ^= 1; - else { - save_regs(1); - vseti(VT_JMP, gvtst(1, 0)); - } - break; - case '~': - next(); - unary(); - vpushi(-1); - gen_op('^'); - break; - case '+': - next(); - unary(); - if ((vtop->type.t & VT_BTYPE) == VT_PTR) - tcc_error("pointer not accepted for unary plus"); - /* In order to force cast, we add zero, except for floating point - where we really need an noop (otherwise -0.0 will be transformed - into +0.0). */ - if (!is_float(vtop->type.t)) { - vpushi(0); - gen_op('+'); - } - break; - case TOK_SIZEOF: - case TOK_ALIGNOF1: - case TOK_ALIGNOF2: - t = tok; - next(); - in_sizeof++; - unary_type(&type); // Perform a in_sizeof = 0; - size = type_size(&type, &align); - if (t == TOK_SIZEOF) { - if (!(type.t & VT_VLA)) { - if (size < 0) - tcc_error("sizeof applied to an incomplete type"); - vpushs(size); - } else { - vla_runtime_type_size(&type, &align); - } - } else { - vpushs(align); - } - vtop->type.t |= VT_UNSIGNED; - break; - - case TOK_builtin_types_compatible_p: - { - CType type1, type2; - next(); - skip('('); - parse_type(&type1); - skip(','); - parse_type(&type2); - skip(')'); - type1.t &= ~(VT_CONSTANT | VT_VOLATILE); - type2.t &= ~(VT_CONSTANT | VT_VOLATILE); - vpushi(is_compatible_types(&type1, &type2)); - } - break; - case TOK_builtin_constant_p: - { - int saved_nocode_wanted, res; - next(); - skip('('); - saved_nocode_wanted = nocode_wanted; - nocode_wanted = 1; - gexpr(); - res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; - vpop(); - nocode_wanted = saved_nocode_wanted; - skip(')'); - vpushi(res); - } - break; - case TOK_builtin_frame_address: - case TOK_builtin_return_address: - { - int tok1 = tok; - int level; - CType type; - next(); - skip('('); - if (tok != TOK_CINT) { - tcc_error("%s only takes positive integers", - tok1 == TOK_builtin_return_address ? - "__builtin_return_address" : - "__builtin_frame_address"); - } - level = (uint32_t)tokc.i; - next(); - skip(')'); - type.t = VT_VOID; - mk_pointer(&type); - vset(&type, VT_LOCAL, 0); /* local frame */ - while (level--) { - mk_pointer(&vtop->type); - indir(); /* -> parent frame */ - } - if (tok1 == TOK_builtin_return_address) { - // assume return address is just above frame pointer on stack - vpushi(PTR_SIZE); - gen_op('+'); - mk_pointer(&vtop->type); - indir(); - } - } - break; -#ifdef TCC_TARGET_X86_64 -#ifdef TCC_TARGET_PE - case TOK_builtin_va_start: - { - next(); - skip('('); - expr_eq(); - skip(','); - expr_eq(); - skip(')'); - if ((vtop->r & VT_VALMASK) != VT_LOCAL) - tcc_error("__builtin_va_start expects a local variable"); - vtop->r &= ~(VT_LVAL | VT_REF); - vtop->type = char_pointer_type; - vstore(); - } - break; -#else - case TOK_builtin_va_arg_types: - { - CType type; - next(); - skip('('); - parse_type(&type); - skip(')'); - vpushi(classify_x86_64_va_arg(&type)); - } - break; -#endif -#endif - -#ifdef TCC_TARGET_ARM64 - case TOK___va_start: { - if (nocode_wanted) - tcc_error("statement in global scope"); - next(); - skip('('); - expr_eq(); - skip(','); - expr_eq(); - skip(')'); - //xx check types - gen_va_start(); - vpushi(0); - vtop->type.t = VT_VOID; - break; - } - case TOK___va_arg: { - CType type; - if (nocode_wanted) - tcc_error("statement in global scope"); - next(); - skip('('); - expr_eq(); - skip(','); - parse_type(&type); - skip(')'); - //xx check types - gen_va_arg(&type); - vtop->type = type; - break; - } - case TOK___arm64_clear_cache: { - next(); - skip('('); - expr_eq(); - skip(','); - expr_eq(); - skip(')'); - gen_clear_cache(); - vpushi(0); - vtop->type.t = VT_VOID; - break; - } -#endif - /* pre operations */ - case TOK_INC: - case TOK_DEC: - t = tok; - next(); - unary(); - inc(0, t); - break; - case '-': - next(); - unary(); - t = vtop->type.t & VT_BTYPE; - if (is_float(t)) { - /* In IEEE negate(x) isn't subtract(0,x), but rather - subtract(-0, x). */ - vpush(&vtop->type); - if (t == VT_FLOAT) - vtop->c.f = -0.0f; - else if (t == VT_DOUBLE) - vtop->c.d = -0.0; - else - vtop->c.ld = -0.0; - } else - vpushi(0); - vswap(); - gen_op('-'); - break; - case TOK_LAND: - if (!gnu_ext) - goto tok_identifier; - next(); - /* allow to take the address of a label */ - if (tok < TOK_UIDENT) - expect("label identifier"); - s = label_find(tok); - if (!s) { - s = label_push(&global_label_stack, tok, LABEL_FORWARD); - } else { - if (s->r == LABEL_DECLARED) - s->r = LABEL_FORWARD; - } - if (!s->type.t) { - s->type.t = VT_VOID; - mk_pointer(&s->type); - s->type.t |= VT_STATIC; - } - vpushsym(&s->type, s); - next(); - break; - - // special qnan , snan and infinity values - case TOK___NAN__: - vpush64(VT_DOUBLE, 0x7ff8000000000000ULL); - next(); - break; - case TOK___SNAN__: - vpush64(VT_DOUBLE, 0x7ff0000000000001ULL); - next(); - break; - case TOK___INF__: - vpush64(VT_DOUBLE, 0x7ff0000000000000ULL); - next(); - break; - - default: - tok_identifier: - t = tok; - next(); - if (t < TOK_UIDENT) - expect("identifier"); - s = sym_find(t); - if (!s) { - const char *name = get_tok_str(t, NULL); - if (tok != '(') - tcc_error("'%s' undeclared", name); - /* for simple function calls, we tolerate undeclared - external reference to int() function */ - if (tcc_state->warn_implicit_function_declaration -#ifdef TCC_TARGET_PE - /* people must be warned about using undeclared WINAPI functions - (which usually start with uppercase letter) */ - || (name[0] >= 'A' && name[0] <= 'Z') -#endif - ) - tcc_warning("implicit declaration of function '%s'", name); - s = external_global_sym(t, &func_old_type, 0); - } - if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) == - (VT_STATIC | VT_INLINE | VT_FUNC)) { - /* if referencing an inline function, then we generate a - symbol to it if not already done. It will have the - effect to generate code for it at the end of the - compilation unit. Inline function as always - generated in the text section. */ - if (!s->c) - put_extern_sym(s, text_section, 0, 0); - r = VT_SYM | VT_CONST; - } else { - r = s->r; - } - vset(&s->type, r, s->c); - /* if forward reference, we must point to s */ - if (vtop->r & VT_SYM) { - vtop->sym = s; - vtop->c.i = 0; - } - break; - } - - /* post operations */ - while (1) { - if (tok == TOK_INC || tok == TOK_DEC) { - inc(1, tok); - next(); - } else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) { - int qualifiers; - /* field */ - if (tok == TOK_ARROW) - indir(); - qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE); - test_lvalue(); - gaddrof(); - /* expect pointer on structure */ - if ((vtop->type.t & VT_BTYPE) != VT_STRUCT) - expect("struct or union"); - if (tok == TOK_CDOUBLE) - expect("field name"); - next(); - if (tok == TOK_CINT || tok == TOK_CUINT) - expect("field name"); - s = vtop->type.ref; - /* find field */ - tok |= SYM_FIELD; - while ((s = s->next) != NULL) { - if (s->v == tok) - break; - } - if (!s) - tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, &tokc)); - /* add field offset to pointer */ - vtop->type = char_pointer_type; /* change type to 'char *' */ - vpushi(s->c); - gen_op('+'); - /* change type to field type, and set to lvalue */ - vtop->type = s->type; - vtop->type.t |= qualifiers; - /* an array is never an lvalue */ - if (!(vtop->type.t & VT_ARRAY)) { - vtop->r |= lvalue_type(vtop->type.t); -#ifdef CONFIG_TCC_BCHECK - /* if bound checking, the referenced pointer must be checked */ - if (tcc_state->do_bounds_check) - vtop->r |= VT_MUSTBOUND; -#endif - } - next(); - } else if (tok == '[') { - next(); - gexpr(); - gen_op('+'); - indir(); - skip(']'); - } else if (tok == '(') { - SValue ret; - Sym *sa; - int nb_args, ret_nregs, ret_align, regsize, variadic; - - /* function call */ - if ((vtop->type.t & VT_BTYPE) != VT_FUNC) { - /* pointer test (no array accepted) */ - if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) { - vtop->type = *pointed_type(&vtop->type); - if ((vtop->type.t & VT_BTYPE) != VT_FUNC) - goto error_func; - } else { - error_func: - expect("function pointer"); - } - } else { - vtop->r &= ~VT_LVAL; /* no lvalue */ - } - /* get return type */ - s = vtop->type.ref; - next(); - sa = s->next; /* first parameter */ - nb_args = 0; - ret.r2 = VT_CONST; - /* compute first implicit argument if a structure is returned */ - if ((s->type.t & VT_BTYPE) == VT_STRUCT) { - variadic = (s->c == FUNC_ELLIPSIS); - ret_nregs = gfunc_sret(&s->type, variadic, &ret.type, - &ret_align, ®size); - if (!ret_nregs) { - /* get some space for the returned structure */ - size = type_size(&s->type, &align); -#ifdef TCC_TARGET_ARM64 - /* On arm64, a small struct is return in registers. - It is much easier to write it to memory if we know - that we are allowed to write some extra bytes, so - round the allocated space up to a power of 2: */ - if (size < 16) - while (size & (size - 1)) - size = (size | (size - 1)) + 1; -#endif - loc = (loc - size) & -align; - ret.type = s->type; - ret.r = VT_LOCAL | VT_LVAL; - /* pass it as 'int' to avoid structure arg passing - problems */ - vseti(VT_LOCAL, loc); - ret.c = vtop->c; - nb_args++; - } - } else { - ret_nregs = 1; - ret.type = s->type; - } - - if (ret_nregs) { - /* return in register */ - if (is_float(ret.type.t)) { - ret.r = reg_fret(ret.type.t); -#ifdef TCC_TARGET_X86_64 - if ((ret.type.t & VT_BTYPE) == VT_QFLOAT) - ret.r2 = REG_QRET; -#endif - } else { -#ifndef TCC_TARGET_ARM64 -#ifdef TCC_TARGET_X86_64 - if ((ret.type.t & VT_BTYPE) == VT_QLONG) -#else - if ((ret.type.t & VT_BTYPE) == VT_LLONG) -#endif - ret.r2 = REG_LRET; -#endif - ret.r = REG_IRET; - } - ret.c.i = 0; - } - if (tok != ')') { - for(;;) { - expr_eq(); - gfunc_param_typed(s, sa); - nb_args++; - if (sa) - sa = sa->next; - if (tok == ')') - break; - skip(','); - } - } - if (sa) - tcc_error("too few arguments to function"); - skip(')'); - if (!nocode_wanted) { - gfunc_call(nb_args); - } else { - vtop -= (nb_args + 1); - } - - /* return value */ - for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) { - vsetc(&ret.type, r, &ret.c); - vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */ - } - - /* handle packed struct return */ - if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) { - int addr, offset; - - size = type_size(&s->type, &align); - /* We're writing whole regs often, make sure there's enough - space. Assume register size is power of 2. */ - if (regsize > align) - align = regsize; - loc = (loc - size) & -align; - addr = loc; - offset = 0; - for (;;) { - vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset); - vswap(); - vstore(); - vtop--; - if (--ret_nregs == 0) - break; - offset += regsize; - } - vset(&s->type, VT_LOCAL | VT_LVAL, addr); - } - } else { - break; - } - } -} - -ST_FUNC void expr_prod(void) -{ - int t; - - unary(); - while (tok == '*' || tok == '/' || tok == '%') { - t = tok; - next(); - unary(); - gen_op(t); - } -} - -ST_FUNC void expr_sum(void) -{ - int t; - - expr_prod(); - while (tok == '+' || tok == '-') { - t = tok; - next(); - expr_prod(); - gen_op(t); - } -} - -static void expr_shift(void) -{ - int t; - - expr_sum(); - while (tok == TOK_SHL || tok == TOK_SAR) { - t = tok; - next(); - expr_sum(); - gen_op(t); - } -} - -static void expr_cmp(void) -{ - int t; - - expr_shift(); - while ((tok >= TOK_ULE && tok <= TOK_GT) || - tok == TOK_ULT || tok == TOK_UGE) { - t = tok; - next(); - expr_shift(); - gen_op(t); - } -} - -static void expr_cmpeq(void) -{ - int t; - - expr_cmp(); - while (tok == TOK_EQ || tok == TOK_NE) { - t = tok; - next(); - expr_cmp(); - gen_op(t); - } -} - -static void expr_and(void) -{ - expr_cmpeq(); - while (tok == '&') { - next(); - expr_cmpeq(); - gen_op('&'); - } -} - -static void expr_xor(void) -{ - expr_and(); - while (tok == '^') { - next(); - expr_and(); - gen_op('^'); - } -} - -static void expr_or(void) -{ - expr_xor(); - while (tok == '|') { - next(); - expr_xor(); - gen_op('|'); - } -} - -static void expr_land(void) -{ - expr_or(); - if (tok == TOK_LAND) { - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - CType ctb, cti; - ctb.t = VT_BOOL; - cti.t = VT_INT; - next(); - gen_cast(&ctb); - if (vtop->c.i) { - vpop(); - expr_land(); - gen_cast(&ctb); - } else { - int saved_nocode_wanted = nocode_wanted; - nocode_wanted = 1; - expr_land(); - vpop(); - nocode_wanted = saved_nocode_wanted; - } - gen_cast(&cti); - } else { - int t = 0; - save_regs(1); - for(;;) { - t = gvtst(1, t); - if (tok != TOK_LAND) { - vseti(VT_JMPI, t); - break; - } - next(); - expr_or(); - } - } - } -} - -static void expr_lor(void) -{ - expr_land(); - if (tok == TOK_LOR) { - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - CType ctb, cti; - ctb.t = VT_BOOL; - cti.t = VT_INT; - next(); - gen_cast(&ctb); - if (vtop->c.i) { - int saved_nocode_wanted = nocode_wanted; - nocode_wanted = 1; - expr_lor(); - vpop(); - nocode_wanted = saved_nocode_wanted; - } else { - vpop(); - expr_lor(); - gen_cast(&ctb); - } - gen_cast(&cti); - } else { - int t = 0; - save_regs(1); - for(;;) { - t = gvtst(0, t); - if (tok != TOK_LOR) { - vseti(VT_JMP, t); - break; - } - next(); - expr_land(); - } - } - } -} - -static void expr_cond(void) -{ - int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv; - SValue sv; - CType type, type1, type2; - - expr_lor(); - if (tok == '?') { - next(); - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - int saved_nocode_wanted = nocode_wanted; - CType boolean; - int c; - boolean.t = VT_BOOL; - vdup(); - gen_cast(&boolean); - c = vtop->c.i; - vpop(); - if (c) { - if (tok != ':' || !gnu_ext) { - vpop(); - gexpr(); - } - skip(':'); - nocode_wanted = 1; - expr_cond(); - vpop(); - nocode_wanted = saved_nocode_wanted; - } else { - vpop(); - if (tok != ':' || !gnu_ext) { - nocode_wanted = 1; - gexpr(); - vpop(); - nocode_wanted = saved_nocode_wanted; - } - skip(':'); - expr_cond(); - } - } - else { - if (vtop != vstack) { - /* needed to avoid having different registers saved in - each branch */ - if (is_float(vtop->type.t)) { - rc = RC_FLOAT; -#ifdef TCC_TARGET_X86_64 - if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { - rc = RC_ST0; - } -#endif - } - else - rc = RC_INT; - gv(rc); - save_regs(1); - } - if (tok == ':' && gnu_ext) { - gv_dup(); - tt = gvtst(1, 0); - } else { - tt = gvtst(1, 0); - gexpr(); - } - type1 = vtop->type; - sv = *vtop; /* save value to handle it later */ - vtop--; /* no vpop so that FP stack is not flushed */ - skip(':'); - u = gjmp(0); - gsym(tt); - expr_cond(); - type2 = vtop->type; - - t1 = type1.t; - bt1 = t1 & VT_BTYPE; - t2 = type2.t; - bt2 = t2 & VT_BTYPE; - /* cast operands to correct type according to ISOC rules */ - if (is_float(bt1) || is_float(bt2)) { - if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) { - type.t = VT_LDOUBLE; - } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) { - type.t = VT_DOUBLE; - } else { - type.t = VT_FLOAT; - } - } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) { - /* cast to biggest op */ - type.t = VT_LLONG; - /* convert to unsigned if it does not fit in a long long */ - if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) || - (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED)) - type.t |= VT_UNSIGNED; - } else if (bt1 == VT_PTR || bt2 == VT_PTR) { - /* If one is a null ptr constant the result type - is the other. */ - if (is_null_pointer (vtop)) - type = type1; - else if (is_null_pointer (&sv)) - type = type2; - /* XXX: test pointer compatibility, C99 has more elaborate - rules here. */ - else - type = type1; - } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) { - /* XXX: test function pointer compatibility */ - type = bt1 == VT_FUNC ? type1 : type2; - } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) { - /* XXX: test structure compatibility */ - type = bt1 == VT_STRUCT ? type1 : type2; - } else if (bt1 == VT_VOID || bt2 == VT_VOID) { - /* NOTE: as an extension, we accept void on only one side */ - type.t = VT_VOID; - } else { - /* integer operations */ - type.t = VT_INT; - /* convert to unsigned if it does not fit in an integer */ - if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) || - (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED)) - type.t |= VT_UNSIGNED; - } - /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so - that `(expr ? a : b).mem` does not error with "lvalue expected" */ - islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE); - - /* now we convert second operand */ - gen_cast(&type); - if (islv) { - mk_pointer(&vtop->type); - gaddrof(); - } - else if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) - gaddrof(); - rc = RC_INT; - if (is_float(type.t)) { - rc = RC_FLOAT; -#ifdef TCC_TARGET_X86_64 - if ((type.t & VT_BTYPE) == VT_LDOUBLE) { - rc = RC_ST0; - } -#endif - } else if ((type.t & VT_BTYPE) == VT_LLONG) { - /* for long longs, we use fixed registers to avoid having - to handle a complicated move */ - rc = RC_IRET; - } - - r2 = gv(rc); - /* this is horrible, but we must also convert first - operand */ - tt = gjmp(0); - gsym(u); - /* put again first value and cast it */ - *vtop = sv; - gen_cast(&type); - if (islv) { - mk_pointer(&vtop->type); - gaddrof(); - } - else if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) - gaddrof(); - r1 = gv(rc); - move_reg(r2, r1, type.t); - vtop->r = r2; - gsym(tt); - if (islv) - indir(); - } - } -} - -static void expr_eq(void) -{ - int t; - - expr_cond(); - if (tok == '=' || - (tok >= TOK_A_MOD && tok <= TOK_A_DIV) || - tok == TOK_A_XOR || tok == TOK_A_OR || - tok == TOK_A_SHL || tok == TOK_A_SAR) { - test_lvalue(); - t = tok; - next(); - if (t == '=') { - expr_eq(); - } else { - vdup(); - expr_eq(); - gen_op(t & 0x7f); - } - vstore(); - } -} - -ST_FUNC void gexpr(void) -{ - while (1) { - expr_eq(); - if (tok != ',') - break; - vpop(); - next(); - } -} - -/* parse an expression and return its type without any side effect. */ -static void expr_type(CType *type) -{ - int saved_nocode_wanted; - - saved_nocode_wanted = nocode_wanted; - nocode_wanted = 1; - gexpr(); - *type = vtop->type; - vpop(); - nocode_wanted = saved_nocode_wanted; -} - -/* parse a unary expression and return its type without any side - effect. */ -static void unary_type(CType *type) -{ - int a; - - a = nocode_wanted; - nocode_wanted = 1; - unary(); - *type = vtop->type; - vpop(); - nocode_wanted = a; -} - -/* parse a constant expression and return value in vtop. */ -static void expr_const1(void) -{ - int a; - a = const_wanted; - const_wanted = 1; - expr_cond(); - const_wanted = a; -} - -/* parse an integer constant and return its value. */ -ST_FUNC int expr_const(void) -{ - int c; - expr_const1(); - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) - expect("constant expression"); - c = vtop->c.i; - vpop(); - return c; -} - -/* return the label token if current token is a label, otherwise - return zero */ -static int is_label(void) -{ - int last_tok; - - /* fast test first */ - if (tok < TOK_UIDENT) - return 0; - /* no need to save tokc because tok is an identifier */ - last_tok = tok; - next(); - if (tok == ':') { - next(); - return last_tok; - } else { - unget_tok(last_tok); - return 0; - } -} - -static void label_or_decl(int l) -{ - int last_tok; - - /* fast test first */ - if (tok >= TOK_UIDENT) - { - /* no need to save tokc because tok is an identifier */ - last_tok = tok; - next(); - if (tok == ':') { - unget_tok(last_tok); - return; - } - unget_tok(last_tok); - } - decl(l); -} - -static void block(int *bsym, int *csym, int *case_sym, int *def_sym, - int case_reg, int is_expr) -{ - int a, b, c, d; - Sym *s, *frame_bottom; - - /* generate line number info */ - if (tcc_state->do_debug && - (last_line_num != file->line_num || last_ind != ind)) { - put_stabn(N_SLINE, 0, file->line_num, ind - func_ind); - last_ind = ind; - last_line_num = file->line_num; - } - - if (is_expr) { - /* default return value is (void) */ - vpushi(0); - vtop->type.t = VT_VOID; - } - - if (tok == TOK_IF) { - /* if test */ - next(); - skip('('); - gexpr(); - skip(')'); - a = gvtst(1, 0); - block(bsym, csym, case_sym, def_sym, case_reg, 0); - c = tok; - if (c == TOK_ELSE) { - next(); - d = gjmp(0); - gsym(a); - block(bsym, csym, case_sym, def_sym, case_reg, 0); - gsym(d); /* patch else jmp */ - } else - gsym(a); - } else if (tok == TOK_WHILE) { - next(); - d = ind; - vla_sp_restore(); - skip('('); - gexpr(); - skip(')'); - a = gvtst(1, 0); - b = 0; - block(&a, &b, case_sym, def_sym, case_reg, 0); - gjmp_addr(d); - gsym(a); - gsym_addr(b, d); - } else if (tok == '{') { - Sym *llabel; - int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope; - - next(); - /* record local declaration stack position */ - s = local_stack; - frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0); - frame_bottom->next = scope_stack_bottom; - scope_stack_bottom = frame_bottom; - llabel = local_label_stack; - - /* handle local labels declarations */ - if (tok == TOK_LABEL) { - next(); - for(;;) { - if (tok < TOK_UIDENT) - expect("label identifier"); - label_push(&local_label_stack, tok, LABEL_DECLARED); - next(); - if (tok == ',') { - next(); - } else { - skip(';'); - break; - } - } - } - while (tok != '}') { - label_or_decl(VT_LOCAL); - if (tok != '}') { - if (is_expr) - vpop(); - block(bsym, csym, case_sym, def_sym, case_reg, is_expr); - } - } - /* pop locally defined labels */ - label_pop(&local_label_stack, llabel); - if(is_expr) { - /* XXX: this solution makes only valgrind happy... - triggered by gcc.c-torture/execute/20000917-1.c */ - Sym *p; - switch(vtop->type.t & VT_BTYPE) { - /* case VT_PTR: */ - /* this breaks a compilation of the linux kernel v2.4.26 */ - /* pmd_t *new = ({ __asm__ __volatile__("ud2\n") ; ((pmd_t *)1); }); */ - /* Look a commit a80acab: Display error on statement expressions with complex return type */ - /* A pointer is not a complex return type */ - case VT_STRUCT: - case VT_ENUM: - case VT_FUNC: - for(p=vtop->type.ref;p;p=p->prev) - if(p->prev==s) - tcc_error("unsupported expression type"); - } - } - /* pop locally defined symbols */ - scope_stack_bottom = scope_stack_bottom->next; - sym_pop(&local_stack, s); - - /* Pop VLA frames and restore stack pointer if required */ - if (vlas_in_scope > saved_vlas_in_scope) { - vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc; - vla_sp_restore(); - } - vlas_in_scope = saved_vlas_in_scope; - - next(); - } else if (tok == TOK_RETURN) { - next(); - if (tok != ';') { - gexpr(); - gen_assign_cast(&func_vt); -#ifdef TCC_TARGET_ARM64 - // Perhaps it would be better to use this for all backends: - greturn(); -#else - if ((func_vt.t & VT_BTYPE) == VT_STRUCT) { - CType type, ret_type; - int ret_align, ret_nregs, regsize; - ret_nregs = gfunc_sret(&func_vt, func_var, &ret_type, - &ret_align, ®size); - if (0 == ret_nregs) { - /* if returning structure, must copy it to implicit - first pointer arg location */ - type = func_vt; - mk_pointer(&type); - vset(&type, VT_LOCAL | VT_LVAL, func_vc); - indir(); - vswap(); - /* copy structure value to pointer */ - vstore(); - } else { - /* returning structure packed into registers */ - int r, size, addr, align; - size = type_size(&func_vt,&align); - if ((vtop->r != (VT_LOCAL | VT_LVAL) || - (vtop->c.i & (ret_align-1))) - && (align & (ret_align-1))) { - loc = (loc - size) & -ret_align; - addr = loc; - type = func_vt; - vset(&type, VT_LOCAL | VT_LVAL, addr); - vswap(); - vstore(); - vpop(); - vset(&ret_type, VT_LOCAL | VT_LVAL, addr); - } - vtop->type = ret_type; - if (is_float(ret_type.t)) - r = rc_fret(ret_type.t); - else - r = RC_IRET; - - for (;;) { - gv(r); - if (--ret_nregs == 0) - break; - /* We assume that when a structure is returned in multiple - registers, their classes are consecutive values of the - suite s(n) = 2^n */ - r <<= 1; - vtop->c.i += regsize; - vtop->r = VT_LOCAL | VT_LVAL; - } - } - } else if (is_float(func_vt.t)) { - gv(rc_fret(func_vt.t)); - } else { - gv(RC_IRET); - } -#endif - vtop--; /* NOT vpop() because on x86 it would flush the fp stack */ - } - skip(';'); - rsym = gjmp(rsym); /* jmp */ - } else if (tok == TOK_BREAK) { - /* compute jump */ - if (!bsym) - tcc_error("cannot break"); - *bsym = gjmp(*bsym); - next(); - skip(';'); - } else if (tok == TOK_CONTINUE) { - /* compute jump */ - if (!csym) - tcc_error("cannot continue"); - vla_sp_restore_root(); - *csym = gjmp(*csym); - next(); - skip(';'); - } else if (tok == TOK_FOR) { - int e; - next(); - skip('('); - s = local_stack; - frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0); - frame_bottom->next = scope_stack_bottom; - scope_stack_bottom = frame_bottom; - if (tok != ';') { - /* c99 for-loop init decl? */ - if (!decl0(VT_LOCAL, 1)) { - /* no, regular for-loop init expr */ - gexpr(); - vpop(); - } - } - skip(';'); - d = ind; - c = ind; - vla_sp_restore(); - a = 0; - b = 0; - if (tok != ';') { - gexpr(); - a = gvtst(1, 0); - } - skip(';'); - if (tok != ')') { - e = gjmp(0); - c = ind; - vla_sp_restore(); - gexpr(); - vpop(); - gjmp_addr(d); - gsym(e); - } - skip(')'); - block(&a, &b, case_sym, def_sym, case_reg, 0); - gjmp_addr(c); - gsym(a); - gsym_addr(b, c); - scope_stack_bottom = scope_stack_bottom->next; - sym_pop(&local_stack, s); - } else - if (tok == TOK_DO) { - next(); - a = 0; - b = 0; - d = ind; - vla_sp_restore(); - block(&a, &b, case_sym, def_sym, case_reg, 0); - skip(TOK_WHILE); - skip('('); - gsym(b); - gexpr(); - c = gvtst(0, 0); - gsym_addr(c, d); - skip(')'); - gsym(a); - skip(';'); - } else - if (tok == TOK_SWITCH) { - next(); - skip('('); - gexpr(); - /* XXX: other types than integer */ - case_reg = gv(RC_INT); - vpop(); - skip(')'); - a = 0; - b = gjmp(0); /* jump to first case */ - c = 0; - block(&a, csym, &b, &c, case_reg, 0); - /* if no default, jmp after switch */ - if (c == 0) - c = ind; - /* default label */ - gsym_addr(b, c); - /* break label */ - gsym(a); - } else - if (tok == TOK_CASE) { - int v1, v2; - if (!case_sym) - expect("switch"); - next(); - v1 = expr_const(); - v2 = v1; - if (gnu_ext && tok == TOK_DOTS) { - next(); - v2 = expr_const(); - if (v2 < v1) - tcc_warning("empty case range"); - } - /* since a case is like a label, we must skip it with a jmp */ - b = gjmp(0); - gsym(*case_sym); - vseti(case_reg, 0); - vdup(); - vpushi(v1); - if (v1 == v2) { - gen_op(TOK_EQ); - *case_sym = gtst(1, 0); - } else { - gen_op(TOK_GE); - *case_sym = gtst(1, 0); - vseti(case_reg, 0); - vpushi(v2); - gen_op(TOK_LE); - *case_sym = gtst(1, *case_sym); - } - case_reg = gv(RC_INT); - vpop(); - gsym(b); - skip(':'); - is_expr = 0; - goto block_after_label; - } else - if (tok == TOK_DEFAULT) { - next(); - skip(':'); - if (!def_sym) - expect("switch"); - if (*def_sym) - tcc_error("too many 'default'"); - *def_sym = ind; - is_expr = 0; - goto block_after_label; - } else - if (tok == TOK_GOTO) { - next(); - if (tok == '*' && gnu_ext) { - /* computed goto */ - next(); - gexpr(); - if ((vtop->type.t & VT_BTYPE) != VT_PTR) - expect("pointer"); - ggoto(); - } else if (tok >= TOK_UIDENT) { - s = label_find(tok); - /* put forward definition if needed */ - if (!s) { - s = label_push(&global_label_stack, tok, LABEL_FORWARD); - } else { - if (s->r == LABEL_DECLARED) - s->r = LABEL_FORWARD; - } - vla_sp_restore_root(); - if (s->r & LABEL_FORWARD) - s->jnext = gjmp(s->jnext); - else - gjmp_addr(s->jnext); - next(); - } else { - expect("label identifier"); - } - skip(';'); - } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) { - asm_instr(); - } else { - b = is_label(); - if (b) { - /* label case */ - s = label_find(b); - if (s) { - if (s->r == LABEL_DEFINED) - tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL)); - gsym(s->jnext); - s->r = LABEL_DEFINED; - } else { - s = label_push(&global_label_stack, b, LABEL_DEFINED); - } - s->jnext = ind; - vla_sp_restore(); - /* we accept this, but it is a mistake */ - block_after_label: - if (tok == '}') { - tcc_warning("deprecated use of label at end of compound statement"); - } else { - if (is_expr) - vpop(); - block(bsym, csym, case_sym, def_sym, case_reg, is_expr); - } - } else { - /* expression case */ - if (tok != ';') { - if (is_expr) { - vpop(); - gexpr(); - } else { - gexpr(); - vpop(); - } - } - skip(';'); - } - } -} - -/* t is the array or struct type. c is the array or struct - address. cur_index/cur_field is the pointer to the current - value. 'size_only' is true if only size info is needed (only used - in arrays) */ -static void decl_designator(CType *type, Section *sec, unsigned long c, - int *cur_index, Sym **cur_field, - int size_only) -{ - Sym *s, *f; - int notfirst, index, index_last, align, l, nb_elems, elem_size; - CType type1; - - notfirst = 0; - elem_size = 0; - nb_elems = 1; - if (gnu_ext && (l = is_label()) != 0) - goto struct_field; - while (tok == '[' || tok == '.') { - if (tok == '[') { - if (!(type->t & VT_ARRAY)) - expect("array type"); - s = type->ref; - next(); - index = expr_const(); - if (index < 0 || (s->c >= 0 && index >= s->c)) - expect("invalid index"); - if (tok == TOK_DOTS && gnu_ext) { - next(); - index_last = expr_const(); - if (index_last < 0 || - (s->c >= 0 && index_last >= s->c) || - index_last < index) - expect("invalid index"); - } else { - index_last = index; - } - skip(']'); - if (!notfirst) - *cur_index = index_last; - type = pointed_type(type); - elem_size = type_size(type, &align); - c += index * elem_size; - /* NOTE: we only support ranges for last designator */ - nb_elems = index_last - index + 1; - if (nb_elems != 1) { - notfirst = 1; - break; - } - } else { - next(); - l = tok; - next(); - struct_field: - if ((type->t & VT_BTYPE) != VT_STRUCT) - expect("struct/union type"); - s = type->ref; - l |= SYM_FIELD; - f = s->next; - while (f) { - if (f->v == l) - break; - f = f->next; - } - if (!f) - expect("field"); - if (!notfirst) - *cur_field = f; - /* XXX: fix this mess by using explicit storage field */ - type1 = f->type; - type1.t |= (type->t & ~VT_TYPE); - type = &type1; - c += f->c; - } - notfirst = 1; - } - if (notfirst) { - if (tok == '=') { - next(); - } else { - if (!gnu_ext) - expect("="); - } - } else { - if (type->t & VT_ARRAY) { - index = *cur_index; - type = pointed_type(type); - c += index * type_size(type, &align); - } else { - f = *cur_field; - if (!f) - tcc_error("too many field init"); - /* XXX: fix this mess by using explicit storage field */ - type1 = f->type; - type1.t |= (type->t & ~VT_TYPE); - type = &type1; - c += f->c; - } - } - decl_initializer(type, sec, c, 0, size_only); - - /* XXX: make it more general */ - if (!size_only && nb_elems > 1) { - unsigned long c_end; - uint8_t *src, *dst; - int i; - - if (!sec) - tcc_error("range init not supported yet for dynamic storage"); - c_end = c + nb_elems * elem_size; - if (c_end > sec->data_allocated) - section_realloc(sec, c_end); - src = sec->data + c; - dst = src; - for(i = 1; i < nb_elems; i++) { - dst += elem_size; - memcpy(dst, src, elem_size); - } - } -} - -#define EXPR_VAL 0 -#define EXPR_CONST 1 -#define EXPR_ANY 2 - -/* store a value or an expression directly in global data or in local array */ -static void init_putv(CType *type, Section *sec, unsigned long c, - int v, int expr_type) -{ - int saved_global_expr, bt, bit_pos, bit_size; - void *ptr; - unsigned long long bit_mask; - CType dtype; - - switch(expr_type) { - case EXPR_VAL: - vpushi(v); - break; - case EXPR_CONST: - /* compound literals must be allocated globally in this case */ - saved_global_expr = global_expr; - global_expr = 1; - expr_const1(); - global_expr = saved_global_expr; - /* NOTE: symbols are accepted */ - if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST) - tcc_error("initializer element is not constant"); - break; - case EXPR_ANY: - expr_eq(); - break; - } - - dtype = *type; - dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */ - - if (sec) { - /* XXX: not portable */ - /* XXX: generate error if incorrect relocation */ - gen_assign_cast(&dtype); - bt = type->t & VT_BTYPE; - /* we'll write at most 16 bytes */ - if (c + 16 > sec->data_allocated) { - section_realloc(sec, c + 16); - } - ptr = sec->data + c; - /* XXX: make code faster ? */ - if (!(type->t & VT_BITFIELD)) { - bit_pos = 0; - bit_size = 32; - bit_mask = -1LL; - } else { - bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f; - bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f; - bit_mask = (1LL << bit_size) - 1; - } - if ((vtop->r & VT_SYM) && - (bt == VT_BYTE || - bt == VT_SHORT || - bt == VT_DOUBLE || - bt == VT_LDOUBLE || - bt == VT_LLONG || - (bt == VT_INT && bit_size != 32))) - tcc_error("initializer element is not computable at load time"); - switch(bt) { - /* XXX: when cross-compiling we assume that each type has the - same representation on host and target, which is likely to - be wrong in the case of long double */ - case VT_BOOL: - vtop->c.i = (vtop->c.i != 0); - case VT_BYTE: - *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos; - break; - case VT_SHORT: - *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos; - break; - case VT_DOUBLE: - *(double *)ptr = vtop->c.d; - break; - case VT_LDOUBLE: - *(long double *)ptr = vtop->c.ld; - break; - case VT_LLONG: - *(long long *)ptr |= (vtop->c.i & bit_mask) << bit_pos; - break; - case VT_PTR: { - addr_t val = (vtop->c.i & bit_mask) << bit_pos; -#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) - if (vtop->r & VT_SYM) - greloca(sec, vtop->sym, c, R_DATA_PTR, val); - else - *(addr_t *)ptr |= val; -#else - if (vtop->r & VT_SYM) - greloc(sec, vtop->sym, c, R_DATA_PTR); - *(addr_t *)ptr |= val; -#endif - break; - } - default: { - int val = (vtop->c.i & bit_mask) << bit_pos; -#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) - if (vtop->r & VT_SYM) - greloca(sec, vtop->sym, c, R_DATA_PTR, val); - else - *(int *)ptr |= val; -#else - if (vtop->r & VT_SYM) - greloc(sec, vtop->sym, c, R_DATA_PTR); - *(int *)ptr |= val; -#endif - break; - } - } - vtop--; - } else { - vset(&dtype, VT_LOCAL|VT_LVAL, c); - vswap(); - vstore(); - vpop(); - } -} - -/* put zeros for variable based init */ -static void init_putz(CType *t, Section *sec, unsigned long c, int size) -{ - if (sec) { - /* nothing to do because globals are already set to zero */ - } else { - vpush_global_sym(&func_old_type, TOK_memset); - vseti(VT_LOCAL, c); -#ifdef TCC_TARGET_ARM - vpushs(size); - vpushi(0); -#else - vpushi(0); - vpushs(size); -#endif - gfunc_call(3); - } -} - -/* 't' contains the type and storage info. 'c' is the offset of the - object in section 'sec'. If 'sec' is NULL, it means stack based - allocation. 'first' is true if array '{' must be read (multi - dimension implicit array init handling). 'size_only' is true if - size only evaluation is wanted (only for arrays). */ -static void decl_initializer(CType *type, Section *sec, unsigned long c, - int first, int size_only) -{ - int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i; - int size1, align1, expr_type; - Sym *s, *f; - CType *t1; - - if (type->t & VT_VLA) { - int a; - - /* save current stack pointer */ - if (vlas_in_scope == 0) { - if (vla_sp_root_loc == -1) - vla_sp_root_loc = (loc -= PTR_SIZE); - gen_vla_sp_save(vla_sp_root_loc); - } - - vla_runtime_type_size(type, &a); - gen_vla_alloc(type, a); - gen_vla_sp_save(c); - vla_sp_loc = c; - vlas_in_scope++; - } else if (type->t & VT_ARRAY) { - s = type->ref; - n = s->c; - array_length = 0; - t1 = pointed_type(type); - size1 = type_size(t1, &align1); - - no_oblock = 1; - if ((first && tok != TOK_LSTR && tok != TOK_STR) || - tok == '{') { - if (tok != '{') - tcc_error("character array initializer must be a literal," - " optionally enclosed in braces"); - skip('{'); - no_oblock = 0; - } - - /* only parse strings here if correct type (otherwise: handle - them as ((w)char *) expressions */ - if ((tok == TOK_LSTR && -#ifdef TCC_TARGET_PE - (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED) -#else - (t1->t & VT_BTYPE) == VT_INT -#endif - ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) { - while (tok == TOK_STR || tok == TOK_LSTR) { - int cstr_len, ch; - - /* compute maximum number of chars wanted */ - if (tok == TOK_STR) - cstr_len = tokc.str.size; - else - cstr_len = tokc.str.size / sizeof(nwchar_t); - cstr_len--; - nb = cstr_len; - if (n >= 0 && nb > (n - array_length)) - nb = n - array_length; - if (!size_only) { - if (cstr_len > nb) - tcc_warning("initializer-string for array is too long"); - /* in order to go faster for common case (char - string in global variable, we handle it - specifically */ - if (sec && tok == TOK_STR && size1 == 1) { - memcpy(sec->data + c + array_length, tokc.str.data, nb); - } else { - for(i=0;i= 0 && index >= n) - tcc_error("index too large"); - /* must put zero in holes (note that doing it that way - ensures that it even works with designators) */ - if (!size_only && array_length < index) { - init_putz(t1, sec, c + array_length * size1, - (index - array_length) * size1); - } - index++; - if (index > array_length) - array_length = index; - /* special test for multi dimensional arrays (may not - be strictly correct if designators are used at the - same time) */ - if (index >= n && no_oblock) - break; - if (tok == '}') - break; - skip(','); - } - } - if (!no_oblock) - skip('}'); - /* put zeros at the end */ - if (!size_only && n >= 0 && array_length < n) { - init_putz(t1, sec, c + array_length * size1, - (n - array_length) * size1); - } - /* patch type size if needed */ - if (n < 0) - s->c = array_length; - } else if ((type->t & VT_BTYPE) == VT_STRUCT && - (sec || !first || tok == '{')) { - - /* NOTE: the previous test is a specific case for automatic - struct/union init */ - /* XXX: union needs only one init */ - - int par_count = 0; - if (tok == '(') { - AttributeDef ad1; - CType type1; - next(); - if (tcc_state->old_struct_init_code) { - /* an old version of struct initialization. - It have a problems. But with a new version - linux 2.4.26 can't load ramdisk. - */ - while (tok == '(') { - par_count++; - next(); - } - if (!parse_btype(&type1, &ad1)) - expect("cast"); - type_decl(&type1, &ad1, &n, TYPE_ABSTRACT); - #if 0 - if (!is_assignable_types(type, &type1)) - tcc_error("invalid type for cast"); - #endif - skip(')'); - } - else - { - if (tok != '(') { - if (!parse_btype(&type1, &ad1)) - expect("cast"); - type_decl(&type1, &ad1, &n, TYPE_ABSTRACT); - #if 0 - if (!is_assignable_types(type, &type1)) - tcc_error("invalid type for cast"); - #endif - skip(')'); - } else - unget_tok(tok); - } - } - - no_oblock = 1; - if (first || tok == '{') { - skip('{'); - no_oblock = 0; - } - s = type->ref; - f = s->next; - array_length = 0; - index = 0; - n = s->c; - while (tok != '}') { - decl_designator(type, sec, c, NULL, &f, size_only); - index = f->c; - if (!size_only && array_length < index) { - init_putz(type, sec, c + array_length, - index - array_length); - } - index = index + type_size(&f->type, &align1); - if (index > array_length) - array_length = index; - - /* gr: skip fields from same union - ugly. */ - while (f->next) { - int align = 0; - int f_size = type_size(&f->type, &align); - int f_type = (f->type.t & VT_BTYPE); - - ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t); - /* test for same offset */ - if (f->next->c != f->c) - break; - if ((f_type == VT_STRUCT) && (f_size == 0)) { - /* - Lets assume a structure of size 0 can't be a member of the union. - This allow to compile the following code from a linux kernel v2.4.26 - typedef struct { } rwlock_t; - struct fs_struct { - int count; - rwlock_t lock; - int umask; - }; - struct fs_struct init_fs = { { (1) }, (rwlock_t) {}, 0022, }; - tcc-0.9.23 can succesfully compile this version of the kernel. - gcc don't have problems with this code too. - */ - break; - } - /* if yes, test for bitfield shift */ - if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) { - int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f; - int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f; - //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2); - if (bit_pos_1 != bit_pos_2) - break; - } - f = f->next; - } - - f = f->next; - if (no_oblock && f == NULL) - break; - if (tok == '}') - break; - skip(','); - } - /* put zeros at the end */ - if (!size_only && array_length < n) { - init_putz(type, sec, c + array_length, - n - array_length); - } - if (!no_oblock) - skip('}'); - while (par_count) { - skip(')'); - par_count--; - } - } else if (tok == '{') { - next(); - decl_initializer(type, sec, c, first, size_only); - skip('}'); - } else if (size_only) { - /* just skip expression */ - parlevel = parlevel1 = 0; - while ((parlevel > 0 || parlevel1 > 0 || - (tok != '}' && tok != ',')) && tok != -1) { - if (tok == '(') - parlevel++; - else if (tok == ')') { - if (parlevel == 0 && parlevel1 == 0) - break; - parlevel--; - } - else if (tok == '{') - parlevel1++; - else if (tok == '}') { - if (parlevel == 0 && parlevel1 == 0) - break; - parlevel1--; - } - next(); - } - } else { - /* currently, we always use constant expression for globals - (may change for scripting case) */ - expr_type = EXPR_CONST; - if (!sec) - expr_type = EXPR_ANY; - init_putv(type, sec, c, 0, expr_type); - } -} - -/* parse an initializer for type 't' if 'has_init' is non zero, and - allocate space in local or global data space ('r' is either - VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated - variable 'v' of scope 'scope' is declared before initializers - are parsed. If 'v' is zero, then a reference to the new object - is put in the value stack. If 'has_init' is 2, a special parsing - is done to handle string constants. */ -static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, - int has_init, int v, int scope) -{ - int size, align, addr, data_offset; - int level; - ParseState saved_parse_state = {0}; - TokenString init_str; - Section *sec; - Sym *flexible_array; - - flexible_array = NULL; - if ((type->t & VT_BTYPE) == VT_STRUCT) { - Sym *field = type->ref->next; - if (field) { - while (field->next) - field = field->next; - if (field->type.t & VT_ARRAY && field->type.ref->c < 0) - flexible_array = field; - } - } - - size = type_size(type, &align); - /* If unknown size, we must evaluate it before - evaluating initializers because - initializers can generate global data too - (e.g. string pointers or ISOC99 compound - literals). It also simplifies local - initializers handling */ - tok_str_new(&init_str); - if (size < 0 || (flexible_array && has_init)) { - if (!has_init) - tcc_error("unknown type size"); - /* get all init string */ - if (has_init == 2) { - /* only get strings */ - while (tok == TOK_STR || tok == TOK_LSTR) { - tok_str_add_tok(&init_str); - next(); - } - } else { - level = 0; - while (level > 0 || (tok != ',' && tok != ';')) { - if (tok < 0) - tcc_error("unexpected end of file in initializer"); - tok_str_add_tok(&init_str); - if (tok == '{') - level++; - else if (tok == '}') { - level--; - if (level <= 0) { - next(); - break; - } - } - next(); - } - } - tok_str_add(&init_str, -1); - tok_str_add(&init_str, 0); - - /* compute size */ - save_parse_state(&saved_parse_state); - - begin_macro(&init_str, 0); - next(); - decl_initializer(type, NULL, 0, 1, 1); - /* prepare second initializer parsing */ - macro_ptr = init_str.str; - next(); - - /* if still unknown size, error */ - size = type_size(type, &align); - if (size < 0) - tcc_error("unknown type size"); - } - /* If there's a flex member and it was used in the initializer - adjust size. */ - if (flexible_array && - flexible_array->type.ref->c > 0) - size += flexible_array->type.ref->c - * pointed_size(&flexible_array->type); - /* take into account specified alignment if bigger */ - if (ad->a.aligned) { - if (ad->a.aligned > align) - align = ad->a.aligned; - } else if (ad->a.packed) { - align = 1; - } - if ((r & VT_VALMASK) == VT_LOCAL) { - sec = NULL; -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) { - loc--; - } -#endif - loc = (loc - size) & -align; - addr = loc; -#ifdef CONFIG_TCC_BCHECK - /* handles bounds */ - /* XXX: currently, since we do only one pass, we cannot track - '&' operators, so we add only arrays */ - if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) { - addr_t *bounds_ptr; - /* add padding between regions */ - loc--; - /* then add local bound info */ - bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(addr_t)); - bounds_ptr[0] = addr; - bounds_ptr[1] = size; - } -#endif - if (v) { - /* local variable */ - sym_push(v, type, r, addr); - } else { - /* push local reference */ - vset(type, r, addr); - } - } else { - Sym *sym; - - sym = NULL; - if (v && scope == VT_CONST) { - /* see if the symbol was already defined */ - sym = sym_find(v); - if (sym) { - if (!is_compatible_types(&sym->type, type)) - tcc_error("incompatible types for redefinition of '%s'", - get_tok_str(v, NULL)); - if (sym->type.t & VT_EXTERN) { - /* if the variable is extern, it was not allocated */ - sym->type.t &= ~VT_EXTERN; - /* set array size if it was omitted in extern - declaration */ - if ((sym->type.t & VT_ARRAY) && - sym->type.ref->c < 0 && - type->ref->c >= 0) - sym->type.ref->c = type->ref->c; - } else { - /* we accept several definitions of the same - global variable. this is tricky, because we - must play with the SHN_COMMON type of the symbol */ - /* XXX: should check if the variable was already - initialized. It is incorrect to initialized it - twice */ - /* no init data, we won't add more to the symbol */ - if (!has_init) - goto no_alloc; - } - } - } - - /* allocate symbol in corresponding section */ - sec = ad->section; - if (!sec) { - if (has_init) - sec = data_section; - else if (tcc_state->nocommon) - sec = bss_section; - } - if (sec) { - data_offset = sec->data_offset; - data_offset = (data_offset + align - 1) & -align; - addr = data_offset; - /* very important to increment global pointer at this time - because initializers themselves can create new initializers */ - data_offset += size; -#ifdef CONFIG_TCC_BCHECK - /* add padding if bound check */ - if (tcc_state->do_bounds_check) - data_offset++; -#endif - sec->data_offset = data_offset; - /* allocate section space to put the data */ - if (sec->sh_type != SHT_NOBITS && - data_offset > sec->data_allocated) - section_realloc(sec, data_offset); - /* align section if needed */ - if (align > sec->sh_addralign) - sec->sh_addralign = align; - } else { - addr = 0; /* avoid warning */ - } - - if (v) { - if (scope != VT_CONST || !sym) { - sym = sym_push(v, type, r | VT_SYM, 0); - sym->asm_label = ad->asm_label; - } - /* update symbol definition */ - if (sec) { - put_extern_sym(sym, sec, addr, size); - } else { - ElfW(Sym) *esym; - /* put a common area */ - put_extern_sym(sym, NULL, align, size); - /* XXX: find a nicer way */ - esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; - esym->st_shndx = SHN_COMMON; - } - } else { - /* push global reference */ - sym = get_sym_ref(type, sec, addr, size); - vpushsym(type, sym); - } - /* patch symbol weakness */ - if (type->t & VT_WEAK) - weaken_symbol(sym); - apply_visibility(sym, type); -#ifdef CONFIG_TCC_BCHECK - /* handles bounds now because the symbol must be defined - before for the relocation */ - if (tcc_state->do_bounds_check) { - addr_t *bounds_ptr; - - greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR); - /* then add global bound info */ - bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t)); - bounds_ptr[0] = 0; /* relocated */ - bounds_ptr[1] = size; - } -#endif - } - if (has_init || (type->t & VT_VLA)) { - decl_initializer(type, sec, addr, 1, 0); - /* restore parse state if needed */ - if (init_str.str) { - end_macro(); - restore_parse_state(&saved_parse_state); - } - /* patch flexible array member size back to -1, */ - /* for possible subsequent similar declarations */ - if (flexible_array) - flexible_array->type.ref->c = -1; - } - no_alloc: ; -} - -static void put_func_debug(Sym *sym) -{ - char buf[512]; - - /* stabs info */ - /* XXX: we put here a dummy type */ - snprintf(buf, sizeof(buf), "%s:%c1", - funcname, sym->type.t & VT_STATIC ? 'f' : 'F'); - put_stabs_r(buf, N_FUN, 0, file->line_num, 0, - cur_text_section, sym->c); - /* //gr gdb wants a line at the function */ - put_stabn(N_SLINE, 0, file->line_num, 0); - last_ind = 0; - last_line_num = 0; -} - -/* parse an old style function declaration list */ -/* XXX: check multiple parameter */ -static void func_decl_list(Sym *func_sym) -{ - AttributeDef ad; - int v; - Sym *s; - CType btype, type; - - /* parse each declaration */ - while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF && - tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) { - if (!parse_btype(&btype, &ad)) - expect("declaration list"); - if (((btype.t & VT_BTYPE) == VT_ENUM || - (btype.t & VT_BTYPE) == VT_STRUCT) && - tok == ';') { - /* we accept no variable after */ - } else { - for(;;) { - type = btype; - type_decl(&type, &ad, &v, TYPE_DIRECT); - /* find parameter in function parameter list */ - s = func_sym->next; - while (s != NULL) { - if ((s->v & ~SYM_FIELD) == v) - goto found; - s = s->next; - } - tcc_error("declaration for parameter '%s' but no such parameter", - get_tok_str(v, NULL)); - found: - /* check that no storage specifier except 'register' was given */ - if (type.t & VT_STORAGE) - tcc_error("storage class specified for '%s'", get_tok_str(v, NULL)); - convert_parameter_type(&type); - /* we can add the type (NOTE: it could be local to the function) */ - s->type = type; - /* accept other parameters */ - if (tok == ',') - next(); - else - break; - } - } - skip(';'); - } -} - -/* parse a function defined by symbol 'sym' and generate its code in - 'cur_text_section' */ -static void gen_function(Sym *sym) -{ - int saved_nocode_wanted = nocode_wanted; - - nocode_wanted = 0; - ind = cur_text_section->data_offset; - /* NOTE: we patch the symbol size later */ - put_extern_sym(sym, cur_text_section, ind, 0); - funcname = get_tok_str(sym->v, NULL); - func_ind = ind; - /* Initialize VLA state */ - vla_sp_loc = -1; - vla_sp_root_loc = -1; - /* put debug symbol */ - if (tcc_state->do_debug) - put_func_debug(sym); - /* push a dummy symbol to enable local sym storage */ - sym_push2(&local_stack, SYM_FIELD, 0, 0); - gfunc_prolog(&sym->type); -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check && !strcmp(funcname, "main")) { - int i; - Sym *sym; - for (i = 0, sym = local_stack; i < 2; i++, sym = sym->prev) { - if (sym->v & SYM_FIELD || sym->prev->v & SYM_FIELD) - break; - vpush_global_sym(&func_old_type, TOK___bound_main_arg); - vset(&sym->type, sym->r, sym->c); - gfunc_call(1); - } - } -#endif - rsym = 0; - block(NULL, NULL, NULL, NULL, 0, 0); - gsym(rsym); - gfunc_epilog(); - cur_text_section->data_offset = ind; - label_pop(&global_label_stack, NULL); - /* reset local stack */ - scope_stack_bottom = NULL; - sym_pop(&local_stack, NULL); - /* end of function */ - /* patch symbol size */ - ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size = - ind - func_ind; - /* patch symbol weakness (this definition overrules any prototype) */ - if (sym->type.t & VT_WEAK) - weaken_symbol(sym); - apply_visibility(sym, &sym->type); - if (tcc_state->do_debug) { - put_stabn(N_FUN, 0, 0, ind - func_ind); - } - /* It's better to crash than to generate wrong code */ - cur_text_section = NULL; - funcname = ""; /* for safety */ - func_vt.t = VT_VOID; /* for safety */ - func_var = 0; /* for safety */ - ind = 0; /* for safety */ - nocode_wanted = saved_nocode_wanted; - check_vstack(); -} - -ST_FUNC void gen_inline_functions(void) -{ - Sym *sym; - int inline_generated, i, ln; - struct InlineFunc *fn; - - ln = file->line_num; - /* iterate while inline function are referenced */ - for(;;) { - inline_generated = 0; - for (i = 0; i < tcc_state->nb_inline_fns; ++i) { - fn = tcc_state->inline_fns[i]; - sym = fn->sym; - if (sym && sym->c) { - /* the function was used: generate its code and - convert it to a normal function */ - fn->sym = NULL; - if (file) - pstrcpy(file->filename, sizeof file->filename, fn->filename); - sym->r = VT_SYM | VT_CONST; - sym->type.t &= ~VT_INLINE; - - begin_macro(&fn->func_str, 0); - next(); - cur_text_section = text_section; - gen_function(sym); - end_macro(); - - inline_generated = 1; - } - } - if (!inline_generated) - break; - } - file->line_num = ln; - /* free tokens of unused inline functions */ - for (i = 0; i < tcc_state->nb_inline_fns; ++i) { - fn = tcc_state->inline_fns[i]; - if (fn->sym) - tok_str_free(fn->func_str.str); - } - dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns); -} - -/* 'l' is VT_LOCAL or VT_CONST to define default storage type */ -static int decl0(int l, int is_for_loop_init) -{ - int v, has_init, r; - CType type, btype; - Sym *sym; - AttributeDef ad; - - while (1) { - if (!parse_btype(&btype, &ad)) { - if (is_for_loop_init) - return 0; - /* skip redundant ';' */ - /* XXX: find more elegant solution */ - if (tok == ';') { - next(); - continue; - } - if (l == VT_CONST && - (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) { - /* global asm block */ - asm_global_instr(); - continue; - } - /* special test for old K&R protos without explicit int - type. Only accepted when defining global data */ - if (l == VT_LOCAL || tok < TOK_DEFINE) - break; - btype.t = VT_INT; - } - if (((btype.t & VT_BTYPE) == VT_ENUM || - (btype.t & VT_BTYPE) == VT_STRUCT) && - tok == ';') { - if ((btype.t & VT_BTYPE) == VT_STRUCT) { - int v = btype.ref->v; - if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM) - tcc_warning("unnamed struct/union that defines no instances"); - } - next(); - continue; - } - while (1) { /* iterate thru each declaration */ - type = btype; - type_decl(&type, &ad, &v, TYPE_DIRECT); -#if 0 - { - char buf[500]; - type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL)); - printf("type = '%s'\n", buf); - } -#endif - if ((type.t & VT_BTYPE) == VT_FUNC) { - if ((type.t & VT_STATIC) && (l == VT_LOCAL)) { - tcc_error("function without file scope cannot be static"); - } - /* if old style function prototype, we accept a - declaration list */ - sym = type.ref; - if (sym->c == FUNC_OLD) - func_decl_list(sym); - } - - if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) { - ad.asm_label = asm_label_instr(); - /* parse one last attribute list, after asm label */ - parse_attribute(&ad); - if (tok == '{') - expect(";"); - } - - if (ad.a.weak) - type.t |= VT_WEAK; -#ifdef TCC_TARGET_PE - if (ad.a.func_import) - type.t |= VT_IMPORT; - if (ad.a.func_export) - type.t |= VT_EXPORT; -#endif - type.t |= ad.a.visibility << VT_VIS_SHIFT; - - if (tok == '{') { - if (l == VT_LOCAL) - tcc_error("cannot use local functions"); - if ((type.t & VT_BTYPE) != VT_FUNC) - expect("function definition"); - - /* reject abstract declarators in function definition */ - sym = type.ref; - while ((sym = sym->next) != NULL) - if (!(sym->v & ~SYM_FIELD)) - expect("identifier"); - - /* XXX: cannot do better now: convert extern line to static inline */ - if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE)) - type.t = (type.t & ~VT_EXTERN) | VT_STATIC; - - sym = sym_find(v); - if (sym) { - Sym *ref; - if ((sym->type.t & VT_BTYPE) != VT_FUNC) - goto func_error1; - - ref = sym->type.ref; - if (0 == ref->a.func_proto) - tcc_error("redefinition of '%s'", get_tok_str(v, NULL)); - - /* use func_call from prototype if not defined */ - if (ref->a.func_call != FUNC_CDECL - && type.ref->a.func_call == FUNC_CDECL) - type.ref->a.func_call = ref->a.func_call; - - /* use export from prototype */ - if (ref->a.func_export) - type.ref->a.func_export = 1; - - /* use static from prototype */ - if (sym->type.t & VT_STATIC) - type.t = (type.t & ~VT_EXTERN) | VT_STATIC; - - /* If the definition has no visibility use the - one from prototype. */ - if (! (type.t & VT_VIS_MASK)) - type.t |= sym->type.t & VT_VIS_MASK; - - if (!is_compatible_types(&sym->type, &type)) { - func_error1: - tcc_error("incompatible types for redefinition of '%s'", - get_tok_str(v, NULL)); - } - type.ref->a.func_proto = 0; - /* if symbol is already defined, then put complete type */ - sym->type = type; - } else { - /* put function symbol */ - sym = global_identifier_push(v, type.t, 0); - sym->type.ref = type.ref; - } - - /* static inline functions are just recorded as a kind - of macro. Their code will be emitted at the end of - the compilation unit only if they are used */ - if ((type.t & (VT_INLINE | VT_STATIC)) == - (VT_INLINE | VT_STATIC)) { - int block_level; - struct InlineFunc *fn; - const char *filename; - - filename = file ? file->filename : ""; - fn = tcc_malloc(sizeof *fn + strlen(filename)); - strcpy(fn->filename, filename); - fn->sym = sym; - tok_str_new(&fn->func_str); - - block_level = 0; - for(;;) { - int t; - if (tok == TOK_EOF) - tcc_error("unexpected end of file"); - tok_str_add_tok(&fn->func_str); - t = tok; - next(); - if (t == '{') { - block_level++; - } else if (t == '}') { - block_level--; - if (block_level == 0) - break; - } - } - tok_str_add(&fn->func_str, -1); - tok_str_add(&fn->func_str, 0); - dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn); - - } else { - /* compute text section */ - cur_text_section = ad.section; - if (!cur_text_section) - cur_text_section = text_section; - sym->r = VT_SYM | VT_CONST; - gen_function(sym); - } - break; - } else { - if (btype.t & VT_TYPEDEF) { - /* save typedefed type */ - /* XXX: test storage specifiers ? */ - sym = sym_push(v, &type, 0, 0); - sym->a = ad.a; - sym->type.t |= VT_TYPEDEF; - } else { - r = 0; - if ((type.t & VT_BTYPE) == VT_FUNC) { - /* external function definition */ - /* specific case for func_call attribute */ - ad.a.func_proto = 1; - type.ref->a = ad.a; - } else if (!(type.t & VT_ARRAY)) { - /* not lvalue if array */ - r |= lvalue_type(type.t); - } - has_init = (tok == '='); - if (has_init && (type.t & VT_VLA)) - tcc_error("Variable length array cannot be initialized"); - if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) || - ((type.t & VT_ARRAY) && (type.t & VT_STATIC) && - !has_init && l == VT_CONST && type.ref->c < 0)) { - /* external variable or function */ - /* NOTE: as GCC, uninitialized global static - arrays of null size are considered as - extern */ - sym = external_sym(v, &type, r); - sym->asm_label = ad.asm_label; - - if (ad.alias_target) { - Section tsec; - Elf32_Sym *esym; - Sym *alias_target; - - alias_target = sym_find(ad.alias_target); - if (!alias_target || !alias_target->c) - tcc_error("unsupported forward __alias__ attribute"); - esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c]; - tsec.sh_num = esym->st_shndx; - put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0); - } - } else { - type.t |= (btype.t & VT_STATIC); /* Retain "static". */ - if (type.t & VT_STATIC) - r |= VT_CONST; - else - r |= l; - if (has_init) - next(); - decl_initializer_alloc(&type, &ad, r, has_init, v, l); - } - } - if (tok != ',') { - if (is_for_loop_init) - return 1; - skip(';'); - break; - } - next(); - } - ad.a.aligned = 0; - } - } - return 0; -} - -ST_FUNC void decl(int l) -{ - decl0(l, 0); -} diff --git a/external/TCC/tcclib.h b/external/TCC/tcclib.h deleted file mode 100644 index 8d59e4c9..00000000 --- a/external/TCC/tcclib.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Simple libc header for TCC - * - * Add any function you want from the libc there. This file is here - * only for your convenience so that you do not need to put the whole - * glibc include files on your floppy disk - */ -#ifndef _TCCLIB_H -#define _TCCLIB_H - -#include -#include - -/* stdlib.h */ -void *calloc(size_t nmemb, size_t size); -void *malloc(size_t size); -void free(void *ptr); -void *realloc(void *ptr, size_t size); -int atoi(const char *nptr); -long int strtol(const char *nptr, char **endptr, int base); -unsigned long int strtoul(const char *nptr, char **endptr, int base); -void exit(int); - -/* stdio.h */ -typedef struct __FILE FILE; -#define EOF (-1) -extern FILE *stdin; -extern FILE *stdout; -extern FILE *stderr; -FILE *fopen(const char *path, const char *mode); -FILE *fdopen(int fildes, const char *mode); -FILE *freopen(const char *path, const char *mode, FILE *stream); -int fclose(FILE *stream); -size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); -size_t fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream); -int fgetc(FILE *stream); -char *fgets(char *s, int size, FILE *stream); -int getc(FILE *stream); -int getchar(void); -char *gets(char *s); -int ungetc(int c, FILE *stream); -int fflush(FILE *stream); -int putchar (int c); - -int printf(const char *format, ...); -int fprintf(FILE *stream, const char *format, ...); -int sprintf(char *str, const char *format, ...); -int snprintf(char *str, size_t size, const char *format, ...); -int asprintf(char **strp, const char *format, ...); -int dprintf(int fd, const char *format, ...); -int vprintf(const char *format, va_list ap); -int vfprintf(FILE *stream, const char *format, va_list ap); -int vsprintf(char *str, const char *format, va_list ap); -int vsnprintf(char *str, size_t size, const char *format, va_list ap); -int vasprintf(char **strp, const char *format, va_list ap); -int vdprintf(int fd, const char *format, va_list ap); - -void perror(const char *s); - -/* string.h */ -char *strcat(char *dest, const char *src); -char *strchr(const char *s, int c); -char *strrchr(const char *s, int c); -char *strcpy(char *dest, const char *src); -void *memcpy(void *dest, const void *src, size_t n); -void *memmove(void *dest, const void *src, size_t n); -void *memset(void *s, int c, size_t n); -char *strdup(const char *s); -size_t strlen(const char *s); - -/* dlfcn.h */ -#define RTLD_LAZY 0x001 -#define RTLD_NOW 0x002 -#define RTLD_GLOBAL 0x100 - -void *dlopen(const char *filename, int flag); -const char *dlerror(void); -void *dlsym(void *handle, char *symbol); -int dlclose(void *handle); - -#endif /* _TCCLIB_H */ diff --git a/external/TCC/tccpe.c b/external/TCC/tccpe.c deleted file mode 100644 index eb13d2df..00000000 --- a/external/TCC/tccpe.c +++ /dev/null @@ -1,1890 +0,0 @@ -/* - * TCCPE.C - PE file output for the Tiny C Compiler - * - * Copyright (c) 2005-2007 grischka - * - * 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "tcc.h" - -#ifndef _WIN32 -#define stricmp strcasecmp -#define strnicmp strncasecmp -#endif - -#ifndef MAX_PATH -#define MAX_PATH 260 -#endif - -#define PE_MERGE_DATA -/* #define PE_PRINT_SECTIONS */ - -#ifdef TCC_TARGET_X86_64 -# define ADDR3264 ULONGLONG -# define REL_TYPE_DIRECT R_X86_64_64 -# define R_XXX_THUNKFIX R_X86_64_PC32 -# define R_XXX_RELATIVE R_X86_64_RELATIVE -# define IMAGE_FILE_MACHINE 0x8664 -# define RSRC_RELTYPE 3 - -#elif defined TCC_TARGET_ARM -# define ADDR3264 DWORD -# define REL_TYPE_DIRECT R_ARM_ABS32 -# define R_XXX_THUNKFIX R_ARM_ABS32 -# define R_XXX_RELATIVE R_ARM_RELATIVE -# define IMAGE_FILE_MACHINE 0x01C0 -# define RSRC_RELTYPE 7 /* ??? (not tested) */ - -#elif defined TCC_TARGET_I386 -# define ADDR3264 DWORD -# define REL_TYPE_DIRECT R_386_32 -# define R_XXX_THUNKFIX R_386_32 -# define R_XXX_RELATIVE R_386_RELATIVE -# define IMAGE_FILE_MACHINE 0x014C -# define RSRC_RELTYPE 7 /* DIR32NB */ - -#endif - -#ifdef _WIN32 -void dbg_printf (const char *fmt, ...) -{ - char buffer[4000]; - va_list arg; - int x; - va_start(arg, fmt); - x = vsprintf (buffer, fmt, arg); - strcpy(buffer+x, "\n"); - OutputDebugString(buffer); -} -#endif - -/* ----------------------------------------------------------- */ -#ifndef IMAGE_NT_SIGNATURE -/* ----------------------------------------------------------- */ -/* definitions below are from winnt.h */ - -typedef unsigned char BYTE; -typedef unsigned short WORD; -typedef unsigned int DWORD; -typedef unsigned long long ULONGLONG; -#pragma pack(push, 1) - -typedef struct _IMAGE_DOS_HEADER { /* DOS .EXE header */ - WORD e_magic; /* Magic number */ - WORD e_cblp; /* Bytes on last page of file */ - WORD e_cp; /* Pages in file */ - WORD e_crlc; /* Relocations */ - WORD e_cparhdr; /* Size of header in paragraphs */ - WORD e_minalloc; /* Minimum extra paragraphs needed */ - WORD e_maxalloc; /* Maximum extra paragraphs needed */ - WORD e_ss; /* Initial (relative) SS value */ - WORD e_sp; /* Initial SP value */ - WORD e_csum; /* Checksum */ - WORD e_ip; /* Initial IP value */ - WORD e_cs; /* Initial (relative) CS value */ - WORD e_lfarlc; /* File address of relocation table */ - WORD e_ovno; /* Overlay number */ - WORD e_res[4]; /* Reserved words */ - WORD e_oemid; /* OEM identifier (for e_oeminfo) */ - WORD e_oeminfo; /* OEM information; e_oemid specific */ - WORD e_res2[10]; /* Reserved words */ - DWORD e_lfanew; /* File address of new exe header */ -} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; - -#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */ -#define SIZE_OF_NT_SIGNATURE 4 - -typedef struct _IMAGE_FILE_HEADER { - WORD Machine; - WORD NumberOfSections; - DWORD TimeDateStamp; - DWORD PointerToSymbolTable; - DWORD NumberOfSymbols; - WORD SizeOfOptionalHeader; - WORD Characteristics; -} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; - - -#define IMAGE_SIZEOF_FILE_HEADER 20 - -typedef struct _IMAGE_DATA_DIRECTORY { - DWORD VirtualAddress; - DWORD Size; -} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; - - -typedef struct _IMAGE_OPTIONAL_HEADER { - /* Standard fields. */ - WORD Magic; - BYTE MajorLinkerVersion; - BYTE MinorLinkerVersion; - DWORD SizeOfCode; - DWORD SizeOfInitializedData; - DWORD SizeOfUninitializedData; - DWORD AddressOfEntryPoint; - DWORD BaseOfCode; -#ifndef TCC_TARGET_X86_64 - DWORD BaseOfData; -#endif - /* NT additional fields. */ - ADDR3264 ImageBase; - DWORD SectionAlignment; - DWORD FileAlignment; - WORD MajorOperatingSystemVersion; - WORD MinorOperatingSystemVersion; - WORD MajorImageVersion; - WORD MinorImageVersion; - WORD MajorSubsystemVersion; - WORD MinorSubsystemVersion; - DWORD Win32VersionValue; - DWORD SizeOfImage; - DWORD SizeOfHeaders; - DWORD CheckSum; - WORD Subsystem; - WORD DllCharacteristics; - ADDR3264 SizeOfStackReserve; - ADDR3264 SizeOfStackCommit; - ADDR3264 SizeOfHeapReserve; - ADDR3264 SizeOfHeapCommit; - DWORD LoaderFlags; - DWORD NumberOfRvaAndSizes; - IMAGE_DATA_DIRECTORY DataDirectory[16]; -} IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, IMAGE_OPTIONAL_HEADER; - -#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 /* Export Directory */ -#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 /* Import Directory */ -#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 /* Resource Directory */ -#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 /* Exception Directory */ -#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 /* Security Directory */ -#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 /* Base Relocation Table */ -#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 /* Debug Directory */ -/* IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 (X86 usage) */ -#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 /* Architecture Specific Data */ -#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 /* RVA of GP */ -#define IMAGE_DIRECTORY_ENTRY_TLS 9 /* TLS Directory */ -#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 /* Load Configuration Directory */ -#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 /* Bound Import Directory in headers */ -#define IMAGE_DIRECTORY_ENTRY_IAT 12 /* Import Address Table */ -#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 /* Delay Load Import Descriptors */ -#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 /* COM Runtime descriptor */ - -/* Section header format. */ -#define IMAGE_SIZEOF_SHORT_NAME 8 - -typedef struct _IMAGE_SECTION_HEADER { - BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; - union { - DWORD PhysicalAddress; - DWORD VirtualSize; - } Misc; - DWORD VirtualAddress; - DWORD SizeOfRawData; - DWORD PointerToRawData; - DWORD PointerToRelocations; - DWORD PointerToLinenumbers; - WORD NumberOfRelocations; - WORD NumberOfLinenumbers; - DWORD Characteristics; -} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; - -#define IMAGE_SIZEOF_SECTION_HEADER 40 - -typedef struct _IMAGE_EXPORT_DIRECTORY { - DWORD Characteristics; - DWORD TimeDateStamp; - WORD MajorVersion; - WORD MinorVersion; - DWORD Name; - DWORD Base; - DWORD NumberOfFunctions; - DWORD NumberOfNames; - DWORD AddressOfFunctions; - DWORD AddressOfNames; - DWORD AddressOfNameOrdinals; -} IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY; - -typedef struct _IMAGE_IMPORT_DESCRIPTOR { - union { - DWORD Characteristics; - DWORD OriginalFirstThunk; - }; - DWORD TimeDateStamp; - DWORD ForwarderChain; - DWORD Name; - DWORD FirstThunk; -} IMAGE_IMPORT_DESCRIPTOR; - -typedef struct _IMAGE_BASE_RELOCATION { - DWORD VirtualAddress; - DWORD SizeOfBlock; -// WORD TypeOffset[1]; -} IMAGE_BASE_RELOCATION; - -#define IMAGE_SIZEOF_BASE_RELOCATION 8 - -#define IMAGE_REL_BASED_ABSOLUTE 0 -#define IMAGE_REL_BASED_HIGH 1 -#define IMAGE_REL_BASED_LOW 2 -#define IMAGE_REL_BASED_HIGHLOW 3 -#define IMAGE_REL_BASED_HIGHADJ 4 -#define IMAGE_REL_BASED_MIPS_JMPADDR 5 -#define IMAGE_REL_BASED_SECTION 6 -#define IMAGE_REL_BASED_REL32 7 - -#pragma pack(pop) - -/* ----------------------------------------------------------- */ -#endif /* ndef IMAGE_NT_SIGNATURE */ -/* ----------------------------------------------------------- */ -#pragma pack(push, 1) - -struct pe_header -{ - IMAGE_DOS_HEADER doshdr; - BYTE dosstub[0x40]; - DWORD nt_sig; - IMAGE_FILE_HEADER filehdr; -#ifdef TCC_TARGET_X86_64 - IMAGE_OPTIONAL_HEADER64 opthdr; -#else -#ifdef _WIN64 - IMAGE_OPTIONAL_HEADER32 opthdr; -#else - IMAGE_OPTIONAL_HEADER opthdr; -#endif -#endif -}; - -struct pe_reloc_header { - DWORD offset; - DWORD size; -}; - -struct pe_rsrc_header { - struct _IMAGE_FILE_HEADER filehdr; - struct _IMAGE_SECTION_HEADER sectionhdr; -}; - -struct pe_rsrc_reloc { - DWORD offset; - DWORD size; - WORD type; -}; - -#pragma pack(pop) - -/* ------------------------------------------------------------- */ -/* internal temporary structures */ - -/* -#define IMAGE_SCN_CNT_CODE 0x00000020 -#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 -#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 -#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 -#define IMAGE_SCN_MEM_SHARED 0x10000000 -#define IMAGE_SCN_MEM_EXECUTE 0x20000000 -#define IMAGE_SCN_MEM_READ 0x40000000 -#define IMAGE_SCN_MEM_WRITE 0x80000000 -*/ - -enum { - sec_text = 0, - sec_data , - sec_bss , - sec_idata , - sec_pdata , - sec_other , - sec_rsrc , - sec_stab , - sec_reloc , - sec_last -}; - -static const DWORD pe_sec_flags[] = { - 0x60000020, /* ".text" , */ - 0xC0000040, /* ".data" , */ - 0xC0000080, /* ".bss" , */ - 0x40000040, /* ".idata" , */ - 0x40000040, /* ".pdata" , */ - 0xE0000060, /* < other > , */ - 0x40000040, /* ".rsrc" , */ - 0x42000802, /* ".stab" , */ - 0x42000040, /* ".reloc" , */ -}; - -struct section_info { - int cls, ord; - char name[32]; - DWORD sh_addr; - DWORD sh_size; - DWORD sh_flags; - unsigned char *data; - DWORD data_size; - IMAGE_SECTION_HEADER ish; -}; - -struct import_symbol { - int sym_index; - int iat_index; - int thk_offset; -}; - -struct pe_import_info { - int dll_index; - int sym_count; - struct import_symbol **symbols; -}; - -struct pe_info { - TCCState *s1; - Section *reloc; - Section *thunk; - const char *filename; - int type; - DWORD sizeofheaders; - ADDR3264 imagebase; - DWORD start_addr; - DWORD imp_offs; - DWORD imp_size; - DWORD iat_offs; - DWORD iat_size; - DWORD exp_offs; - DWORD exp_size; - int subsystem; - DWORD section_align; - DWORD file_align; - struct section_info *sec_info; - int sec_count; - struct pe_import_info **imp_info; - int imp_count; -}; - -#define PE_NUL 0 -#define PE_DLL 1 -#define PE_GUI 2 -#define PE_EXE 3 -#define PE_RUN 4 - -/* --------------------------------------------*/ - -static const char *pe_export_name(TCCState *s1, ElfW(Sym) *sym) -{ - const char *name = symtab_section->link->data + sym->st_name; - if (s1->leading_underscore && name[0] == '_' && !(sym->st_other & ST_PE_STDCALL)) - return name + 1; - return name; -} - -static int pe_find_import(TCCState * s1, ElfW(Sym) *sym) -{ - char buffer[200]; - const char *s, *p; - int sym_index = 0, n = 0; - - do { - s = pe_export_name(s1, sym); - if (n) { - /* second try: */ - if (sym->st_other & ST_PE_STDCALL) { - /* try w/0 stdcall deco (windows API convention) */ - p = strrchr(s, '@'); - if (!p || s[0] != '_') - break; - strcpy(buffer, s+1)[p-s-1] = 0; - } else if (s[0] != '_') { /* try non-ansi function */ - buffer[0] = '_', strcpy(buffer + 1, s); - } else if (0 == memcmp(s, "__imp__", 7)) { /* mingw 2.0 */ - strcpy(buffer, s + 6); - } else if (0 == memcmp(s, "_imp___", 7)) { /* mingw 3.7 */ - strcpy(buffer, s + 6); - } else { - break; - } - s = buffer; - } - sym_index = find_elf_sym(s1->dynsymtab_section, s); - // printf("find (%d) %d %s\n", n, sym_index, s); - } while (0 == sym_index && ++n < 2); - return sym_index; -} - -/*----------------------------------------------------------------------------*/ - -static int dynarray_assoc(void **pp, int n, int key) -{ - int i; - for (i = 0; i < n; ++i, ++pp) - if (key == **(int **) pp) - return i; - return -1; -} - -#if 0 -ST_FN DWORD umin(DWORD a, DWORD b) -{ - return a < b ? a : b; -} -#endif - -static DWORD umax(DWORD a, DWORD b) -{ - return a < b ? b : a; -} - -static DWORD pe_file_align(struct pe_info *pe, DWORD n) -{ - return (n + (pe->file_align - 1)) & ~(pe->file_align - 1); -} - -static DWORD pe_virtual_align(struct pe_info *pe, DWORD n) -{ - return (n + (pe->section_align - 1)) & ~(pe->section_align - 1); -} - -static void pe_align_section(Section *s, int a) -{ - int i = s->data_offset & (a-1); - if (i) - section_ptr_add(s, a - i); -} - -static void pe_set_datadir(struct pe_header *hdr, int dir, DWORD addr, DWORD size) -{ - hdr->opthdr.DataDirectory[dir].VirtualAddress = addr; - hdr->opthdr.DataDirectory[dir].Size = size; -} - -static int pe_fwrite(void *data, unsigned len, FILE *fp, DWORD *psum) -{ - if (psum) { - DWORD sum = *psum; - WORD *p = data; - int i; - for (i = len; i > 0; i -= 2) { - sum += (i >= 2) ? *p++ : *(BYTE*)p; - sum = (sum + (sum >> 16)) & 0xFFFF; - } - *psum = sum; - } - return len == fwrite(data, 1, len, fp) ? 0 : -1; -} - -static void pe_fpad(FILE *fp, DWORD new_pos) -{ - DWORD pos = ftell(fp); - while (++pos <= new_pos) - fputc(0, fp); -} - -/*----------------------------------------------------------------------------*/ -static int pe_write(struct pe_info *pe) -{ - static const struct pe_header pe_template = { - { - /* IMAGE_DOS_HEADER doshdr */ - 0x5A4D, /*WORD e_magic; Magic number */ - 0x0090, /*WORD e_cblp; Bytes on last page of file */ - 0x0003, /*WORD e_cp; Pages in file */ - 0x0000, /*WORD e_crlc; Relocations */ - - 0x0004, /*WORD e_cparhdr; Size of header in paragraphs */ - 0x0000, /*WORD e_minalloc; Minimum extra paragraphs needed */ - 0xFFFF, /*WORD e_maxalloc; Maximum extra paragraphs needed */ - 0x0000, /*WORD e_ss; Initial (relative) SS value */ - - 0x00B8, /*WORD e_sp; Initial SP value */ - 0x0000, /*WORD e_csum; Checksum */ - 0x0000, /*WORD e_ip; Initial IP value */ - 0x0000, /*WORD e_cs; Initial (relative) CS value */ - 0x0040, /*WORD e_lfarlc; File address of relocation table */ - 0x0000, /*WORD e_ovno; Overlay number */ - {0,0,0,0}, /*WORD e_res[4]; Reserved words */ - 0x0000, /*WORD e_oemid; OEM identifier (for e_oeminfo) */ - 0x0000, /*WORD e_oeminfo; OEM information; e_oemid specific */ - {0,0,0,0,0,0,0,0,0,0}, /*WORD e_res2[10]; Reserved words */ - 0x00000080 /*DWORD e_lfanew; File address of new exe header */ - },{ - /* BYTE dosstub[0x40] */ - /* 14 code bytes + "This program cannot be run in DOS mode.\r\r\n$" + 6 * 0x00 */ - 0x0e,0x1f,0xba,0x0e,0x00,0xb4,0x09,0xcd,0x21,0xb8,0x01,0x4c,0xcd,0x21,0x54,0x68, - 0x69,0x73,0x20,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x20,0x63,0x61,0x6e,0x6e,0x6f, - 0x74,0x20,0x62,0x65,0x20,0x72,0x75,0x6e,0x20,0x69,0x6e,0x20,0x44,0x4f,0x53,0x20, - 0x6d,0x6f,0x64,0x65,0x2e,0x0d,0x0d,0x0a,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - }, - 0x00004550, /* DWORD nt_sig = IMAGE_NT_SIGNATURE */ - { - /* IMAGE_FILE_HEADER filehdr */ - IMAGE_FILE_MACHINE, /*WORD Machine; */ - 0x0003, /*WORD NumberOfSections; */ - 0x00000000, /*DWORD TimeDateStamp; */ - 0x00000000, /*DWORD PointerToSymbolTable; */ - 0x00000000, /*DWORD NumberOfSymbols; */ -#if defined(TCC_TARGET_X86_64) - 0x00F0, /*WORD SizeOfOptionalHeader; */ - 0x022F /*WORD Characteristics; */ -#define CHARACTERISTICS_DLL 0x222E -#elif defined(TCC_TARGET_I386) - 0x00E0, /*WORD SizeOfOptionalHeader; */ - 0x030F /*WORD Characteristics; */ -#define CHARACTERISTICS_DLL 0x230E -#elif defined(TCC_TARGET_ARM) - 0x00E0, /*WORD SizeOfOptionalHeader; */ - 0x010F, /*WORD Characteristics; */ -#define CHARACTERISTICS_DLL 0x230F -#endif -},{ - /* IMAGE_OPTIONAL_HEADER opthdr */ - /* Standard fields. */ -#ifdef TCC_TARGET_X86_64 - 0x020B, /*WORD Magic; */ -#else - 0x010B, /*WORD Magic; */ -#endif - 0x06, /*BYTE MajorLinkerVersion; */ - 0x00, /*BYTE MinorLinkerVersion; */ - 0x00000000, /*DWORD SizeOfCode; */ - 0x00000000, /*DWORD SizeOfInitializedData; */ - 0x00000000, /*DWORD SizeOfUninitializedData; */ - 0x00000000, /*DWORD AddressOfEntryPoint; */ - 0x00000000, /*DWORD BaseOfCode; */ -#ifndef TCC_TARGET_X86_64 - 0x00000000, /*DWORD BaseOfData; */ -#endif - /* NT additional fields. */ -#if defined(TCC_TARGET_ARM) - 0x00100000, /*DWORD ImageBase; */ -#else - 0x00400000, /*DWORD ImageBase; */ -#endif - 0x00001000, /*DWORD SectionAlignment; */ - 0x00000200, /*DWORD FileAlignment; */ - 0x0004, /*WORD MajorOperatingSystemVersion; */ - 0x0000, /*WORD MinorOperatingSystemVersion; */ - 0x0000, /*WORD MajorImageVersion; */ - 0x0000, /*WORD MinorImageVersion; */ - 0x0004, /*WORD MajorSubsystemVersion; */ - 0x0000, /*WORD MinorSubsystemVersion; */ - 0x00000000, /*DWORD Win32VersionValue; */ - 0x00000000, /*DWORD SizeOfImage; */ - 0x00000200, /*DWORD SizeOfHeaders; */ - 0x00000000, /*DWORD CheckSum; */ - 0x0002, /*WORD Subsystem; */ - 0x0000, /*WORD DllCharacteristics; */ - 0x00100000, /*DWORD SizeOfStackReserve; */ - 0x00001000, /*DWORD SizeOfStackCommit; */ - 0x00100000, /*DWORD SizeOfHeapReserve; */ - 0x00001000, /*DWORD SizeOfHeapCommit; */ - 0x00000000, /*DWORD LoaderFlags; */ - 0x00000010, /*DWORD NumberOfRvaAndSizes; */ - - /* IMAGE_DATA_DIRECTORY DataDirectory[16]; */ - {{0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}} - }}; - - struct pe_header pe_header = pe_template; - - int i; - FILE *op; - DWORD file_offset, sum; - struct section_info *si; - IMAGE_SECTION_HEADER *psh; - - op = fopen(pe->filename, "wb"); - if (NULL == op) { - tcc_error_noabort("could not write '%s': %s", pe->filename, strerror(errno)); - return -1; - } - - pe->sizeofheaders = pe_file_align(pe, - sizeof (struct pe_header) - + pe->sec_count * sizeof (IMAGE_SECTION_HEADER) - ); - - file_offset = pe->sizeofheaders; - - if (2 == pe->s1->verbose) - printf("-------------------------------" - "\n virt file size section" "\n"); - for (i = 0; i < pe->sec_count; ++i) { - DWORD addr, size; - const char *sh_name; - - si = pe->sec_info + i; - sh_name = si->name; - addr = si->sh_addr - pe->imagebase; - size = si->sh_size; - psh = &si->ish; - - if (2 == pe->s1->verbose) - printf("%6x %6x %6x %s\n", - (unsigned)addr, (unsigned)file_offset, (unsigned)size, sh_name); - - switch (si->cls) { - case sec_text: - pe_header.opthdr.BaseOfCode = addr; - pe_header.opthdr.AddressOfEntryPoint = addr + pe->start_addr; - break; - - case sec_data: -#ifndef TCC_TARGET_X86_64 - pe_header.opthdr.BaseOfData = addr; -#endif - break; - - case sec_bss: - break; - - case sec_reloc: - pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_BASERELOC, addr, size); - break; - - case sec_rsrc: - pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_RESOURCE, addr, size); - break; - - case sec_pdata: - pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_EXCEPTION, addr, size); - break; - - case sec_stab: - break; - } - - if (pe->thunk == pe->s1->sections[si->ord]) { - if (pe->imp_size) { - pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_IMPORT, - pe->imp_offs + addr, pe->imp_size); - pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_IAT, - pe->iat_offs + addr, pe->iat_size); - } - if (pe->exp_size) { - pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_EXPORT, - pe->exp_offs + addr, pe->exp_size); - } - } - - strncpy((char*)psh->Name, sh_name, sizeof psh->Name); - - psh->Characteristics = pe_sec_flags[si->cls]; - psh->VirtualAddress = addr; - psh->Misc.VirtualSize = size; - pe_header.opthdr.SizeOfImage = - umax(pe_virtual_align(pe, size + addr), pe_header.opthdr.SizeOfImage); - - if (si->data_size) { - psh->PointerToRawData = file_offset; - file_offset = pe_file_align(pe, file_offset + si->data_size); - psh->SizeOfRawData = file_offset - psh->PointerToRawData; - } - } - - //pe_header.filehdr.TimeDateStamp = time(NULL); - pe_header.filehdr.NumberOfSections = pe->sec_count; - pe_header.opthdr.SizeOfHeaders = pe->sizeofheaders; - pe_header.opthdr.ImageBase = pe->imagebase; - pe_header.opthdr.Subsystem = pe->subsystem; - if (pe->s1->pe_stack_size) - pe_header.opthdr.SizeOfStackReserve = pe->s1->pe_stack_size; - if (PE_DLL == pe->type) - pe_header.filehdr.Characteristics = CHARACTERISTICS_DLL; - - sum = 0; - pe_fwrite(&pe_header, sizeof pe_header, op, &sum); - for (i = 0; i < pe->sec_count; ++i) - pe_fwrite(&pe->sec_info[i].ish, sizeof(IMAGE_SECTION_HEADER), op, &sum); - pe_fpad(op, pe->sizeofheaders); - for (i = 0; i < pe->sec_count; ++i) { - si = pe->sec_info + i; - psh = &si->ish; - if (si->data_size) { - pe_fwrite(si->data, si->data_size, op, &sum); - file_offset = psh->PointerToRawData + psh->SizeOfRawData; - pe_fpad(op, file_offset); - } - } - - pe_header.opthdr.CheckSum = sum + file_offset; - fseek(op, offsetof(struct pe_header, opthdr.CheckSum), SEEK_SET); - pe_fwrite(&pe_header.opthdr.CheckSum, sizeof pe_header.opthdr.CheckSum, op, NULL); - fclose (op); - - if (2 == pe->s1->verbose) - printf("-------------------------------\n"); - if (pe->s1->verbose) - printf("<- %s (%u bytes)\n", pe->filename, (unsigned)file_offset); - - return 0; -} - -/*----------------------------------------------------------------------------*/ - -static struct import_symbol *pe_add_import(struct pe_info *pe, int sym_index) -{ - int i; - int dll_index; - struct pe_import_info *p; - struct import_symbol *s; - ElfW(Sym) *isym; - - isym = (ElfW(Sym) *)pe->s1->dynsymtab_section->data + sym_index; - dll_index = isym->st_size; - - i = dynarray_assoc ((void**)pe->imp_info, pe->imp_count, dll_index); - if (-1 != i) { - p = pe->imp_info[i]; - goto found_dll; - } - p = tcc_mallocz(sizeof *p); - p->dll_index = dll_index; - dynarray_add((void***)&pe->imp_info, &pe->imp_count, p); - -found_dll: - i = dynarray_assoc ((void**)p->symbols, p->sym_count, sym_index); - if (-1 != i) - return p->symbols[i]; - - s = tcc_mallocz(sizeof *s); - dynarray_add((void***)&p->symbols, &p->sym_count, s); - s->sym_index = sym_index; - return s; -} - -/*----------------------------------------------------------------------------*/ -static void pe_build_imports(struct pe_info *pe) -{ - int thk_ptr, ent_ptr, dll_ptr, sym_cnt, i; - DWORD rva_base = pe->thunk->sh_addr - pe->imagebase; - int ndlls = pe->imp_count; - - for (sym_cnt = i = 0; i < ndlls; ++i) - sym_cnt += pe->imp_info[i]->sym_count; - - if (0 == sym_cnt) - return; - - pe_align_section(pe->thunk, 16); - - pe->imp_offs = dll_ptr = pe->thunk->data_offset; - pe->imp_size = (ndlls + 1) * sizeof(IMAGE_IMPORT_DESCRIPTOR); - pe->iat_offs = dll_ptr + pe->imp_size; - pe->iat_size = (sym_cnt + ndlls) * sizeof(ADDR3264); - section_ptr_add(pe->thunk, pe->imp_size + 2*pe->iat_size); - - thk_ptr = pe->iat_offs; - ent_ptr = pe->iat_offs + pe->iat_size; - - for (i = 0; i < pe->imp_count; ++i) { - IMAGE_IMPORT_DESCRIPTOR *hdr; - int k, n, dllindex; - ADDR3264 v; - struct pe_import_info *p = pe->imp_info[i]; - const char *name; - DLLReference *dllref; - - dllindex = p->dll_index; - if (dllindex) - name = (dllref = pe->s1->loaded_dlls[dllindex-1])->name; - else - name = "", dllref = NULL; - - /* put the dll name into the import header */ - v = put_elf_str(pe->thunk, name); - hdr = (IMAGE_IMPORT_DESCRIPTOR*)(pe->thunk->data + dll_ptr); - hdr->FirstThunk = thk_ptr + rva_base; - hdr->OriginalFirstThunk = ent_ptr + rva_base; - hdr->Name = v + rva_base; - - for (k = 0, n = p->sym_count; k <= n; ++k) { - if (k < n) { - int iat_index = p->symbols[k]->iat_index; - int sym_index = p->symbols[k]->sym_index; - ElfW(Sym) *imp_sym = (ElfW(Sym) *)pe->s1->dynsymtab_section->data + sym_index; - ElfW(Sym) *org_sym = (ElfW(Sym) *)symtab_section->data + iat_index; - const char *name = pe->s1->dynsymtab_section->link->data + imp_sym->st_name; - int ordinal; - - org_sym->st_value = thk_ptr; - org_sym->st_shndx = pe->thunk->sh_num; - - if (dllref) - v = 0, ordinal = imp_sym->st_value; /* ordinal from pe_load_def */ - else - ordinal = 0, v = imp_sym->st_value; /* address from tcc_add_symbol() */ - -#ifdef TCC_IS_NATIVE - if (pe->type == PE_RUN) { - if (dllref) { - if ( !dllref->handle ) - dllref->handle = LoadLibrary(dllref->name); - v = (ADDR3264)GetProcAddress(dllref->handle, ordinal?(LPCSTR)NULL+ordinal:name); - } - if (!v) - tcc_error_noabort("can't build symbol '%s'", name); - } else -#endif - if (ordinal) { - v = ordinal | (ADDR3264)1 << (sizeof(ADDR3264)*8 - 1); - } else { - v = pe->thunk->data_offset + rva_base; - section_ptr_add(pe->thunk, sizeof(WORD)); /* hint, not used */ - put_elf_str(pe->thunk, name); - } - - } else { - v = 0; /* last entry is zero */ - } - - *(ADDR3264*)(pe->thunk->data+thk_ptr) = - *(ADDR3264*)(pe->thunk->data+ent_ptr) = v; - thk_ptr += sizeof (ADDR3264); - ent_ptr += sizeof (ADDR3264); - } - dll_ptr += sizeof(IMAGE_IMPORT_DESCRIPTOR); - dynarray_reset(&p->symbols, &p->sym_count); - } - dynarray_reset(&pe->imp_info, &pe->imp_count); -} - -/* ------------------------------------------------------------- */ - -struct pe_sort_sym -{ - int index; - const char *name; -}; - -static int sym_cmp(const void *va, const void *vb) -{ - const char *ca = (*(struct pe_sort_sym**)va)->name; - const char *cb = (*(struct pe_sort_sym**)vb)->name; - return strcmp(ca, cb); -} - -static void pe_build_exports(struct pe_info *pe) -{ - ElfW(Sym) *sym; - int sym_index, sym_end; - DWORD rva_base, func_o, name_o, ord_o, str_o; - IMAGE_EXPORT_DIRECTORY *hdr; - int sym_count, ord; - struct pe_sort_sym **sorted, *p; - - FILE *op; - char buf[MAX_PATH]; - const char *dllname; - const char *name; - - rva_base = pe->thunk->sh_addr - pe->imagebase; - sym_count = 0, sorted = NULL, op = NULL; - - sym_end = symtab_section->data_offset / sizeof(ElfW(Sym)); - for (sym_index = 1; sym_index < sym_end; ++sym_index) { - sym = (ElfW(Sym)*)symtab_section->data + sym_index; - name = pe_export_name(pe->s1, sym); - if ((sym->st_other & ST_PE_EXPORT) - /* export only symbols from actually written sections */ - && pe->s1->sections[sym->st_shndx]->sh_addr) { - p = tcc_malloc(sizeof *p); - p->index = sym_index; - p->name = name; - dynarray_add((void***)&sorted, &sym_count, p); - } -#if 0 - if (sym->st_other & ST_PE_EXPORT) - printf("export: %s\n", name); - if (sym->st_other & ST_PE_STDCALL) - printf("stdcall: %s\n", name); -#endif - } - - if (0 == sym_count) - return; - - qsort (sorted, sym_count, sizeof *sorted, sym_cmp); - - pe_align_section(pe->thunk, 16); - dllname = tcc_basename(pe->filename); - - pe->exp_offs = pe->thunk->data_offset; - func_o = pe->exp_offs + sizeof(IMAGE_EXPORT_DIRECTORY); - name_o = func_o + sym_count * sizeof (DWORD); - ord_o = name_o + sym_count * sizeof (DWORD); - str_o = ord_o + sym_count * sizeof(WORD); - - hdr = section_ptr_add(pe->thunk, str_o - pe->exp_offs); - hdr->Characteristics = 0; - hdr->Base = 1; - hdr->NumberOfFunctions = sym_count; - hdr->NumberOfNames = sym_count; - hdr->AddressOfFunctions = func_o + rva_base; - hdr->AddressOfNames = name_o + rva_base; - hdr->AddressOfNameOrdinals = ord_o + rva_base; - hdr->Name = str_o + rva_base; - put_elf_str(pe->thunk, dllname); - -#if 1 - /* automatically write exports to .def */ - pstrcpy(buf, sizeof buf, pe->filename); - strcpy(tcc_fileextension(buf), ".def"); - op = fopen(buf, "w"); - if (NULL == op) { - tcc_error_noabort("could not create '%s': %s", buf, strerror(errno)); - } else { - fprintf(op, "LIBRARY %s\n\nEXPORTS\n", dllname); - if (pe->s1->verbose) - printf("<- %s (%d symbols)\n", buf, sym_count); - } -#endif - - for (ord = 0; ord < sym_count; ++ord) - { - p = sorted[ord], sym_index = p->index, name = p->name; - /* insert actual address later in pe_relocate_rva */ - put_elf_reloc(symtab_section, pe->thunk, - func_o, R_XXX_RELATIVE, sym_index); - *(DWORD*)(pe->thunk->data + name_o) - = pe->thunk->data_offset + rva_base; - *(WORD*)(pe->thunk->data + ord_o) - = ord; - put_elf_str(pe->thunk, name); - func_o += sizeof (DWORD); - name_o += sizeof (DWORD); - ord_o += sizeof (WORD); - if (op) - fprintf(op, "%s\n", name); - } - pe->exp_size = pe->thunk->data_offset - pe->exp_offs; - dynarray_reset(&sorted, &sym_count); - if (op) - fclose(op); -} - -/* ------------------------------------------------------------- */ -static void pe_build_reloc (struct pe_info *pe) -{ - DWORD offset, block_ptr, addr; - int count, i; - ElfW_Rel *rel, *rel_end; - Section *s = NULL, *sr; - - offset = addr = block_ptr = count = i = 0; - rel = rel_end = NULL; - - for(;;) { - if (rel < rel_end) { - int type = ELFW(R_TYPE)(rel->r_info); - addr = rel->r_offset + s->sh_addr; - ++ rel; - if (type != REL_TYPE_DIRECT) - continue; - if (count == 0) { /* new block */ - block_ptr = pe->reloc->data_offset; - section_ptr_add(pe->reloc, sizeof(struct pe_reloc_header)); - offset = addr & 0xFFFFFFFF<<12; - } - if ((addr -= offset) < (1<<12)) { /* one block spans 4k addresses */ - WORD *wp = section_ptr_add(pe->reloc, sizeof (WORD)); - *wp = addr | IMAGE_REL_BASED_HIGHLOW<<12; - ++count; - continue; - } - -- rel; - - } else if (i < pe->sec_count) { - sr = (s = pe->s1->sections[pe->sec_info[i++].ord])->reloc; - if (sr) { - rel = (ElfW_Rel *)sr->data; - rel_end = (ElfW_Rel *)(sr->data + sr->data_offset); - } - continue; - } - - if (count) { - /* store the last block and ready for a new one */ - struct pe_reloc_header *hdr; - if (count & 1) /* align for DWORDS */ - section_ptr_add(pe->reloc, sizeof(WORD)), ++count; - hdr = (struct pe_reloc_header *)(pe->reloc->data + block_ptr); - hdr -> offset = offset - pe->imagebase; - hdr -> size = count * sizeof(WORD) + sizeof(struct pe_reloc_header); - count = 0; - } - - if (rel >= rel_end) - break; - } -} - -/* ------------------------------------------------------------- */ -static int pe_section_class(Section *s) -{ - int type, flags; - const char *name; - - type = s->sh_type; - flags = s->sh_flags; - name = s->name; - if (flags & SHF_ALLOC) { - if (type == SHT_PROGBITS) { - if (flags & SHF_EXECINSTR) - return sec_text; - if (flags & SHF_WRITE) - return sec_data; - if (0 == strcmp(name, ".rsrc")) - return sec_rsrc; - if (0 == strcmp(name, ".iedat")) - return sec_idata; - if (0 == strcmp(name, ".pdata")) - return sec_pdata; - return sec_other; - } else if (type == SHT_NOBITS) { - if (flags & SHF_WRITE) - return sec_bss; - } - } else { - if (0 == strcmp(name, ".reloc")) - return sec_reloc; - if (0 == strncmp(name, ".stab", 5)) /* .stab and .stabstr */ - return sec_stab; - } - return -1; -} - -static int pe_assign_addresses (struct pe_info *pe) -{ - int i, k, o, c; - DWORD addr; - int *section_order; - struct section_info *si; - Section *s; - - // pe->thunk = new_section(pe->s1, ".iedat", SHT_PROGBITS, SHF_ALLOC); - - section_order = tcc_malloc(pe->s1->nb_sections * sizeof (int)); - for (o = k = 0 ; k < sec_last; ++k) { - for (i = 1; i < pe->s1->nb_sections; ++i) { - s = pe->s1->sections[i]; - if (k == pe_section_class(s)) { - // printf("%s %d\n", s->name, k); - s->sh_addr = pe->imagebase; - section_order[o++] = i; - } - } - } - - pe->sec_info = tcc_mallocz(o * sizeof (struct section_info)); - addr = pe->imagebase + 1; - - for (i = 0; i < o; ++i) - { - k = section_order[i]; - s = pe->s1->sections[k]; - c = pe_section_class(s); - si = &pe->sec_info[pe->sec_count]; - -#ifdef PE_MERGE_DATA - if (c == sec_bss && pe->sec_count && si[-1].cls == sec_data) { - /* append .bss to .data */ - s->sh_addr = addr = ((addr-1) | (s->sh_addralign-1)) + 1; - addr += s->data_offset; - si[-1].sh_size = addr - si[-1].sh_addr; - continue; - } -#endif - if (c == sec_stab && 0 == pe->s1->do_debug) - continue; - - strcpy(si->name, s->name); - si->cls = c; - si->ord = k; - si->sh_addr = s->sh_addr = addr = pe_virtual_align(pe, addr); - si->sh_flags = s->sh_flags; - - if (c == sec_data && NULL == pe->thunk) - pe->thunk = s; - - if (s == pe->thunk) { - pe_build_imports(pe); - pe_build_exports(pe); - } - - if (c == sec_reloc) - pe_build_reloc (pe); - - if (s->data_offset) - { - if (s->sh_type != SHT_NOBITS) { - si->data = s->data; - si->data_size = s->data_offset; - } - - addr += s->data_offset; - si->sh_size = s->data_offset; - ++pe->sec_count; - } - // printf("%08x %05x %s\n", si->sh_addr, si->sh_size, si->name); - } - -#if 0 - for (i = 1; i < pe->s1->nb_sections; ++i) { - Section *s = pe->s1->sections[i]; - int type = s->sh_type; - int flags = s->sh_flags; - printf("section %-16s %-10s %5x %s,%s,%s\n", - s->name, - type == SHT_PROGBITS ? "progbits" : - type == SHT_NOBITS ? "nobits" : - type == SHT_SYMTAB ? "symtab" : - type == SHT_STRTAB ? "strtab" : - type == SHT_RELX ? "rel" : "???", - s->data_offset, - flags & SHF_ALLOC ? "alloc" : "", - flags & SHF_WRITE ? "write" : "", - flags & SHF_EXECINSTR ? "exec" : "" - ); - } - pe->s1->verbose = 2; -#endif - - tcc_free(section_order); - return 0; -} - -/* ------------------------------------------------------------- */ -static void pe_relocate_rva (struct pe_info *pe, Section *s) -{ - Section *sr = s->reloc; - ElfW_Rel *rel, *rel_end; - rel_end = (ElfW_Rel *)(sr->data + sr->data_offset); - for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) { - if (ELFW(R_TYPE)(rel->r_info) == R_XXX_RELATIVE) { - int sym_index = ELFW(R_SYM)(rel->r_info); - DWORD addr = s->sh_addr; - if (sym_index) { - ElfW(Sym) *sym = (ElfW(Sym) *)symtab_section->data + sym_index; - addr = sym->st_value; - } - // printf("reloc rva %08x %08x %s\n", (DWORD)rel->r_offset, addr, s->name); - *(DWORD*)(s->data + rel->r_offset) += addr - pe->imagebase; - } - } -} - -/*----------------------------------------------------------------------------*/ - -static int pe_isafunc(int sym_index) -{ - Section *sr = text_section->reloc; - ElfW_Rel *rel, *rel_end; - Elf32_Word info = ELF32_R_INFO(sym_index, R_386_PC32); - if (!sr) - return 0; - rel_end = (ElfW_Rel *)(sr->data + sr->data_offset); - for (rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) - if (rel->r_info == info) - return 1; - return 0; -} - -/*----------------------------------------------------------------------------*/ -static int pe_check_symbols(struct pe_info *pe) -{ - ElfW(Sym) *sym; - int sym_index, sym_end; - int ret = 0; - - pe_align_section(text_section, 8); - - sym_end = symtab_section->data_offset / sizeof(ElfW(Sym)); - for (sym_index = 1; sym_index < sym_end; ++sym_index) { - - sym = (ElfW(Sym) *)symtab_section->data + sym_index; - if (sym->st_shndx == SHN_UNDEF) { - - const char *name = symtab_section->link->data + sym->st_name; - unsigned type = ELFW(ST_TYPE)(sym->st_info); - int imp_sym = pe_find_import(pe->s1, sym); - struct import_symbol *is; - - if (0 == imp_sym) - goto not_found; - - if (type == STT_NOTYPE) { - /* symbols from assembler have no type, find out which */ - if (pe_isafunc(sym_index)) - type = STT_FUNC; - else - type = STT_OBJECT; - } - - is = pe_add_import(pe, imp_sym); - - if (type == STT_FUNC) { - unsigned long offset = is->thk_offset; - if (offset) { - /* got aliased symbol, like stricmp and _stricmp */ - - } else { - char buffer[100]; - WORD *p; - - offset = text_section->data_offset; - /* add the 'jmp IAT[x]' instruction */ -#ifdef TCC_TARGET_ARM - p = section_ptr_add(text_section, 8+4); // room for code and address - (*(DWORD*)(p)) = 0xE59FC000; // arm code ldr ip, [pc] ; PC+8+0 = 0001xxxx - (*(DWORD*)(p+2)) = 0xE59CF000; // arm code ldr pc, [ip] -#else - p = section_ptr_add(text_section, 8); - *p = 0x25FF; -#ifdef TCC_TARGET_X86_64 - *(DWORD*)(p+1) = (DWORD)-4; -#endif -#endif - /* add a helper symbol, will be patched later in - pe_build_imports */ - sprintf(buffer, "IAT.%s", name); - is->iat_index = put_elf_sym( - symtab_section, 0, sizeof(DWORD), - ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT), - 0, SHN_UNDEF, buffer); -#ifdef TCC_TARGET_ARM - put_elf_reloc(symtab_section, text_section, - offset + 8, R_XXX_THUNKFIX, is->iat_index); // offset to IAT position -#else - put_elf_reloc(symtab_section, text_section, - offset + 2, R_XXX_THUNKFIX, is->iat_index); -#endif - is->thk_offset = offset; - } - - /* tcc_realloc might have altered sym's address */ - sym = (ElfW(Sym) *)symtab_section->data + sym_index; - - /* patch the original symbol */ - sym->st_value = offset; - sym->st_shndx = text_section->sh_num; - sym->st_other &= ~ST_PE_EXPORT; /* do not export */ - continue; - } - - if (type == STT_OBJECT) { /* data, ptr to that should be */ - if (0 == is->iat_index) { - /* original symbol will be patched later in pe_build_imports */ - is->iat_index = sym_index; - continue; - } - } - - not_found: - tcc_error_noabort("undefined symbol '%s'", name); - ret = -1; - - } else if (pe->s1->rdynamic - && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { - /* if -rdynamic option, then export all non local symbols */ - sym->st_other |= ST_PE_EXPORT; - } - } - return ret; -} - -/*----------------------------------------------------------------------------*/ -#ifdef PE_PRINT_SECTIONS -static void pe_print_section(FILE * f, Section * s) -{ - /* just if you'r curious */ - BYTE *p, *e, b; - int i, n, l, m; - p = s->data; - e = s->data + s->data_offset; - l = e - p; - - fprintf(f, "section \"%s\"", s->name); - if (s->link) - fprintf(f, "\nlink \"%s\"", s->link->name); - if (s->reloc) - fprintf(f, "\nreloc \"%s\"", s->reloc->name); - fprintf(f, "\nv_addr %08X", (unsigned)s->sh_addr); - fprintf(f, "\ncontents %08X", (unsigned)l); - fprintf(f, "\n\n"); - - if (s->sh_type == SHT_NOBITS) - return; - - if (0 == l) - return; - - if (s->sh_type == SHT_SYMTAB) - m = sizeof(ElfW(Sym)); - else if (s->sh_type == SHT_RELX) - m = sizeof(ElfW_Rel); - else - m = 16; - - fprintf(f, "%-8s", "offset"); - for (i = 0; i < m; ++i) - fprintf(f, " %02x", i); - n = 56; - - if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_RELX) { - const char *fields1[] = { - "name", - "value", - "size", - "bind", - "type", - "other", - "shndx", - NULL - }; - - const char *fields2[] = { - "offs", - "type", - "symb", - NULL - }; - - const char **p; - - if (s->sh_type == SHT_SYMTAB) - p = fields1, n = 106; - else - p = fields2, n = 58; - - for (i = 0; p[i]; ++i) - fprintf(f, "%6s", p[i]); - fprintf(f, " symbol"); - } - - fprintf(f, "\n"); - for (i = 0; i < n; ++i) - fprintf(f, "-"); - fprintf(f, "\n"); - - for (i = 0; i < l;) - { - fprintf(f, "%08X", i); - for (n = 0; n < m; ++n) { - if (n + i < l) - fprintf(f, " %02X", p[i + n]); - else - fprintf(f, " "); - } - - if (s->sh_type == SHT_SYMTAB) { - ElfW(Sym) *sym = (ElfW(Sym) *) (p + i); - const char *name = s->link->data + sym->st_name; - fprintf(f, " %04X %04X %04X %02X %02X %02X %04X \"%s\"", - (unsigned)sym->st_name, - (unsigned)sym->st_value, - (unsigned)sym->st_size, - (unsigned)ELFW(ST_BIND)(sym->st_info), - (unsigned)ELFW(ST_TYPE)(sym->st_info), - (unsigned)sym->st_other, - (unsigned)sym->st_shndx, - name); - - } else if (s->sh_type == SHT_RELX) { - ElfW_Rel *rel = (ElfW_Rel *) (p + i); - ElfW(Sym) *sym = - (ElfW(Sym) *) s->link->data + ELFW(R_SYM)(rel->r_info); - const char *name = s->link->link->data + sym->st_name; - fprintf(f, " %04X %02X %04X \"%s\"", - (unsigned)rel->r_offset, - (unsigned)ELFW(R_TYPE)(rel->r_info), - (unsigned)ELFW(R_SYM)(rel->r_info), - name); - } else { - fprintf(f, " "); - for (n = 0; n < m; ++n) { - if (n + i < l) { - b = p[i + n]; - if (b < 32 || b >= 127) - b = '.'; - fprintf(f, "%c", b); - } - } - } - i += m; - fprintf(f, "\n"); - } - fprintf(f, "\n\n"); -} - -static void pe_print_sections(TCCState *s1, const char *fname) -{ - Section *s; - FILE *f; - int i; - f = fopen(fname, "w"); - for (i = 1; i < s1->nb_sections; ++i) { - s = s1->sections[i]; - pe_print_section(f, s); - } - pe_print_section(f, s1->dynsymtab_section); - fclose(f); -} -#endif - -/* ------------------------------------------------------------- */ -/* helper function for load/store to insert one more indirection */ - -ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2) -{ - Sym *sym; - ElfW(Sym) *esym; - int r2; - - if ((sv->r & (VT_VALMASK|VT_SYM)) != (VT_CONST|VT_SYM) || (sv->r2 != VT_CONST)) - return sv; - sym = sv->sym; - if ((sym->type.t & (VT_EXTERN|VT_STATIC)) != VT_EXTERN) - return sv; - if (!sym->c) - put_extern_sym(sym, NULL, 0, 0); - esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; - if (!(esym->st_other & ST_PE_IMPORT)) - return sv; - - // printf("import %04x %04x %04x %s\n", sv->type.t, sym->type.t, sv->r, get_tok_str(sv->sym->v, NULL)); - - memset(v2, 0, sizeof *v2); - v2->type.t = VT_PTR; - v2->r = VT_CONST | VT_SYM | VT_LVAL; - v2->sym = sv->sym; - - r2 = get_reg(RC_INT); - load(r2, v2); - v2->r = r2; - - if ((uint32_t)sv->c.i) { - vpushv(v2); - vpushi(sv->c.i); - gen_opi('+'); - *v2 = *vtop--; - } - - v2->type.t = sv->type.t; - v2->r |= sv->r & VT_LVAL; - return v2; -} - -ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value) -{ - return add_elf_sym( - s1->dynsymtab_section, - value, - dllindex, /* st_size */ - ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), - 0, - value ? SHN_ABS : SHN_UNDEF, - name - ); -} - -static int add_dllref(TCCState *s1, const char *dllname) -{ - DLLReference *dllref; - int i; - for (i = 0; i < s1->nb_loaded_dlls; ++i) - if (0 == strcmp(s1->loaded_dlls[i]->name, dllname)) - return i + 1; - dllref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname)); - strcpy(dllref->name, dllname); - dynarray_add((void ***) &s1->loaded_dlls, &s1->nb_loaded_dlls, dllref); - return s1->nb_loaded_dlls; -} - -/* ------------------------------------------------------------- */ - -static int read_mem(int fd, unsigned offset, void *buffer, unsigned len) -{ - lseek(fd, offset, SEEK_SET); - return len == read(fd, buffer, len); -} - -/* ------------------------------------------------------------- - * This is for compiled windows resources in 'coff' format - * as generated by 'windres.exe -O coff ...'. - */ - -static int pe_load_res(TCCState *s1, int fd) -{ - struct pe_rsrc_header hdr; - Section *rsrc_section; - int i, ret = -1; - BYTE *ptr; - unsigned offs; - - if (!read_mem(fd, 0, &hdr, sizeof hdr)) - goto quit; - - if (hdr.filehdr.Machine != IMAGE_FILE_MACHINE - || hdr.filehdr.NumberOfSections != 1 - || strcmp(hdr.sectionhdr.Name, ".rsrc") != 0) - goto quit; - - rsrc_section = new_section(s1, ".rsrc", SHT_PROGBITS, SHF_ALLOC); - ptr = section_ptr_add(rsrc_section, hdr.sectionhdr.SizeOfRawData); - offs = hdr.sectionhdr.PointerToRawData; - if (!read_mem(fd, offs, ptr, hdr.sectionhdr.SizeOfRawData)) - goto quit; - offs = hdr.sectionhdr.PointerToRelocations; - for (i = 0; i < hdr.sectionhdr.NumberOfRelocations; ++i) - { - struct pe_rsrc_reloc rel; - if (!read_mem(fd, offs, &rel, sizeof rel)) - goto quit; - // printf("rsrc_reloc: %x %x %x\n", rel.offset, rel.size, rel.type); - if (rel.type != RSRC_RELTYPE) - goto quit; - put_elf_reloc(symtab_section, rsrc_section, - rel.offset, R_XXX_RELATIVE, 0); - offs += sizeof rel; - } - ret = 0; -quit: - return ret; -} - -/* ------------------------------------------------------------- */ -static char *trimfront(char *p) -{ - while (*p && (unsigned char)*p <= ' ') - ++p; - return p; -} - -static char *trimback(char *a, char *e) -{ - while (e > a && (unsigned char)e[-1] <= ' ') - --e; - *e = 0;; - return a; -} - -/* ------------------------------------------------------------- */ -static int pe_load_def(TCCState *s1, int fd) -{ - int state = 0, ret = -1, dllindex = 0, ord; - char line[400], dllname[80], *p, *x; - FILE *fp; - - fp = fdopen(dup(fd), "rb"); - while (fgets(line, sizeof line, fp)) - { - p = trimfront(trimback(line, strchr(line, 0))); - if (0 == *p || ';' == *p) - continue; - - switch (state) { - case 0: - if (0 != strnicmp(p, "LIBRARY", 7)) - goto quit; - pstrcpy(dllname, sizeof dllname, trimfront(p+7)); - ++state; - continue; - - case 1: - if (0 != stricmp(p, "EXPORTS")) - goto quit; - ++state; - continue; - - case 2: - dllindex = add_dllref(s1, dllname); - ++state; - /* fall through */ - default: - /* get ordinal and will store in sym->st_value */ - ord = 0; - x = strchr(p, ' '); - if (x) { - *x = 0, x = strrchr(x + 1, '@'); - if (x) { - char *d; - ord = (int)strtol(x + 1, &d, 10); - if (*d) - ord = 0; - } - } - pe_putimport(s1, dllindex, p, ord); - continue; - } - } - ret = 0; -quit: - fclose(fp); - return ret; -} - -/* ------------------------------------------------------------- */ -#define TINY_IMPDEF_GET_EXPORT_NAMES_ONLY -#include "win32/tools/tiny_impdef.c" - -static int pe_load_dll(TCCState *s1, const char *dllname, int fd) -{ - char *p, *q; - int index; - p = get_export_names(fd); - if (!p) - return -1; - index = add_dllref(s1, dllname); - for (q = p; *q; q += 1 + strlen(q)) - pe_putimport(s1, index, q, 0); - tcc_free(p); - return 0; -} - -/* ------------------------------------------------------------- */ -ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd) -{ - int ret = -1; - char buf[10]; - if (0 == strcmp(tcc_fileextension(filename), ".def")) - ret = pe_load_def(s1, fd); - else if (pe_load_res(s1, fd) == 0) - ret = 0; - else if (read_mem(fd, 0, buf, sizeof buf) && 0 == strncmp(buf, "MZ", 2)) - ret = pe_load_dll(s1, tcc_basename(filename), fd); - return ret; -} - -/* ------------------------------------------------------------- */ -#ifdef TCC_TARGET_X86_64 -static unsigned pe_add_uwwind_info(TCCState *s1) -{ - if (NULL == s1->uw_pdata) { - s1->uw_pdata = find_section(tcc_state, ".pdata"); - s1->uw_pdata->sh_addralign = 4; - s1->uw_sym = put_elf_sym(symtab_section, 0, 0, 0, 0, text_section->sh_num, NULL); - } - - if (0 == s1->uw_offs) { - /* As our functions all have the same stackframe, we use one entry for all */ - static const unsigned char uw_info[] = { - 0x01, // UBYTE: 3 Version , UBYTE: 5 Flags - 0x04, // UBYTE Size of prolog - 0x02, // UBYTE Count of unwind codes - 0x05, // UBYTE: 4 Frame Register (rbp), UBYTE: 4 Frame Register offset (scaled) - // USHORT * n Unwind codes array - // 0x0b, 0x01, 0xff, 0xff, // stack size - 0x04, 0x03, // set frame ptr (mov rsp -> rbp) - 0x01, 0x50 // push reg (rbp) - }; - - Section *s = text_section; - unsigned char *p; - - section_ptr_add(s, -s->data_offset & 3); /* align */ - s1->uw_offs = s->data_offset; - p = section_ptr_add(s, sizeof uw_info); - memcpy(p, uw_info, sizeof uw_info); - } - - return s1->uw_offs; -} - -ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack) -{ - TCCState *s1 = tcc_state; - Section *pd; - unsigned o, n, d; - struct /* _RUNTIME_FUNCTION */ { - DWORD BeginAddress; - DWORD EndAddress; - DWORD UnwindData; - } *p; - - d = pe_add_uwwind_info(s1); - pd = s1->uw_pdata; - o = pd->data_offset; - p = section_ptr_add(pd, sizeof *p); - - /* record this function */ - p->BeginAddress = start; - p->EndAddress = end; - p->UnwindData = d; - - /* put relocations on it */ - for (n = o + sizeof *p; o < n; o += sizeof p->BeginAddress) - put_elf_reloc(symtab_section, pd, o, R_X86_64_RELATIVE, s1->uw_sym); -} -#endif -/* ------------------------------------------------------------- */ -#ifdef TCC_TARGET_X86_64 -#define PE_STDSYM(n,s) n -#else -#define PE_STDSYM(n,s) "_" n s -#endif - -static void pe_add_runtime(TCCState *s1, struct pe_info *pe) -{ - const char *start_symbol; - int pe_type = 0; - - if (find_elf_sym(symtab_section, PE_STDSYM("WinMain","@16"))) - pe_type = PE_GUI; - else - if (TCC_OUTPUT_DLL == s1->output_type) { - pe_type = PE_DLL; - /* need this for 'tccelf.c:relocate_section()' */ - s1->output_type = TCC_OUTPUT_EXE; - } - else - pe_type = PE_EXE; - - start_symbol = - TCC_OUTPUT_MEMORY == s1->output_type - ? PE_GUI == pe_type ? "__runwinmain" : "_main" - : PE_DLL == pe_type ? PE_STDSYM("__dllstart","@12") - : PE_GUI == pe_type ? "__winstart" : "__start" - ; - - if (!s1->leading_underscore || strchr(start_symbol, '@')) - ++start_symbol; - - /* grab the startup code from libtcc1 */ - if (TCC_OUTPUT_MEMORY != s1->output_type || PE_GUI == pe_type) - add_elf_sym(symtab_section, - 0, 0, - ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, - SHN_UNDEF, start_symbol); - - tcc_add_pragma_libs(s1); - - if (0 == s1->nostdlib) { - static const char *libs[] = { - "tcc1", "msvcrt", "kernel32", "", "user32", "gdi32", NULL - }; - const char **pp, *p; - for (pp = libs; 0 != (p = *pp); ++pp) { - if (0 == *p) { - if (PE_DLL != pe_type && PE_GUI != pe_type) - break; - } else if (tcc_add_library_err(s1, p) < 0) { - break; - } - } - } - - if (TCC_OUTPUT_MEMORY == s1->output_type) { - pe_type = PE_RUN; -#ifdef TCC_IS_NATIVE - s1->runtime_main = start_symbol; -#endif - } else { - pe->start_addr = (DWORD)(uintptr_t)tcc_get_symbol_err(s1, start_symbol); - } - - pe->type = pe_type; -} - -ST_FUNC int pe_output_file(TCCState * s1, const char *filename) -{ - int ret; - struct pe_info pe; - int i; - - memset(&pe, 0, sizeof pe); - pe.filename = filename; - pe.s1 = s1; - - pe_add_runtime(s1, &pe); - tcc_add_bcheck(s1); - relocate_common_syms(); /* assign bss adresses */ - tcc_add_linker_symbols(s1); - - ret = pe_check_symbols(&pe); - if (ret) - ; - else if (filename) { - if (PE_DLL == pe.type) { - pe.reloc = new_section(pe.s1, ".reloc", SHT_PROGBITS, 0); - /* XXX: check if is correct for arm-pe target */ - pe.imagebase = 0x10000000; - } else { -#if defined(TCC_TARGET_ARM) - pe.imagebase = 0x00010000; -#else - pe.imagebase = 0x00400000; -#endif - } - -#if defined(TCC_TARGET_ARM) - /* we use "console" subsystem by default */ - pe.subsystem = 9; -#else - if (PE_DLL == pe.type || PE_GUI == pe.type) - pe.subsystem = 2; - else - pe.subsystem = 3; -#endif - /* Allow override via -Wl,-subsystem=... option */ - if (s1->pe_subsystem != 0) - pe.subsystem = s1->pe_subsystem; - - /* set default file/section alignment */ - if (pe.subsystem == 1) { - pe.section_align = 0x20; - pe.file_align = 0x20; - } else { - pe.section_align = 0x1000; - pe.file_align = 0x200; - } - - if (s1->section_align != 0) - pe.section_align = s1->section_align; - if (s1->pe_file_align != 0) - pe.file_align = s1->pe_file_align; - - if ((pe.subsystem >= 10) && (pe.subsystem <= 12)) - pe.imagebase = 0; - - if (s1->has_text_addr) - pe.imagebase = s1->text_addr; - - pe_assign_addresses(&pe); - relocate_syms(s1, 0); - for (i = 1; i < s1->nb_sections; ++i) { - Section *s = s1->sections[i]; - if (s->reloc) { - relocate_section(s1, s); - pe_relocate_rva(&pe, s); - } - } - if (s1->nb_errors) - ret = -1; - else - ret = pe_write(&pe); - tcc_free(pe.sec_info); - } else { -#ifdef TCC_IS_NATIVE - pe.thunk = data_section; - pe_build_imports(&pe); -#endif - } - -#ifdef PE_PRINT_SECTIONS - pe_print_sections(s1, "tcc.log"); -#endif - return ret; -} - -/* ------------------------------------------------------------- */ diff --git a/external/TCC/tccpp.c b/external/TCC/tccpp.c deleted file mode 100644 index 2c276c28..00000000 --- a/external/TCC/tccpp.c +++ /dev/null @@ -1,3460 +0,0 @@ -/* - * TCC - Tiny C Compiler - * - * Copyright (c) 2001-2004 Fabrice Bellard - * - * 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "tcc.h" - -/********************************************************/ -/* global variables */ - -ST_DATA int tok_flags; -ST_DATA int parse_flags; - -ST_DATA struct BufferedFile *file; -ST_DATA int ch, tok; -ST_DATA CValue tokc; -ST_DATA const int *macro_ptr; -ST_DATA CString tokcstr; /* current parsed string, if any */ - -/* display benchmark infos */ -ST_DATA int total_lines; -ST_DATA int total_bytes; -ST_DATA int tok_ident; -ST_DATA TokenSym **table_ident; - -/* ------------------------------------------------------------------------- */ - -static TokenSym *hash_ident[TOK_HASH_SIZE]; -static char token_buf[STRING_MAX_SIZE + 1]; -static unsigned char isidnum_table[256 - CH_EOF]; -/* isidnum_table flags: */ -#define IS_SPC 1 -#define IS_ID 2 -#define IS_NUM 4 - -static TokenString *macro_stack; - -static const char tcc_keywords[] = -#define DEF(id, str) str "\0" -#include "tcctok.h" -#undef DEF -; - -/* WARNING: the content of this string encodes token numbers */ -static const unsigned char tok_two_chars[] = -/* outdated -- gr - "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253" - "-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266"; -*/{ - '<','=', TOK_LE, - '>','=', TOK_GE, - '!','=', TOK_NE, - '&','&', TOK_LAND, - '|','|', TOK_LOR, - '+','+', TOK_INC, - '-','-', TOK_DEC, - '=','=', TOK_EQ, - '<','<', TOK_SHL, - '>','>', TOK_SAR, - '+','=', TOK_A_ADD, - '-','=', TOK_A_SUB, - '*','=', TOK_A_MUL, - '/','=', TOK_A_DIV, - '%','=', TOK_A_MOD, - '&','=', TOK_A_AND, - '^','=', TOK_A_XOR, - '|','=', TOK_A_OR, - '-','>', TOK_ARROW, - '.','.', 0xa8, // C++ token ? - '#','#', TOK_TWOSHARPS, - 0 -}; - -static void next_nomacro_spc(void); - -ST_FUNC void skip(int c) -{ - if (tok != c) - tcc_error("'%c' expected (got \"%s\")", c, get_tok_str(tok, &tokc)); - next(); -} - -ST_FUNC void expect(const char *msg) -{ - tcc_error("%s expected", msg); -} - -ST_FUNC void begin_macro(TokenString *str, int alloc) -{ - str->alloc = alloc; - str->prev = macro_stack; - str->prev_ptr = macro_ptr; - macro_ptr = str->str; - macro_stack = str; -} - -ST_FUNC void end_macro(void) -{ - TokenString *str = macro_stack; - macro_stack = str->prev; - macro_ptr = str->prev_ptr; - if (str->alloc == 2) { - str->alloc = 3; /* just mark as finished */ - } else { - tok_str_free(str->str); - if (str->alloc == 1) - tcc_free(str); - } -} - -/* ------------------------------------------------------------------------- */ -/* CString handling */ -static void cstr_realloc(CString *cstr, int new_size) -{ - int size; - void *data; - - size = cstr->size_allocated; - if (size == 0) - size = 8; /* no need to allocate a too small first string */ - while (size < new_size) - size = size * 2; - data = tcc_realloc(cstr->data_allocated, size); - cstr->data_allocated = data; - cstr->size_allocated = size; - cstr->data = data; -} - -/* add a byte */ -ST_FUNC void cstr_ccat(CString *cstr, int ch) -{ - int size; - size = cstr->size + 1; - if (size > cstr->size_allocated) - cstr_realloc(cstr, size); - ((unsigned char *)cstr->data)[size - 1] = ch; - cstr->size = size; -} - -ST_FUNC void cstr_cat(CString *cstr, const char *str) -{ - int c; - for(;;) { - c = *str; - if (c == '\0') - break; - cstr_ccat(cstr, c); - str++; - } -} - -/* add a wide char */ -ST_FUNC void cstr_wccat(CString *cstr, int ch) -{ - int size; - size = cstr->size + sizeof(nwchar_t); - if (size > cstr->size_allocated) - cstr_realloc(cstr, size); - *(nwchar_t *)(((unsigned char *)cstr->data) + size - sizeof(nwchar_t)) = ch; - cstr->size = size; -} - -ST_FUNC void cstr_new(CString *cstr) -{ - memset(cstr, 0, sizeof(CString)); -} - -/* free string and reset it to NULL */ -ST_FUNC void cstr_free(CString *cstr) -{ - tcc_free(cstr->data_allocated); - cstr_new(cstr); -} - -/* reset string to empty */ -ST_FUNC void cstr_reset(CString *cstr) -{ - cstr->size = 0; -} - -/* XXX: unicode ? */ -static void add_char(CString *cstr, int c) -{ - if (c == '\'' || c == '\"' || c == '\\') { - /* XXX: could be more precise if char or string */ - cstr_ccat(cstr, '\\'); - } - if (c >= 32 && c <= 126) { - cstr_ccat(cstr, c); - } else { - cstr_ccat(cstr, '\\'); - if (c == '\n') { - cstr_ccat(cstr, 'n'); - } else { - cstr_ccat(cstr, '0' + ((c >> 6) & 7)); - cstr_ccat(cstr, '0' + ((c >> 3) & 7)); - cstr_ccat(cstr, '0' + (c & 7)); - } - } -} - -/* ------------------------------------------------------------------------- */ -/* allocate a new token */ -static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len) -{ - TokenSym *ts, **ptable; - int i; - - if (tok_ident >= SYM_FIRST_ANOM) - tcc_error("memory full (symbols)"); - - /* expand token table if needed */ - i = tok_ident - TOK_IDENT; - if ((i % TOK_ALLOC_INCR) == 0) { - ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *)); - table_ident = ptable; - } - - ts = tcc_malloc(sizeof(TokenSym) + len); - table_ident[i] = ts; - ts->tok = tok_ident++; - ts->sym_define = NULL; - ts->sym_label = NULL; - ts->sym_struct = NULL; - ts->sym_identifier = NULL; - ts->len = len; - ts->hash_next = NULL; - memcpy(ts->str, str, len); - ts->str[len] = '\0'; - *pts = ts; - return ts; -} - -#define TOK_HASH_INIT 1 -#define TOK_HASH_FUNC(h, c) ((h) * 263 + (c)) - -/* find a token and add it if not found */ -ST_FUNC TokenSym *tok_alloc(const char *str, int len) -{ - TokenSym *ts, **pts; - int i; - unsigned int h; - - h = TOK_HASH_INIT; - for(i=0;ilen == len && !memcmp(ts->str, str, len)) - return ts; - pts = &(ts->hash_next); - } - return tok_alloc_new(pts, str, len); -} - -/* XXX: buffer overflow */ -/* XXX: float tokens */ -ST_FUNC const char *get_tok_str(int v, CValue *cv) -{ - static CString cstr_buf; - char *p; - int i, len; - - /* first time preallocate static cstr_buf, next time only reset position to start */ - if (!cstr_buf.data_allocated) - cstr_realloc(&cstr_buf, STRING_MAX_SIZE); - else - cstr_buf.size = 0; - p = cstr_buf.data; - - switch(v) { - case TOK_CINT: - case TOK_CUINT: - /* XXX: not quite exact, but only useful for testing */ - sprintf(p, "%llu", (unsigned long long)cv->i); - break; - case TOK_CLLONG: - case TOK_CULLONG: - /* XXX: not quite exact, but only useful for testing */ -#ifdef _WIN32 - sprintf(p, "%u", (unsigned)cv->i); -#else - sprintf(p, "%llu", (unsigned long long)cv->i); -#endif - break; - case TOK_LCHAR: - cstr_ccat(&cstr_buf, 'L'); - case TOK_CCHAR: - cstr_ccat(&cstr_buf, '\''); - add_char(&cstr_buf, cv->i); - cstr_ccat(&cstr_buf, '\''); - cstr_ccat(&cstr_buf, '\0'); - break; - case TOK_PPNUM: - case TOK_PPSTR: - return (char*)cv->str.data; - case TOK_LSTR: - cstr_ccat(&cstr_buf, 'L'); - case TOK_STR: - cstr_ccat(&cstr_buf, '\"'); - if (v == TOK_STR) { - len = cv->str.size - 1; - for(i=0;istr.data)[i]); - } else { - len = (cv->str.size / sizeof(nwchar_t)) - 1; - for(i=0;istr.data)[i]); - } - cstr_ccat(&cstr_buf, '\"'); - cstr_ccat(&cstr_buf, '\0'); - break; - - case TOK_CFLOAT: - cstr_cat(&cstr_buf, ""); - cstr_ccat(&cstr_buf, '\0'); - break; - case TOK_CDOUBLE: - cstr_cat(&cstr_buf, ""); - cstr_ccat(&cstr_buf, '\0'); - break; - case TOK_CLDOUBLE: - cstr_cat(&cstr_buf, ""); - cstr_ccat(&cstr_buf, '\0'); - break; - case TOK_LINENUM: - cstr_cat(&cstr_buf, ""); - cstr_ccat(&cstr_buf, '\0'); - break; - - /* above tokens have value, the ones below don't */ - - case TOK_LT: - v = '<'; - goto addv; - case TOK_GT: - v = '>'; - goto addv; - case TOK_DOTS: - return strcpy(p, "..."); - case TOK_A_SHL: - return strcpy(p, "<<="); - case TOK_A_SAR: - return strcpy(p, ">>="); - default: - if (v < TOK_IDENT) { - /* search in two bytes table */ - const unsigned char *q = tok_two_chars; - while (*q) { - if (q[2] == v) { - *p++ = q[0]; - *p++ = q[1]; - *p = '\0'; - return cstr_buf.data; - } - q += 3; - } - if (v >= 127) { - sprintf(cstr_buf.data, "<%02x>", v); - return cstr_buf.data; - } - addv: - *p++ = v; - *p = '\0'; - } else if (v < tok_ident) { - return table_ident[v - TOK_IDENT]->str; - } else if (v >= SYM_FIRST_ANOM) { - /* special name for anonymous symbol */ - sprintf(p, "L.%u", v - SYM_FIRST_ANOM); - } else { - /* should never happen */ - return NULL; - } - break; - } - return cstr_buf.data; -} - -/* return the current character, handling end of block if necessary - (but not stray) */ -ST_FUNC int handle_eob(void) -{ - BufferedFile *bf = file; - int len; - - /* only tries to read if really end of buffer */ - if (bf->buf_ptr >= bf->buf_end) { - if (bf->fd != -1) { -#if defined(PARSE_DEBUG) - len = 1; -#else - len = IO_BUF_SIZE; -#endif - len = read(bf->fd, bf->buffer, len); - if (len < 0) - len = 0; - } else { - len = 0; - } - total_bytes += len; - bf->buf_ptr = bf->buffer; - bf->buf_end = bf->buffer + len; - *bf->buf_end = CH_EOB; - } - if (bf->buf_ptr < bf->buf_end) { - return bf->buf_ptr[0]; - } else { - bf->buf_ptr = bf->buf_end; - return CH_EOF; - } -} - -/* read next char from current input file and handle end of input buffer */ -ST_INLN void inp(void) -{ - ch = *(++(file->buf_ptr)); - /* end of buffer/file handling */ - if (ch == CH_EOB) - ch = handle_eob(); -} - -/* handle '\[\r]\n' */ -static int handle_stray_noerror(void) -{ - while (ch == '\\') { - inp(); - if (ch == '\n') { - file->line_num++; - inp(); - } else if (ch == '\r') { - inp(); - if (ch != '\n') - goto fail; - file->line_num++; - inp(); - } else { - fail: - return 1; - } - } - return 0; -} - -static void handle_stray(void) -{ - if (handle_stray_noerror()) - tcc_error("stray '\\' in program"); -} - -/* skip the stray and handle the \\n case. Output an error if - incorrect char after the stray */ -static int handle_stray1(uint8_t *p) -{ - int c; - - file->buf_ptr = p; - if (p >= file->buf_end) { - c = handle_eob(); - if (c != '\\') - return c; - p = file->buf_ptr; - } - ch = *p; - if (handle_stray_noerror()) { - if (!(parse_flags & PARSE_FLAG_ACCEPT_STRAYS)) - tcc_error("stray '\\' in program"); - *--file->buf_ptr = '\\'; - } - p = file->buf_ptr; - c = *p; - return c; -} - -/* handle just the EOB case, but not stray */ -#define PEEKC_EOB(c, p)\ -{\ - p++;\ - c = *p;\ - if (c == '\\') {\ - file->buf_ptr = p;\ - c = handle_eob();\ - p = file->buf_ptr;\ - }\ -} - -/* handle the complicated stray case */ -#define PEEKC(c, p)\ -{\ - p++;\ - c = *p;\ - if (c == '\\') {\ - c = handle_stray1(p);\ - p = file->buf_ptr;\ - }\ -} - -/* input with '\[\r]\n' handling. Note that this function cannot - handle other characters after '\', so you cannot call it inside - strings or comments */ -ST_FUNC void minp(void) -{ - inp(); - if (ch == '\\') - handle_stray(); -} - - -/* single line C++ comments */ -static uint8_t *parse_line_comment(uint8_t *p) -{ - int c; - - p++; - for(;;) { - c = *p; - redo: - if (c == '\n' || c == CH_EOF) { - break; - } else if (c == '\\') { - file->buf_ptr = p; - c = handle_eob(); - p = file->buf_ptr; - if (c == '\\') { - PEEKC_EOB(c, p); - if (c == '\n') { - file->line_num++; - PEEKC_EOB(c, p); - } else if (c == '\r') { - PEEKC_EOB(c, p); - if (c == '\n') { - file->line_num++; - PEEKC_EOB(c, p); - } - } - } else { - goto redo; - } - } else { - p++; - } - } - return p; -} - -/* C comments */ -ST_FUNC uint8_t *parse_comment(uint8_t *p) -{ - int c; - - p++; - for(;;) { - /* fast skip loop */ - for(;;) { - c = *p; - if (c == '\n' || c == '*' || c == '\\') - break; - p++; - c = *p; - if (c == '\n' || c == '*' || c == '\\') - break; - p++; - } - /* now we can handle all the cases */ - if (c == '\n') { - file->line_num++; - p++; - } else if (c == '*') { - p++; - for(;;) { - c = *p; - if (c == '*') { - p++; - } else if (c == '/') { - goto end_of_comment; - } else if (c == '\\') { - file->buf_ptr = p; - c = handle_eob(); - p = file->buf_ptr; - if (c == CH_EOF) - tcc_error("unexpected end of file in comment"); - if (c == '\\') { - /* skip '\[\r]\n', otherwise just skip the stray */ - while (c == '\\') { - PEEKC_EOB(c, p); - if (c == '\n') { - file->line_num++; - PEEKC_EOB(c, p); - } else if (c == '\r') { - PEEKC_EOB(c, p); - if (c == '\n') { - file->line_num++; - PEEKC_EOB(c, p); - } - } else { - goto after_star; - } - } - } - } else { - break; - } - } - after_star: ; - } else { - /* stray, eob or eof */ - file->buf_ptr = p; - c = handle_eob(); - p = file->buf_ptr; - if (c == CH_EOF) { - tcc_error("unexpected end of file in comment"); - } else if (c == '\\') { - p++; - } - } - } - end_of_comment: - p++; - return p; -} - -#define cinp minp - -static inline void skip_spaces(void) -{ - while (isidnum_table[ch - CH_EOF] & IS_SPC) - cinp(); -} - -static inline int check_space(int t, int *spc) -{ - if (t < 256 && (isidnum_table[t - CH_EOF] & IS_SPC)) { - if (*spc) - return 1; - *spc = 1; - } else - *spc = 0; - return 0; -} - -/* parse a string without interpreting escapes */ -static uint8_t *parse_pp_string(uint8_t *p, - int sep, CString *str) -{ - int c; - p++; - for(;;) { - c = *p; - if (c == sep) { - break; - } else if (c == '\\') { - file->buf_ptr = p; - c = handle_eob(); - p = file->buf_ptr; - if (c == CH_EOF) { - unterminated_string: - /* XXX: indicate line number of start of string */ - tcc_error("missing terminating %c character", sep); - } else if (c == '\\') { - /* escape : just skip \[\r]\n */ - PEEKC_EOB(c, p); - if (c == '\n') { - file->line_num++; - p++; - } else if (c == '\r') { - PEEKC_EOB(c, p); - if (c != '\n') - expect("'\n' after '\r'"); - file->line_num++; - p++; - } else if (c == CH_EOF) { - goto unterminated_string; - } else { - if (str) { - cstr_ccat(str, '\\'); - cstr_ccat(str, c); - } - p++; - } - } - } else if (c == '\n') { - file->line_num++; - goto add_char; - } else if (c == '\r') { - PEEKC_EOB(c, p); - if (c != '\n') { - if (str) - cstr_ccat(str, '\r'); - } else { - file->line_num++; - goto add_char; - } - } else { - add_char: - if (str) - cstr_ccat(str, c); - p++; - } - } - p++; - return p; -} - -/* skip block of text until #else, #elif or #endif. skip also pairs of - #if/#endif */ -static void preprocess_skip(void) -{ - int a, start_of_line, c, in_warn_or_error; - uint8_t *p; - - p = file->buf_ptr; - a = 0; -redo_start: - start_of_line = 1; - in_warn_or_error = 0; - for(;;) { - redo_no_start: - c = *p; - switch(c) { - case ' ': - case '\t': - case '\f': - case '\v': - case '\r': - p++; - goto redo_no_start; - case '\n': - file->line_num++; - p++; - goto redo_start; - case '\\': - file->buf_ptr = p; - c = handle_eob(); - if (c == CH_EOF) { - expect("#endif"); - } else if (c == '\\') { - ch = file->buf_ptr[0]; - handle_stray_noerror(); - } - p = file->buf_ptr; - goto redo_no_start; - /* skip strings */ - case '\"': - case '\'': - if (in_warn_or_error) - goto _default; - p = parse_pp_string(p, c, NULL); - break; - /* skip comments */ - case '/': - if (in_warn_or_error) - goto _default; - file->buf_ptr = p; - ch = *p; - minp(); - p = file->buf_ptr; - if (ch == '*') { - p = parse_comment(p); - } else if (ch == '/') { - p = parse_line_comment(p); - } - break; - case '#': - p++; - if (start_of_line) { - file->buf_ptr = p; - next_nomacro(); - p = file->buf_ptr; - if (a == 0 && - (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF)) - goto the_end; - if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF) - a++; - else if (tok == TOK_ENDIF) - a--; - else if( tok == TOK_ERROR || tok == TOK_WARNING) - in_warn_or_error = 1; - else if (tok == TOK_LINEFEED) - goto redo_start; - } else if (parse_flags & PARSE_FLAG_ASM_FILE) - p = parse_line_comment(p); - break; -_default: - default: - p++; - break; - } - start_of_line = 0; - } - the_end: ; - file->buf_ptr = p; -} - -/* ParseState handling */ - -/* XXX: currently, no include file info is stored. Thus, we cannot display - accurate messages if the function or data definition spans multiple - files */ - -/* save current parse state in 's' */ -ST_FUNC void save_parse_state(ParseState *s) -{ - s->line_num = file->line_num; - s->macro_ptr = macro_ptr; - s->tok = tok; - s->tokc = tokc; -} - -/* restore parse state from 's' */ -ST_FUNC void restore_parse_state(ParseState *s) -{ - file->line_num = s->line_num; - macro_ptr = s->macro_ptr; - tok = s->tok; - tokc = s->tokc; -} - -/* return the number of additional 'ints' necessary to store the - token */ -static inline int tok_size(const int *p) -{ - switch(*p) { - /* 4 bytes */ - case TOK_CINT: - case TOK_CUINT: - case TOK_CCHAR: - case TOK_LCHAR: - case TOK_CFLOAT: - case TOK_LINENUM: - return 1 + 1; - case TOK_STR: - case TOK_LSTR: - case TOK_PPNUM: - case TOK_PPSTR: - return 1 + ((sizeof(CString) + ((CString *)(p+1))->size + 3) >> 2); - case TOK_CDOUBLE: - case TOK_CLLONG: - case TOK_CULLONG: - return 1 + 2; - case TOK_CLDOUBLE: - return 1 + LDOUBLE_SIZE / 4; - default: - return 1 + 0; - } -} - -/* token string handling */ - -ST_INLN void tok_str_new(TokenString *s) -{ - s->str = NULL; - s->len = 0; - s->allocated_len = 0; - s->last_line_num = -1; -} - -ST_FUNC void tok_str_free(int *str) -{ - tcc_free(str); -} - -static int *tok_str_realloc(TokenString *s) -{ - int *str, len; - - if (s->allocated_len == 0) { - len = 8; - } else { - len = s->allocated_len * 2; - } - str = tcc_realloc(s->str, len * sizeof(int)); - s->allocated_len = len; - s->str = str; - return str; -} - -ST_FUNC void tok_str_add(TokenString *s, int t) -{ - int len, *str; - - len = s->len; - str = s->str; - if (len >= s->allocated_len) - str = tok_str_realloc(s); - str[len++] = t; - s->len = len; -} - -static void tok_str_add2(TokenString *s, int t, CValue *cv) -{ - int len, *str; - - len = s->len; - str = s->str; - - /* allocate space for worst case */ - if (len + TOK_MAX_SIZE > s->allocated_len) - str = tok_str_realloc(s); - str[len++] = t; - switch(t) { - case TOK_CINT: - case TOK_CUINT: - case TOK_CCHAR: - case TOK_LCHAR: - case TOK_CFLOAT: - case TOK_LINENUM: - str[len++] = cv->tab[0]; - break; - case TOK_PPNUM: - case TOK_PPSTR: - case TOK_STR: - case TOK_LSTR: - { - /* Insert the string into the int array. */ - size_t nb_words = - 1 + (cv->str.size + sizeof(int) - 1) / sizeof(int); - while ((len + nb_words) > s->allocated_len) - str = tok_str_realloc(s); - str[len] = cv->str.size; - memcpy(&str[len + 1], cv->str.data, cv->str.size); - len += nb_words; - } - break; - case TOK_CDOUBLE: - case TOK_CLLONG: - case TOK_CULLONG: -#if LDOUBLE_SIZE == 8 - case TOK_CLDOUBLE: -#endif - str[len++] = cv->tab[0]; - str[len++] = cv->tab[1]; - break; -#if LDOUBLE_SIZE == 12 - case TOK_CLDOUBLE: - str[len++] = cv->tab[0]; - str[len++] = cv->tab[1]; - str[len++] = cv->tab[2]; -#elif LDOUBLE_SIZE == 16 - case TOK_CLDOUBLE: - str[len++] = cv->tab[0]; - str[len++] = cv->tab[1]; - str[len++] = cv->tab[2]; - str[len++] = cv->tab[3]; -#elif LDOUBLE_SIZE != 8 -#error add long double size support -#endif - break; - default: - break; - } - s->len = len; -} - -/* add the current parse token in token string 's' */ -ST_FUNC void tok_str_add_tok(TokenString *s) -{ - CValue cval; - - /* save line number info */ - if (file->line_num != s->last_line_num) { - s->last_line_num = file->line_num; - cval.i = s->last_line_num; - tok_str_add2(s, TOK_LINENUM, &cval); - } - tok_str_add2(s, tok, &tokc); -} - -/* get a token from an integer array and increment pointer - accordingly. we code it as a macro to avoid pointer aliasing. */ -static inline void TOK_GET(int *t, const int **pp, CValue *cv) -{ - const int *p = *pp; - int n, *tab; - - tab = cv->tab; - switch(*t = *p++) { - case TOK_CINT: - case TOK_CUINT: - case TOK_CCHAR: - case TOK_LCHAR: - case TOK_CFLOAT: - case TOK_LINENUM: - tab[0] = *p++; - break; - case TOK_STR: - case TOK_LSTR: - case TOK_PPNUM: - case TOK_PPSTR: - cv->str.size = *p++; - cv->str.data = p; - cv->str.data_allocated = 0; - p += (cv->str.size + sizeof(int) - 1) / sizeof(int); - break; - case TOK_CDOUBLE: - case TOK_CLLONG: - case TOK_CULLONG: - n = 2; - goto copy; - case TOK_CLDOUBLE: -#if LDOUBLE_SIZE == 16 - n = 4; -#elif LDOUBLE_SIZE == 12 - n = 3; -#elif LDOUBLE_SIZE == 8 - n = 2; -#else -# error add long double size support -#endif - copy: - do - *tab++ = *p++; - while (--n); - break; - default: - break; - } - *pp = p; -} - -/* Calling this function is expensive, but it is not possible - to read a token string backwards. */ -static int tok_last(const int *str0, const int *str1) -{ - const int *str = str0; - int tok = 0; - CValue cval; - - while (str < str1) - TOK_GET(&tok, &str, &cval); - return tok; -} - -static int macro_is_equal(const int *a, const int *b) -{ - static CString cstr_buf; - CValue cv; - int t; - while (*a && *b) { - /* first time preallocate static cstr_buf, next time only reset position to start */ - if (!cstr_buf.data_allocated) - cstr_realloc(&cstr_buf, STRING_MAX_SIZE); - else - cstr_buf.size = 0; - TOK_GET(&t, &a, &cv); - cstr_cat(&cstr_buf, get_tok_str(t, &cv)); - cstr_ccat(&cstr_buf, '\0'); - TOK_GET(&t, &b, &cv); - if (strcmp(cstr_buf.data, get_tok_str(t, &cv))) - return 0; - } - return !(*a || *b); -} - -static void pp_line(TCCState *s1, BufferedFile *f, int level) -{ - int d = f->line_num - f->line_ref; - if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_NONE - || (level == 0 && f->line_ref && d < 8)) - { - while (d > 0) - fputs("\n", s1->ppfp), --d; - } - else - if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_STD) { - fprintf(s1->ppfp, "#line %d \"%s\"\n", f->line_num, f->filename); - } - else { - fprintf(s1->ppfp, "# %d \"%s\"%s\n", f->line_num, f->filename, - level > 0 ? " 1" : level < 0 ? " 2" : ""); - } - f->line_ref = f->line_num; -} - -static void tok_print(const char *msg, const int *str) -{ - FILE *pr = tcc_state->ppfp; - int t; - CValue cval; - - fprintf(pr, "%s ", msg); - while (str) { - TOK_GET(&t, &str, &cval); - if (!t) - break; - fprintf(pr,"%s", get_tok_str(t, &cval)); - } - fprintf(pr, "\n"); -} - -static int define_print_prepared(Sym *s) -{ - if (!s || !tcc_state->ppfp || tcc_state->dflag == 0) - return 0; - - if (s->v < TOK_IDENT || s->v >= tok_ident) - return 0; - - if (file) { - file->line_num--; - pp_line(tcc_state, file, 0); - file->line_ref = ++file->line_num; - } - return 1; -} - -static void define_print(int v) -{ - FILE *pr = tcc_state->ppfp; - Sym *s, *a; - - s = define_find(v); - if (define_print_prepared(s) == 0) - return; - - fprintf(pr, "// #define %s", get_tok_str(v, NULL)); - if (s->type.t == MACRO_FUNC) { - a = s->next; - fprintf(pr,"("); - if (a) - for (;;) { - fprintf(pr,"%s", get_tok_str(a->v & ~SYM_FIELD, NULL)); - if (!(a = a->next)) - break; - fprintf(pr,","); - } - fprintf(pr,")"); - } - tok_print("", s->d); -} - -static void undef_print(int v) -{ - FILE *pr = tcc_state->ppfp; - Sym *s; - - s = define_find(v); - if (define_print_prepared(s) == 0) - return; - - fprintf(pr, "// #undef %s\n", get_tok_str(s->v, NULL)); -} - -ST_FUNC void print_defines(void) -{ - Sym *top = define_stack; - while (top) { - define_print(top->v); - top = top->prev; - } -} - -/* defines handling */ -ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg) -{ - Sym *s; - - s = define_find(v); - if (s && !macro_is_equal(s->d, str)) - tcc_warning("%s redefined", get_tok_str(v, NULL)); - - s = sym_push2(&define_stack, v, macro_type, 0); - s->d = str; - s->next = first_arg; - table_ident[v - TOK_IDENT]->sym_define = s; -} - -/* undefined a define symbol. Its name is just set to zero */ -ST_FUNC void define_undef(Sym *s) -{ - int v = s->v; - undef_print(v); - if (v >= TOK_IDENT && v < tok_ident) - table_ident[v - TOK_IDENT]->sym_define = NULL; -} - -ST_INLN Sym *define_find(int v) -{ - v -= TOK_IDENT; - if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) - return NULL; - return table_ident[v]->sym_define; -} - -/* free define stack until top reaches 'b' */ -ST_FUNC void free_defines(Sym *b) -{ - Sym *top, *top1; - int v; - - top = define_stack; - while (top != b) { - top1 = top->prev; - /* do not free args or predefined defines */ - if (top->d) - tok_str_free(top->d); - v = top->v; - if (v >= TOK_IDENT && v < tok_ident) - table_ident[v - TOK_IDENT]->sym_define = NULL; - sym_free(top); - top = top1; - } - define_stack = b; -} - -/* label lookup */ -ST_FUNC Sym *label_find(int v) -{ - v -= TOK_IDENT; - if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) - return NULL; - return table_ident[v]->sym_label; -} - -ST_FUNC Sym *label_push(Sym **ptop, int v, int flags) -{ - Sym *s, **ps; - s = sym_push2(ptop, v, 0, 0); - s->r = flags; - ps = &table_ident[v - TOK_IDENT]->sym_label; - if (ptop == &global_label_stack) { - /* modify the top most local identifier, so that - sym_identifier will point to 's' when popped */ - while (*ps != NULL) - ps = &(*ps)->prev_tok; - } - s->prev_tok = *ps; - *ps = s; - return s; -} - -/* pop labels until element last is reached. Look if any labels are - undefined. Define symbols if '&&label' was used. */ -ST_FUNC void label_pop(Sym **ptop, Sym *slast) -{ - Sym *s, *s1; - for(s = *ptop; s != slast; s = s1) { - s1 = s->prev; - if (s->r == LABEL_DECLARED) { - tcc_warning("label '%s' declared but not used", get_tok_str(s->v, NULL)); - } else if (s->r == LABEL_FORWARD) { - tcc_error("label '%s' used but not defined", - get_tok_str(s->v, NULL)); - } else { - if (s->c) { - /* define corresponding symbol. A size of - 1 is put. */ - put_extern_sym(s, cur_text_section, s->jnext, 1); - } - } - /* remove label */ - table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok; - sym_free(s); - } - *ptop = slast; -} - -/* eval an expression for #if/#elif */ -static int expr_preprocess(void) -{ - int c, t; - TokenString str; - - tok_str_new(&str); - while (tok != TOK_LINEFEED && tok != TOK_EOF) { - next(); /* do macro subst */ - if (tok == TOK_DEFINED) { - next_nomacro(); - t = tok; - if (t == '(') - next_nomacro(); - c = define_find(tok) != 0; - if (t == '(') - next_nomacro(); - tok = TOK_CINT; - tokc.i = c; - } else if (tok >= TOK_IDENT) { - /* if undefined macro */ - tok = TOK_CINT; - tokc.i = 0; - } - tok_str_add_tok(&str); - } - tok_str_add(&str, -1); /* simulate end of file */ - tok_str_add(&str, 0); - /* now evaluate C constant expression */ - begin_macro(&str, 0); - next(); - c = expr_const(); - end_macro(); - return c != 0; -} - - -/* parse after #define */ -ST_FUNC void parse_define(void) -{ - Sym *s, *first, **ps; - int v, t, varg, is_vaargs, spc; - int saved_parse_flags = parse_flags; - TokenString str; - - v = tok; - if (v < TOK_IDENT) - tcc_error("invalid macro name '%s'", get_tok_str(tok, &tokc)); - /* XXX: should check if same macro (ANSI) */ - first = NULL; - t = MACRO_OBJ; - /* '(' must be just after macro definition for MACRO_FUNC */ - parse_flags |= PARSE_FLAG_SPACES; - next_nomacro_spc(); - if (tok == '(') { - next_nomacro(); - ps = &first; - if (tok != ')') for (;;) { - varg = tok; - next_nomacro(); - is_vaargs = 0; - if (varg == TOK_DOTS) { - varg = TOK___VA_ARGS__; - is_vaargs = 1; - } else if (tok == TOK_DOTS && gnu_ext) { - is_vaargs = 1; - next_nomacro(); - } - if (varg < TOK_IDENT) - bad_list: - tcc_error("bad macro parameter list"); - s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0); - *ps = s; - ps = &s->next; - if (tok == ')') - break; - if (tok != ',' || is_vaargs) - goto bad_list; - next_nomacro(); - } - next_nomacro_spc(); - t = MACRO_FUNC; - } - tok_str_new(&str); - spc = 2; - parse_flags |= PARSE_FLAG_ACCEPT_STRAYS | PARSE_FLAG_SPACES | PARSE_FLAG_LINEFEED; - while (tok != TOK_LINEFEED && tok != TOK_EOF) { - /* remove spaces around ## and after '#' */ - if (TOK_TWOSHARPS == tok) { - if (2 == spc) - goto bad_twosharp; - if (1 == spc) - --str.len; - spc = 3; - } else if ('#' == tok) { - spc = 4; - } else if (check_space(tok, &spc)) { - goto skip; - } - tok_str_add2(&str, tok, &tokc); - skip: - next_nomacro_spc(); - } - - parse_flags = saved_parse_flags; - if (spc == 1) - --str.len; /* remove trailing space */ - tok_str_add(&str, 0); - if (3 == spc) -bad_twosharp: - tcc_error("'##' cannot appear at either end of macro"); - define_push(v, t, str.str, first); - define_print(v); -} - -static inline int hash_cached_include(const char *filename) -{ - const unsigned char *s; - unsigned int h; - - h = TOK_HASH_INIT; - s = (unsigned char *) filename; - while (*s) { - h = TOK_HASH_FUNC(h, *s); - s++; - } - h &= (CACHED_INCLUDES_HASH_SIZE - 1); - return h; -} - -static CachedInclude *search_cached_include(TCCState *s1, const char *filename) -{ - CachedInclude *e; - int i, h; - h = hash_cached_include(filename); - i = s1->cached_includes_hash[h]; - for(;;) { - if (i == 0) - break; - e = s1->cached_includes[i - 1]; - if (0 == PATHCMP(e->filename, filename)) - return e; - i = e->hash_next; - } - return NULL; -} - -static inline void add_cached_include(TCCState *s1, const char *filename, int ifndef_macro) -{ - CachedInclude *e; - int h; - - if (search_cached_include(s1, filename)) - return; -#ifdef INC_DEBUG - printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL)); -#endif - e = tcc_malloc(sizeof(CachedInclude) + strlen(filename)); - strcpy(e->filename, filename); - e->ifndef_macro = ifndef_macro; - dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e); - /* add in hash table */ - h = hash_cached_include(filename); - e->hash_next = s1->cached_includes_hash[h]; - s1->cached_includes_hash[h] = s1->nb_cached_includes; -} - -static void pragma_parse(TCCState *s1) -{ - next_nomacro(); - if (tok == TOK_push_macro || tok == TOK_pop_macro) { - int t = tok, v; - Sym *s; - - if (next(), tok != '(') - goto pragma_err; - if (next(), tok != TOK_STR) - goto pragma_err; - v = tok_alloc(tokc.str.data, tokc.str.size - 1)->tok; - if (next(), tok != ')') - goto pragma_err; - if (t == TOK_push_macro) { - while (NULL == (s = define_find(v))) - define_push(v, 0, NULL, NULL); - s->type.ref = s; /* set push boundary */ - } else { - for (s = define_stack; s; s = s->prev) - if (s->v == v && s->type.ref == s) { - s->type.ref = NULL; - break; - } - } - if (s) - table_ident[v - TOK_IDENT]->sym_define = s->d ? s : NULL; - else - tcc_warning("unbalanced #pragma pop_macro"); - - } else if (tok == TOK_once) { - add_cached_include(s1, file->filename, TOK_once); - - } else if (s1->ppfp) { - /* tcc -E: keep pragmas below unchanged */ - unget_tok(' '); - unget_tok(TOK_PRAGMA); - unget_tok('#'); - unget_tok(TOK_LINEFEED); - - } else if (tok == TOK_pack) { - /* This may be: - #pragma pack(1) // set - #pragma pack() // reset to default - #pragma pack(push,1) // push & set - #pragma pack(pop) // restore previous */ - next(); - skip('('); - if (tok == TOK_ASM_pop) { - next(); - if (s1->pack_stack_ptr <= s1->pack_stack) { - stk_error: - tcc_error("out of pack stack"); - } - s1->pack_stack_ptr--; - } else { - int val = 0; - if (tok != ')') { - if (tok == TOK_ASM_push) { - next(); - if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE - 1) - goto stk_error; - s1->pack_stack_ptr++; - skip(','); - } - if (tok != TOK_CINT) - goto pragma_err; - val = tokc.i; - if (val < 1 || val > 16 || (val & (val - 1)) != 0) - goto pragma_err; - next(); - } - *s1->pack_stack_ptr = val; - } - if (tok != ')') - goto pragma_err; - - } else if (tok == TOK_comment) { - char *file; - next(); - skip('('); - if (tok != TOK_lib) - goto pragma_warn; - next(); - skip(','); - if (tok != TOK_STR) - goto pragma_err; - file = tcc_strdup((char *)tokc.str.data); - dynarray_add((void ***)&s1->pragma_libs, &s1->nb_pragma_libs, file); - next(); - if (tok != ')') - goto pragma_err; - } else { -pragma_warn: - if (s1->warn_unsupported) - tcc_warning("#pragma %s is ignored", get_tok_str(tok, &tokc)); - } - return; - -pragma_err: - tcc_error("malformed #pragma directive"); - return; -} - -/* is_bof is true if first non space token at beginning of file */ -ST_FUNC void preprocess(int is_bof) -{ - TCCState *s1 = tcc_state; - int i, c, n, saved_parse_flags; - char buf[1024], *q; - Sym *s; - - saved_parse_flags = parse_flags; - parse_flags = PARSE_FLAG_PREPROCESS - | PARSE_FLAG_TOK_NUM - | PARSE_FLAG_TOK_STR - | PARSE_FLAG_LINEFEED - | (parse_flags & PARSE_FLAG_ASM_FILE) - ; - - next_nomacro(); - redo: - switch(tok) { - case TOK_DEFINE: - next_nomacro(); - parse_define(); - break; - case TOK_UNDEF: - next_nomacro(); - s = define_find(tok); - /* undefine symbol by putting an invalid name */ - if (s) - define_undef(s); - break; - case TOK_INCLUDE: - case TOK_INCLUDE_NEXT: - ch = file->buf_ptr[0]; - /* XXX: incorrect if comments : use next_nomacro with a special mode */ - skip_spaces(); - if (ch == '<') { - c = '>'; - goto read_name; - } else if (ch == '\"') { - c = ch; - read_name: - inp(); - q = buf; - while (ch != c && ch != '\n' && ch != CH_EOF) { - if ((q - buf) < sizeof(buf) - 1) - *q++ = ch; - if (ch == '\\') { - if (handle_stray_noerror() == 0) - --q; - } else - inp(); - } - *q = '\0'; - minp(); -#if 0 - /* eat all spaces and comments after include */ - /* XXX: slightly incorrect */ - while (ch1 != '\n' && ch1 != CH_EOF) - inp(); -#endif - } else { - /* computed #include : either we have only strings or - we have anything enclosed in '<>' */ - next(); - buf[0] = '\0'; - if (tok == TOK_STR) { - while (tok != TOK_LINEFEED) { - if (tok != TOK_STR) { - include_syntax: - tcc_error("'#include' expects \"FILENAME\" or "); - } - pstrcat(buf, sizeof(buf), (char *)tokc.str.data); - next(); - } - c = '\"'; - } else { - int len; - while (tok != TOK_LINEFEED) { - pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc)); - next(); - } - len = strlen(buf); - /* check syntax and remove '<>' */ - if (len < 2 || buf[0] != '<' || buf[len - 1] != '>') - goto include_syntax; - memmove(buf, buf + 1, len - 2); - buf[len - 2] = '\0'; - c = '>'; - } - } - - if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE) - tcc_error("#include recursion too deep"); - /* store current file in stack, but increment stack later below */ - *s1->include_stack_ptr = file; - i = tok == TOK_INCLUDE_NEXT ? file->include_next_index : 0; - n = 2 + s1->nb_include_paths + s1->nb_sysinclude_paths; - for (; i < n; ++i) { - char buf1[sizeof file->filename]; - CachedInclude *e; - const char *path; - - if (i == 0) { - /* check absolute include path */ - if (!IS_ABSPATH(buf)) - continue; - buf1[0] = 0; - - } else if (i == 1) { - /* search in current dir if "header.h" */ - if (c != '\"') - continue; - path = file->filename; - pstrncpy(buf1, path, tcc_basename(path) - path); - - } else { - /* search in all the include paths */ - int j = i - 2, k = j - s1->nb_include_paths; - path = k < 0 ? s1->include_paths[j] : s1->sysinclude_paths[k]; - pstrcpy(buf1, sizeof(buf1), path); - pstrcat(buf1, sizeof(buf1), "/"); - } - - pstrcat(buf1, sizeof(buf1), buf); - e = search_cached_include(s1, buf1); - if (e && (define_find(e->ifndef_macro) || e->ifndef_macro == TOK_once)) { - /* no need to parse the include because the 'ifndef macro' - is defined */ -#ifdef INC_DEBUG - printf("%s: skipping cached %s\n", file->filename, buf1); -#endif - goto include_done; - } - - if (tcc_open(s1, buf1) < 0) - continue; - - file->include_next_index = i + 1; -#ifdef INC_DEBUG - printf("%s: including %s\n", file->prev->filename, file->filename); -#endif - /* update target deps */ - dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps, - tcc_strdup(buf1)); - /* push current file in stack */ - ++s1->include_stack_ptr; - /* add include file debug info */ - if (s1->do_debug) - put_stabs(file->filename, N_BINCL, 0, 0, 0); - tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL; - ch = file->buf_ptr[0]; - goto the_end; - } - tcc_error("include file '%s' not found", buf); -include_done: - break; - case TOK_IFNDEF: - c = 1; - goto do_ifdef; - case TOK_IF: - c = expr_preprocess(); - goto do_if; - case TOK_IFDEF: - c = 0; - do_ifdef: - next_nomacro(); - if (tok < TOK_IDENT) - tcc_error("invalid argument for '#if%sdef'", c ? "n" : ""); - if (is_bof) { - if (c) { -#ifdef INC_DEBUG - printf("#ifndef %s\n", get_tok_str(tok, NULL)); -#endif - file->ifndef_macro = tok; - } - } - c = (define_find(tok) != 0) ^ c; - do_if: - if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE) - tcc_error("memory full (ifdef)"); - *s1->ifdef_stack_ptr++ = c; - goto test_skip; - case TOK_ELSE: - if (s1->ifdef_stack_ptr == s1->ifdef_stack) - tcc_error("#else without matching #if"); - if (s1->ifdef_stack_ptr[-1] & 2) - tcc_error("#else after #else"); - c = (s1->ifdef_stack_ptr[-1] ^= 3); - goto test_else; - case TOK_ELIF: - if (s1->ifdef_stack_ptr == s1->ifdef_stack) - tcc_error("#elif without matching #if"); - c = s1->ifdef_stack_ptr[-1]; - if (c > 1) - tcc_error("#elif after #else"); - /* last #if/#elif expression was true: we skip */ - if (c == 1) - goto skip; - c = expr_preprocess(); - s1->ifdef_stack_ptr[-1] = c; - test_else: - if (s1->ifdef_stack_ptr == file->ifdef_stack_ptr + 1) - file->ifndef_macro = 0; - test_skip: - if (!(c & 1)) { - skip: - preprocess_skip(); - is_bof = 0; - goto redo; - } - break; - case TOK_ENDIF: - if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr) - tcc_error("#endif without matching #if"); - s1->ifdef_stack_ptr--; - /* '#ifndef macro' was at the start of file. Now we check if - an '#endif' is exactly at the end of file */ - if (file->ifndef_macro && - s1->ifdef_stack_ptr == file->ifdef_stack_ptr) { - file->ifndef_macro_saved = file->ifndef_macro; - /* need to set to zero to avoid false matches if another - #ifndef at middle of file */ - file->ifndef_macro = 0; - while (tok != TOK_LINEFEED) - next_nomacro(); - tok_flags |= TOK_FLAG_ENDIF; - goto the_end; - } - break; - case TOK_PPNUM: - n = strtoul((char*)tokc.str.data, &q, 10); - goto _line_num; - case TOK_LINE: - next(); - if (tok != TOK_CINT) -_line_err: - tcc_error("wrong #line format"); - n = tokc.i; -_line_num: - next(); - if (tok != TOK_LINEFEED) { - if (tok == TOK_STR) - pstrcpy(file->filename, sizeof(file->filename), (char *)tokc.str.data); - else if (parse_flags & PARSE_FLAG_ASM_FILE) - break; - else - goto _line_err; - --n; - } - if (file->fd > 0) - total_lines += file->line_num - n; - file->line_num = n; - if (s1->do_debug) - put_stabs(file->filename, N_BINCL, 0, 0, 0); - break; - case TOK_ERROR: - case TOK_WARNING: - c = tok; - ch = file->buf_ptr[0]; - skip_spaces(); - q = buf; - while (ch != '\n' && ch != CH_EOF) { - if ((q - buf) < sizeof(buf) - 1) - *q++ = ch; - if (ch == '\\') { - if (handle_stray_noerror() == 0) - --q; - } else - inp(); - } - *q = '\0'; - if (c == TOK_ERROR) - tcc_error("#error %s", buf); - else - tcc_warning("#warning %s", buf); - break; - case TOK_PRAGMA: - pragma_parse(s1); - break; - case TOK_LINEFEED: - goto the_end; - default: - /* ignore gas line comment in an 'S' file. */ - if (saved_parse_flags & PARSE_FLAG_ASM_FILE) - goto ignore; - if (tok == '!' && is_bof) - /* '!' is ignored at beginning to allow C scripts. */ - goto ignore; - tcc_warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc)); - ignore: - file->buf_ptr = parse_line_comment(file->buf_ptr); - goto the_end; - } - /* ignore other preprocess commands or #! for C scripts */ - while (tok != TOK_LINEFEED) - next_nomacro(); - the_end: - parse_flags = saved_parse_flags; -} - -/* evaluate escape codes in a string. */ -static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long) -{ - int c, n; - const uint8_t *p; - - p = buf; - for(;;) { - c = *p; - if (c == '\0') - break; - if (c == '\\') { - p++; - /* escape */ - c = *p; - switch(c) { - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - /* at most three octal digits */ - n = c - '0'; - p++; - c = *p; - if (isoct(c)) { - n = n * 8 + c - '0'; - p++; - c = *p; - if (isoct(c)) { - n = n * 8 + c - '0'; - p++; - } - } - c = n; - goto add_char_nonext; - case 'x': - case 'u': - case 'U': - p++; - n = 0; - for(;;) { - c = *p; - if (c >= 'a' && c <= 'f') - c = c - 'a' + 10; - else if (c >= 'A' && c <= 'F') - c = c - 'A' + 10; - else if (isnum(c)) - c = c - '0'; - else - break; - n = n * 16 + c; - p++; - } - c = n; - goto add_char_nonext; - case 'a': - c = '\a'; - break; - case 'b': - c = '\b'; - break; - case 'f': - c = '\f'; - break; - case 'n': - c = '\n'; - break; - case 'r': - c = '\r'; - break; - case 't': - c = '\t'; - break; - case 'v': - c = '\v'; - break; - case 'e': - if (!gnu_ext) - goto invalid_escape; - c = 27; - break; - case '\'': - case '\"': - case '\\': - case '?': - break; - default: - invalid_escape: - if (c >= '!' && c <= '~') - tcc_warning("unknown escape sequence: \'\\%c\'", c); - else - tcc_warning("unknown escape sequence: \'\\x%x\'", c); - break; - } - } - p++; - add_char_nonext: - if (!is_long) - cstr_ccat(outstr, c); - else - cstr_wccat(outstr, c); - } - /* add a trailing '\0' */ - if (!is_long) - cstr_ccat(outstr, '\0'); - else - cstr_wccat(outstr, '\0'); -} - -void parse_string(const char *s, int len) -{ - uint8_t buf[1000], *p = buf; - int is_long, sep; - - if ((is_long = *s == 'L')) - ++s, --len; - sep = *s++; - len -= 2; - if (len >= sizeof buf) - p = tcc_malloc(len + 1); - memcpy(p, s, len); - p[len] = 0; - - cstr_reset(&tokcstr); - parse_escape_string(&tokcstr, p, is_long); - if (p != buf) - tcc_free(p); - - if (sep == '\'') { - int char_size; - /* XXX: make it portable */ - if (!is_long) - char_size = 1; - else - char_size = sizeof(nwchar_t); - if (tokcstr.size <= char_size) - tcc_error("empty character constant"); - if (tokcstr.size > 2 * char_size) - tcc_warning("multi-character character constant"); - if (!is_long) { - tokc.i = *(int8_t *)tokcstr.data; - tok = TOK_CCHAR; - } else { - tokc.i = *(nwchar_t *)tokcstr.data; - tok = TOK_LCHAR; - } - } else { - tokc.str.size = tokcstr.size; - tokc.str.data = tokcstr.data; - tokc.str.data_allocated = tokcstr.data_allocated; - if (!is_long) - tok = TOK_STR; - else - tok = TOK_LSTR; - } -} - -/* we use 64 bit numbers */ -#define BN_SIZE 2 - -/* bn = (bn << shift) | or_val */ -static void bn_lshift(unsigned int *bn, int shift, int or_val) -{ - int i; - unsigned int v; - for(i=0;i> (32 - shift); - } -} - -static void bn_zero(unsigned int *bn) -{ - int i; - for(i=0;i= 'a' && ch <= 'f') - t = ch - 'a' + 10; - else if (ch >= 'A' && ch <= 'F') - t = ch - 'A' + 10; - else if (isnum(ch)) - t = ch - '0'; - else - break; - if (t >= b) - break; - if (q >= token_buf + STRING_MAX_SIZE) { - num_too_long: - tcc_error("number too long"); - } - *q++ = ch; - ch = *p++; - } - if (ch == '.' || - ((ch == 'e' || ch == 'E') && b == 10) || - ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) { - if (b != 10) { - /* NOTE: strtox should support that for hexa numbers, but - non ISOC99 libcs do not support it, so we prefer to do - it by hand */ - /* hexadecimal or binary floats */ - /* XXX: handle overflows */ - *q = '\0'; - if (b == 16) - shift = 4; - else - shift = 1; - bn_zero(bn); - q = token_buf; - while (1) { - t = *q++; - if (t == '\0') { - break; - } else if (t >= 'a') { - t = t - 'a' + 10; - } else if (t >= 'A') { - t = t - 'A' + 10; - } else { - t = t - '0'; - } - bn_lshift(bn, shift, t); - } - frac_bits = 0; - if (ch == '.') { - ch = *p++; - while (1) { - t = ch; - if (t >= 'a' && t <= 'f') { - t = t - 'a' + 10; - } else if (t >= 'A' && t <= 'F') { - t = t - 'A' + 10; - } else if (t >= '0' && t <= '9') { - t = t - '0'; - } else { - break; - } - if (t >= b) - tcc_error("invalid digit"); - bn_lshift(bn, shift, t); - frac_bits += shift; - ch = *p++; - } - } - if (ch != 'p' && ch != 'P') - expect("exponent"); - ch = *p++; - s = 1; - exp_val = 0; - if (ch == '+') { - ch = *p++; - } else if (ch == '-') { - s = -1; - ch = *p++; - } - if (ch < '0' || ch > '9') - expect("exponent digits"); - while (ch >= '0' && ch <= '9') { - exp_val = exp_val * 10 + ch - '0'; - ch = *p++; - } - exp_val = exp_val * s; - - /* now we can generate the number */ - /* XXX: should patch directly float number */ - d = (double)bn[1] * 4294967296.0 + (double)bn[0]; - d = ldexp(d, exp_val - frac_bits); - t = toup(ch); - if (t == 'F') { - ch = *p++; - tok = TOK_CFLOAT; - /* float : should handle overflow */ - tokc.f = (float)d; - } else if (t == 'L') { - ch = *p++; -#ifdef TCC_TARGET_PE - tok = TOK_CDOUBLE; - tokc.d = d; -#else - tok = TOK_CLDOUBLE; - /* XXX: not large enough */ - tokc.ld = (long double)d; -#endif - } else { - tok = TOK_CDOUBLE; - tokc.d = d; - } - } else { - /* decimal floats */ - if (ch == '.') { - if (q >= token_buf + STRING_MAX_SIZE) - goto num_too_long; - *q++ = ch; - ch = *p++; - float_frac_parse: - while (ch >= '0' && ch <= '9') { - if (q >= token_buf + STRING_MAX_SIZE) - goto num_too_long; - *q++ = ch; - ch = *p++; - } - } - if (ch == 'e' || ch == 'E') { - if (q >= token_buf + STRING_MAX_SIZE) - goto num_too_long; - *q++ = ch; - ch = *p++; - if (ch == '-' || ch == '+') { - if (q >= token_buf + STRING_MAX_SIZE) - goto num_too_long; - *q++ = ch; - ch = *p++; - } - if (ch < '0' || ch > '9') - expect("exponent digits"); - while (ch >= '0' && ch <= '9') { - if (q >= token_buf + STRING_MAX_SIZE) - goto num_too_long; - *q++ = ch; - ch = *p++; - } - } - *q = '\0'; - t = toup(ch); - errno = 0; - if (t == 'F') { - ch = *p++; - tok = TOK_CFLOAT; - tokc.f = strtof(token_buf, NULL); - } else if (t == 'L') { - ch = *p++; -#ifdef TCC_TARGET_PE - tok = TOK_CDOUBLE; - tokc.d = strtod(token_buf, NULL); -#else - tok = TOK_CLDOUBLE; - tokc.ld = strtold(token_buf, NULL); -#endif - } else { - tok = TOK_CDOUBLE; - tokc.d = strtod(token_buf, NULL); - } - } - } else { - unsigned long long n, n1; - int lcount, ucount, must_64bit; - const char *p1; - - /* integer number */ - *q = '\0'; - q = token_buf; - if (b == 10 && *q == '0') { - b = 8; - q++; - } - n = 0; - while(1) { - t = *q++; - /* no need for checks except for base 10 / 8 errors */ - if (t == '\0') - break; - else if (t >= 'a') - t = t - 'a' + 10; - else if (t >= 'A') - t = t - 'A' + 10; - else - t = t - '0'; - if (t >= b) - tcc_error("invalid digit"); - n1 = n; - n = n * b + t; - /* detect overflow */ - /* XXX: this test is not reliable */ - if (n < n1) - tcc_error("integer constant overflow"); - } - - /* Determine the characteristics (unsigned and/or 64bit) the type of - the constant must have according to the constant suffix(es) */ - lcount = ucount = must_64bit = 0; - p1 = p; - for(;;) { - t = toup(ch); - if (t == 'L') { - if (lcount >= 2) - tcc_error("three 'l's in integer constant"); - if (lcount && *(p - 1) != ch) - tcc_error("incorrect integer suffix: %s", p1); - lcount++; -#if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE - if (lcount == 2) -#endif - must_64bit = 1; - ch = *p++; - } else if (t == 'U') { - if (ucount >= 1) - tcc_error("two 'u's in integer constant"); - ucount++; - ch = *p++; - } else { - break; - } - } - - /* Whether 64 bits are needed to hold the constant's value */ - if (n & 0xffffffff00000000LL || must_64bit) { - tok = TOK_CLLONG; - n1 = n >> 32; - } else { - tok = TOK_CINT; - n1 = n; - } - - /* Whether type must be unsigned to hold the constant's value */ - if (ucount || ((n1 >> 31) && (b != 10))) { - if (tok == TOK_CLLONG) - tok = TOK_CULLONG; - else - tok = TOK_CUINT; - /* If decimal and no unsigned suffix, bump to 64 bits or throw error */ - } else if (n1 >> 31) { - if (tok == TOK_CINT) - tok = TOK_CLLONG; - else - tcc_error("integer constant overflow"); - } - - if (tok == TOK_CINT || tok == TOK_CUINT) - tokc.i = n; - else - tokc.i = n; - } - if (ch) - tcc_error("invalid number\n"); -} - - -#define PARSE2(c1, tok1, c2, tok2) \ - case c1: \ - PEEKC(c, p); \ - if (c == c2) { \ - p++; \ - tok = tok2; \ - } else { \ - tok = tok1; \ - } \ - break; - -/* return next token without macro substitution */ -static inline void next_nomacro1(void) -{ - int t, c, is_long; - TokenSym *ts; - uint8_t *p, *p1; - unsigned int h; - - p = file->buf_ptr; - redo_no_start: - c = *p; - switch(c) { - case ' ': - case '\t': - tok = c; - p++; - if (parse_flags & PARSE_FLAG_SPACES) - goto keep_tok_flags; - while (isidnum_table[*p - CH_EOF] & IS_SPC) - ++p; - goto redo_no_start; - case '\f': - case '\v': - case '\r': - p++; - goto redo_no_start; - case '\\': - /* first look if it is in fact an end of buffer */ - c = handle_stray1(p); - p = file->buf_ptr; - if (c == '\\') - goto parse_simple; - if (c != CH_EOF) - goto redo_no_start; - { - TCCState *s1 = tcc_state; - if ((parse_flags & PARSE_FLAG_LINEFEED) - && !(tok_flags & TOK_FLAG_EOF)) { - tok_flags |= TOK_FLAG_EOF; - tok = TOK_LINEFEED; - goto keep_tok_flags; - } else if (!(parse_flags & PARSE_FLAG_PREPROCESS)) { - tok = TOK_EOF; - } else if (s1->ifdef_stack_ptr != file->ifdef_stack_ptr) { - tcc_error("missing #endif"); - } else if (s1->include_stack_ptr == s1->include_stack) { - /* no include left : end of file. */ - tok = TOK_EOF; - } else { - tok_flags &= ~TOK_FLAG_EOF; - /* pop include file */ - - /* test if previous '#endif' was after a #ifdef at - start of file */ - if (tok_flags & TOK_FLAG_ENDIF) { -#ifdef INC_DEBUG - printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL)); -#endif - add_cached_include(s1, file->filename, file->ifndef_macro_saved); - tok_flags &= ~TOK_FLAG_ENDIF; - } - - /* add end of include file debug info */ - if (tcc_state->do_debug) { - put_stabd(N_EINCL, 0, 0); - } - /* pop include stack */ - tcc_close(); - s1->include_stack_ptr--; - p = file->buf_ptr; - goto redo_no_start; - } - } - break; - - case '\n': - file->line_num++; - tok_flags |= TOK_FLAG_BOL; - p++; -maybe_newline: - if (0 == (parse_flags & PARSE_FLAG_LINEFEED)) - goto redo_no_start; - tok = TOK_LINEFEED; - goto keep_tok_flags; - - case '#': - /* XXX: simplify */ - PEEKC(c, p); - if ((tok_flags & TOK_FLAG_BOL) && - (parse_flags & PARSE_FLAG_PREPROCESS)) { - file->buf_ptr = p; - preprocess(tok_flags & TOK_FLAG_BOF); - p = file->buf_ptr; - goto maybe_newline; - } else { - if (c == '#') { - p++; - tok = TOK_TWOSHARPS; - } else { - if (parse_flags & PARSE_FLAG_ASM_FILE) { - p = parse_line_comment(p - 1); - goto redo_no_start; - } else { - tok = '#'; - } - } - } - break; - - /* dollar is allowed to start identifiers when not parsing asm */ - case '$': - if (!(isidnum_table[c - CH_EOF] & IS_ID) - || (parse_flags & PARSE_FLAG_ASM_FILE)) - goto parse_simple; - - case 'a': case 'b': case 'c': case 'd': - case 'e': case 'f': case 'g': case 'h': - case 'i': case 'j': case 'k': case 'l': - case 'm': case 'n': case 'o': case 'p': - case 'q': case 'r': case 's': case 't': - case 'u': case 'v': case 'w': case 'x': - case 'y': case 'z': - case 'A': case 'B': case 'C': case 'D': - case 'E': case 'F': case 'G': case 'H': - case 'I': case 'J': case 'K': - case 'M': case 'N': case 'O': case 'P': - case 'Q': case 'R': case 'S': case 'T': - case 'U': case 'V': case 'W': case 'X': - case 'Y': case 'Z': - case '_': - parse_ident_fast: - p1 = p; - h = TOK_HASH_INIT; - h = TOK_HASH_FUNC(h, c); - while (c = *++p, isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM)) - h = TOK_HASH_FUNC(h, c); - if (c != '\\') { - TokenSym **pts; - int len; - - /* fast case : no stray found, so we have the full token - and we have already hashed it */ - len = p - p1; - h &= (TOK_HASH_SIZE - 1); - pts = &hash_ident[h]; - for(;;) { - ts = *pts; - if (!ts) - break; - if (ts->len == len && !memcmp(ts->str, p1, len)) - goto token_found; - pts = &(ts->hash_next); - } - ts = tok_alloc_new(pts, (char *) p1, len); - token_found: ; - } else { - /* slower case */ - cstr_reset(&tokcstr); - - while (p1 < p) { - cstr_ccat(&tokcstr, *p1); - p1++; - } - p--; - PEEKC(c, p); - parse_ident_slow: - while (isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM)) { - cstr_ccat(&tokcstr, c); - PEEKC(c, p); - } - ts = tok_alloc(tokcstr.data, tokcstr.size); - } - tok = ts->tok; - break; - case 'L': - t = p[1]; - if (t != '\\' && t != '\'' && t != '\"') { - /* fast case */ - goto parse_ident_fast; - } else { - PEEKC(c, p); - if (c == '\'' || c == '\"') { - is_long = 1; - goto str_const; - } else { - cstr_reset(&tokcstr); - cstr_ccat(&tokcstr, 'L'); - goto parse_ident_slow; - } - } - break; - - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - case '8': case '9': - cstr_reset(&tokcstr); - /* after the first digit, accept digits, alpha, '.' or sign if - prefixed by 'eEpP' */ - parse_num: - for(;;) { - t = c; - cstr_ccat(&tokcstr, c); - PEEKC(c, p); - if (!((isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM)) - || c == '.' - || ((c == '+' || c == '-') - && (t == 'e' || t == 'E' || t == 'p' || t == 'P') - ))) - break; - } - /* We add a trailing '\0' to ease parsing */ - cstr_ccat(&tokcstr, '\0'); - tokc.str.size = tokcstr.size; - tokc.str.data = tokcstr.data; - tokc.str.data_allocated = tokcstr.data_allocated; - tok = TOK_PPNUM; - break; - - case '.': - /* special dot handling because it can also start a number */ - PEEKC(c, p); - if (isnum(c)) { - cstr_reset(&tokcstr); - cstr_ccat(&tokcstr, '.'); - goto parse_num; - } else if ((isidnum_table['.' - CH_EOF] & IS_ID) != 0) { /* asm mode */ - *--p = c = '.'; - goto parse_ident_fast; - } else if (c == '.') { - PEEKC(c, p); - if (c == '.') { - p++; - tok = TOK_DOTS; - } else { - *--p = '.'; /* may underflow into file->unget[] */ - tok = '.'; - } - } else { - tok = '.'; - } - break; - case '\'': - case '\"': - is_long = 0; - str_const: - cstr_reset(&tokcstr); - if (is_long) - cstr_ccat(&tokcstr, 'L'); - cstr_ccat(&tokcstr, c); - p = parse_pp_string(p, c, &tokcstr); - cstr_ccat(&tokcstr, c); - cstr_ccat(&tokcstr, '\0'); - tokc.str.size = tokcstr.size; - tokc.str.data = tokcstr.data; - tokc.str.data_allocated = tokcstr.data_allocated; - tok = TOK_PPSTR; - break; - - case '<': - PEEKC(c, p); - if (c == '=') { - p++; - tok = TOK_LE; - } else if (c == '<') { - PEEKC(c, p); - if (c == '=') { - p++; - tok = TOK_A_SHL; - } else { - tok = TOK_SHL; - } - } else { - tok = TOK_LT; - } - break; - case '>': - PEEKC(c, p); - if (c == '=') { - p++; - tok = TOK_GE; - } else if (c == '>') { - PEEKC(c, p); - if (c == '=') { - p++; - tok = TOK_A_SAR; - } else { - tok = TOK_SAR; - } - } else { - tok = TOK_GT; - } - break; - - case '&': - PEEKC(c, p); - if (c == '&') { - p++; - tok = TOK_LAND; - } else if (c == '=') { - p++; - tok = TOK_A_AND; - } else { - tok = '&'; - } - break; - - case '|': - PEEKC(c, p); - if (c == '|') { - p++; - tok = TOK_LOR; - } else if (c == '=') { - p++; - tok = TOK_A_OR; - } else { - tok = '|'; - } - break; - - case '+': - PEEKC(c, p); - if (c == '+') { - p++; - tok = TOK_INC; - } else if (c == '=') { - p++; - tok = TOK_A_ADD; - } else { - tok = '+'; - } - break; - - case '-': - PEEKC(c, p); - if (c == '-') { - p++; - tok = TOK_DEC; - } else if (c == '=') { - p++; - tok = TOK_A_SUB; - } else if (c == '>') { - p++; - tok = TOK_ARROW; - } else { - tok = '-'; - } - break; - - PARSE2('!', '!', '=', TOK_NE) - PARSE2('=', '=', '=', TOK_EQ) - PARSE2('*', '*', '=', TOK_A_MUL) - PARSE2('%', '%', '=', TOK_A_MOD) - PARSE2('^', '^', '=', TOK_A_XOR) - - /* comments or operator */ - case '/': - PEEKC(c, p); - if (c == '*') { - p = parse_comment(p); - /* comments replaced by a blank */ - tok = ' '; - goto keep_tok_flags; - } else if (c == '/') { - p = parse_line_comment(p); - tok = ' '; - goto keep_tok_flags; - } else if (c == '=') { - p++; - tok = TOK_A_DIV; - } else { - tok = '/'; - } - break; - - /* simple tokens */ - case '(': - case ')': - case '[': - case ']': - case '{': - case '}': - case ',': - case ';': - case ':': - case '?': - case '~': - case '@': /* only used in assembler */ - parse_simple: - tok = c; - p++; - break; - default: - tcc_error("unrecognized character \\x%02x", c); - break; - } - tok_flags = 0; -keep_tok_flags: - file->buf_ptr = p; -#if defined(PARSE_DEBUG) - printf("token = %s\n", get_tok_str(tok, &tokc)); -#endif -} - -/* return next token without macro substitution. Can read input from - macro_ptr buffer */ -static void next_nomacro_spc(void) -{ - if (macro_ptr) { - redo: - tok = *macro_ptr; - if (tok) { - TOK_GET(&tok, ¯o_ptr, &tokc); - if (tok == TOK_LINENUM) { - file->line_num = tokc.i; - goto redo; - } - } - } else { - next_nomacro1(); - } -} - -ST_FUNC void next_nomacro(void) -{ - do { - next_nomacro_spc(); - } while (tok < 256 && (isidnum_table[tok - CH_EOF] & IS_SPC)); -} - - -static void macro_subst( - TokenString *tok_str, - Sym **nested_list, - const int *macro_str, - int can_read_stream - ); - -/* substitute arguments in replacement lists in macro_str by the values in - args (field d) and return allocated string */ -static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args) -{ - int t, t0, t1, spc; - const int *st; - Sym *s; - CValue cval; - TokenString str; - CString cstr; - - tok_str_new(&str); - t0 = t1 = 0; - while(1) { - TOK_GET(&t, ¯o_str, &cval); - if (!t) - break; - if (t == '#') { - /* stringize */ - TOK_GET(&t, ¯o_str, &cval); - if (!t) - goto bad_stringy; - s = sym_find2(args, t); - if (s) { - cstr_new(&cstr); - cstr_ccat(&cstr, '\"'); - st = s->d; - spc = 0; - while (*st) { - TOK_GET(&t, &st, &cval); - if (t != TOK_PLCHLDR - && t != TOK_NOSUBST - && 0 == check_space(t, &spc)) { - const char *s = get_tok_str(t, &cval); - while (*s) { - if (t == TOK_PPSTR && *s != '\'') - add_char(&cstr, *s); - else - cstr_ccat(&cstr, *s); - ++s; - } - } - } - cstr.size -= spc; - cstr_ccat(&cstr, '\"'); - cstr_ccat(&cstr, '\0'); -#ifdef PP_DEBUG - printf("\nstringize: <%s>\n", (char *)cstr.data); -#endif - /* add string */ - cval.str.size = cstr.size; - cval.str.data = cstr.data; - cval.str.data_allocated = cstr.data_allocated; - tok_str_add2(&str, TOK_PPSTR, &cval); - tcc_free(cval.str.data_allocated); - } else { - bad_stringy: - expect("macro parameter after '#'"); - } - } else if (t >= TOK_IDENT) { - s = sym_find2(args, t); - if (s) { - int l0 = str.len; - st = s->d; - /* if '##' is present before or after, no arg substitution */ - if (*macro_str == TOK_TWOSHARPS || t1 == TOK_TWOSHARPS) { - /* special case for var arg macros : ## eats the ',' - if empty VA_ARGS variable. */ - if (t1 == TOK_TWOSHARPS && t0 == ',' && gnu_ext && s->type.t) { - if (*st == 0) { - /* suppress ',' '##' */ - str.len -= 2; - } else { - /* suppress '##' and add variable */ - str.len--; - goto add_var; - } - } else { - for(;;) { - int t1; - TOK_GET(&t1, &st, &cval); - if (!t1) - break; - tok_str_add2(&str, t1, &cval); - } - } - - } else { - add_var: - /* NOTE: the stream cannot be read when macro - substituing an argument */ - macro_subst(&str, nested_list, st, 0); - } - if (str.len == l0) /* exanded to empty string */ - tok_str_add(&str, TOK_PLCHLDR); - } else { - tok_str_add(&str, t); - } - } else { - tok_str_add2(&str, t, &cval); - } - t0 = t1, t1 = t; - } - tok_str_add(&str, 0); - return str.str; -} - -static char const ab_month_name[12][4] = -{ - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; - -/* peek or read [ws_str == NULL] next token from function macro call, - walking up macro levels up to the file if necessary */ -static int next_argstream(Sym **nested_list, int can_read_stream, TokenString *ws_str) -{ - int t; - const int *p; - Sym *sa; - - for (;;) { - if (macro_ptr) { - p = macro_ptr, t = *p; - if (ws_str) { - while (is_space(t) || TOK_LINEFEED == t) - tok_str_add(ws_str, t), t = *++p; - } - if (t == 0 && can_read_stream) { - end_macro(); - /* also, end of scope for nested defined symbol */ - sa = *nested_list; - while (sa && sa->v == -1) - sa = sa->prev; - if (sa) - sa->v = -1; - continue; - } - } else { - ch = handle_eob(); - if (ws_str) { - while (is_space(ch) || ch == '\n' || ch == '/') { - if (ch == '/') { - int c; - uint8_t *p = file->buf_ptr; - PEEKC(c, p); - if (c == '*') { - p = parse_comment(p); - file->buf_ptr = p - 1; - } else if (c == '/') { - p = parse_line_comment(p); - file->buf_ptr = p - 1; - } else - break; - ch = ' '; - } - tok_str_add(ws_str, ch); - cinp(); - } - } - t = ch; - } - - if (ws_str) - return t; - next_nomacro_spc(); - return tok; - } -} - -/* do macro substitution of current token with macro 's' and add - result to (tok_str,tok_len). 'nested_list' is the list of all - macros we got inside to avoid recursing. Return non zero if no - substitution needs to be done */ -static int macro_subst_tok( - TokenString *tok_str, - Sym **nested_list, - Sym *s, - int can_read_stream) -{ - Sym *args, *sa, *sa1; - int parlevel, *mstr, t, t1, spc; - TokenString str; - char *cstrval; - CValue cval; - CString cstr; - char buf[32]; - - /* if symbol is a macro, prepare substitution */ - /* special macros */ - if (tok == TOK___LINE__) { - snprintf(buf, sizeof(buf), "%d", file->line_num); - cstrval = buf; - t1 = TOK_PPNUM; - goto add_cstr1; - } else if (tok == TOK___FILE__) { - cstrval = file->filename; - goto add_cstr; - } else if (tok == TOK___DATE__ || tok == TOK___TIME__) { - time_t ti; - struct tm *tm; - - time(&ti); - tm = localtime(&ti); - if (tok == TOK___DATE__) { - snprintf(buf, sizeof(buf), "%s %2d %d", - ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900); - } else { - snprintf(buf, sizeof(buf), "%02d:%02d:%02d", - tm->tm_hour, tm->tm_min, tm->tm_sec); - } - cstrval = buf; - add_cstr: - t1 = TOK_STR; - add_cstr1: - cstr_new(&cstr); - cstr_cat(&cstr, cstrval); - cstr_ccat(&cstr, '\0'); - cval.str.size = cstr.size; - cval.str.data = cstr.data; - cval.str.data_allocated = cstr.data_allocated; - tok_str_add2(tok_str, t1, &cval); - cstr_free(&cstr); - } else { - int saved_parse_flags = parse_flags; - - mstr = s->d; - if (s->type.t == MACRO_FUNC) { - /* whitespace between macro name and argument list */ - TokenString ws_str; - tok_str_new(&ws_str); - - spc = 0; - parse_flags |= PARSE_FLAG_SPACES | PARSE_FLAG_LINEFEED - | PARSE_FLAG_ACCEPT_STRAYS; - - /* get next token from argument stream */ - t = next_argstream(nested_list, can_read_stream, &ws_str); - if (t != '(') { - /* not a macro substitution after all, restore the - * macro token plus all whitespace we've read. - * whitespace is intentionally not merged to preserve - * newlines. */ - parse_flags = saved_parse_flags; - tok_str_add(tok_str, tok); - if (parse_flags & PARSE_FLAG_SPACES) { - int i; - for (i = 0; i < ws_str.len; i++) - tok_str_add(tok_str, ws_str.str[i]); - } - tok_str_free(ws_str.str); - return 0; - } else { - tok_str_free(ws_str.str); - } - next_nomacro(); /* eat '(' */ - - /* argument macro */ - args = NULL; - sa = s->next; - /* NOTE: empty args are allowed, except if no args */ - for(;;) { - do { - next_argstream(nested_list, can_read_stream, NULL); - } while (is_space(tok) || TOK_LINEFEED == tok); - empty_arg: - /* handle '()' case */ - if (!args && !sa && tok == ')') - break; - if (!sa) - tcc_error("macro '%s' used with too many args", - get_tok_str(s->v, 0)); - tok_str_new(&str); - parlevel = spc = 0; - /* NOTE: non zero sa->t indicates VA_ARGS */ - while ((parlevel > 0 || - (tok != ')' && - (tok != ',' || sa->type.t)))) { - if (tok == TOK_EOF || tok == 0) - break; - if (tok == '(') - parlevel++; - else if (tok == ')') - parlevel--; - if (tok == TOK_LINEFEED) - tok = ' '; - if (!check_space(tok, &spc)) - tok_str_add2(&str, tok, &tokc); - next_argstream(nested_list, can_read_stream, NULL); - } - if (parlevel) - expect(")"); - str.len -= spc; - tok_str_add(&str, 0); - sa1 = sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, 0); - sa1->d = str.str; - sa = sa->next; - if (tok == ')') { - /* special case for gcc var args: add an empty - var arg argument if it is omitted */ - if (sa && sa->type.t && gnu_ext) - goto empty_arg; - break; - } - if (tok != ',') - expect(","); - } - if (sa) { - tcc_error("macro '%s' used with too few args", - get_tok_str(s->v, 0)); - } - - parse_flags = saved_parse_flags; - - /* now subst each arg */ - mstr = macro_arg_subst(nested_list, mstr, args); - /* free memory */ - sa = args; - while (sa) { - sa1 = sa->prev; - tok_str_free(sa->d); - sym_free(sa); - sa = sa1; - } - } - - sym_push2(nested_list, s->v, 0, 0); - parse_flags = saved_parse_flags; - macro_subst(tok_str, nested_list, mstr, can_read_stream); - - /* pop nested defined symbol */ - sa1 = *nested_list; - *nested_list = sa1->prev; - sym_free(sa1); - if (mstr != s->d) - tok_str_free(mstr); - } - return 0; -} - -int paste_tokens(int t1, CValue *v1, int t2, CValue *v2) -{ - CString cstr; - int n; - - cstr_new(&cstr); - if (t1 != TOK_PLCHLDR) - cstr_cat(&cstr, get_tok_str(t1, v1)); - n = cstr.size; - if (t2 != TOK_PLCHLDR) - cstr_cat(&cstr, get_tok_str(t2, v2)); - cstr_ccat(&cstr, '\0'); - - tcc_open_bf(tcc_state, ":paste:", cstr.size); - memcpy(file->buffer, cstr.data, cstr.size); - for (;;) { - next_nomacro1(); - if (0 == *file->buf_ptr) - break; - if (is_space(tok)) - continue; - tcc_warning("pasting <%.*s> and <%s> does not give a valid preprocessing token", - n, cstr.data, (char*)cstr.data + n); - break; - } - tcc_close(); - - //printf("paste <%s>\n", (char*)cstr.data); - cstr_free(&cstr); - return 0; -} - -/* handle the '##' operator. Return NULL if no '##' seen. Otherwise - return the resulting string (which must be freed). */ -static inline int *macro_twosharps(const int *ptr0) -{ - int t; - CValue cval; - TokenString macro_str1; - int start_of_nosubsts = -1; - const int *ptr; - - /* we search the first '##' */ - for (ptr = ptr0;;) { - TOK_GET(&t, &ptr, &cval); - if (t == TOK_TWOSHARPS) - break; - if (t == 0) - return NULL; - } - - tok_str_new(¯o_str1); - - //tok_print(" $$$", ptr0); - for (ptr = ptr0;;) { - TOK_GET(&t, &ptr, &cval); - if (t == 0) - break; - if (t == TOK_TWOSHARPS) - continue; - while (*ptr == TOK_TWOSHARPS) { - int t1; CValue cv1; - /* given 'a##b', remove nosubsts preceding 'a' */ - if (start_of_nosubsts >= 0) - macro_str1.len = start_of_nosubsts; - /* given 'a##b', remove nosubsts preceding 'b' */ - while ((t1 = *++ptr) == TOK_NOSUBST) - ; - if (t1 && t1 != TOK_TWOSHARPS - && t1 != ':') /* 'a##:' don't build a new token */ - { - TOK_GET(&t1, &ptr, &cv1); - if (t != TOK_PLCHLDR || t1 != TOK_PLCHLDR) { - paste_tokens(t, &cval, t1, &cv1); - t = tok, cval = tokc; - } - } - } - if (t == TOK_NOSUBST) { - if (start_of_nosubsts < 0) - start_of_nosubsts = macro_str1.len; - } else { - start_of_nosubsts = -1; - } - tok_str_add2(¯o_str1, t, &cval); - } - tok_str_add(¯o_str1, 0); - //tok_print(" ###", macro_str1.str); - return macro_str1.str; -} - -/* do macro substitution of macro_str and add result to - (tok_str,tok_len). 'nested_list' is the list of all macros we got - inside to avoid recursing. */ -static void macro_subst( - TokenString *tok_str, - Sym **nested_list, - const int *macro_str, - int can_read_stream - ) -{ - Sym *s; - const int *ptr; - int t, spc, nosubst; - CValue cval; - int *macro_str1 = NULL; - - /* first scan for '##' operator handling */ - ptr = macro_str; - spc = nosubst = 0; - - /* first scan for '##' operator handling */ - if (can_read_stream) { - macro_str1 = macro_twosharps(ptr); - if (macro_str1) - ptr = macro_str1; - } - - while (1) { - TOK_GET(&t, &ptr, &cval); - if (t == 0) - break; - - if (t >= TOK_IDENT && 0 == nosubst) { - s = define_find(t); - if (s == NULL) - goto no_subst; - - /* if nested substitution, do nothing */ - if (sym_find2(*nested_list, t)) { - /* and mark it as TOK_NOSUBST, so it doesn't get subst'd again */ - tok_str_add2(tok_str, TOK_NOSUBST, NULL); - goto no_subst; - } - - { - TokenString str; - str.str = (int*)ptr; - begin_macro(&str, 2); - - tok = t; - macro_subst_tok(tok_str, nested_list, s, can_read_stream); - - if (str.alloc == 3) { - /* already finished by reading function macro arguments */ - break; - } - - ptr = macro_ptr; - end_macro (); - } - - spc = (tok_str->len && - is_space(tok_last(tok_str->str, - tok_str->str + tok_str->len))); - - } else { - - if (t == '\\' && !(parse_flags & PARSE_FLAG_ACCEPT_STRAYS)) - tcc_error("stray '\\' in program"); - -no_subst: - if (!check_space(t, &spc)) - tok_str_add2(tok_str, t, &cval); - nosubst = 0; - if (t == TOK_NOSUBST) - nosubst = 1; - } - } - if (macro_str1) - tok_str_free(macro_str1); - -} - -/* return next token with macro substitution */ -ST_FUNC void next(void) -{ - redo: - if (parse_flags & PARSE_FLAG_SPACES) - next_nomacro_spc(); - else - next_nomacro(); - - if (macro_ptr) { - if (tok == TOK_NOSUBST || tok == TOK_PLCHLDR) { - /* discard preprocessor markers */ - goto redo; - } else if (tok == 0) { - /* end of macro or unget token string */ - end_macro(); - goto redo; - } - } else if (tok >= TOK_IDENT && (parse_flags & PARSE_FLAG_PREPROCESS)) { - Sym *s; - /* if reading from file, try to substitute macros */ - s = define_find(tok); - if (s) { - static TokenString str; /* using static string for speed */ - Sym *nested_list = NULL; - tok_str_new(&str); - nested_list = NULL; - macro_subst_tok(&str, &nested_list, s, 1); - tok_str_add(&str, 0); - begin_macro(&str, 0); - goto redo; - } - } - /* convert preprocessor tokens into C tokens */ - if (tok == TOK_PPNUM) { - if (parse_flags & PARSE_FLAG_TOK_NUM) - parse_number((char *)tokc.str.data); - } else if (tok == TOK_PPSTR) { - if (parse_flags & PARSE_FLAG_TOK_STR) - parse_string((char *)tokc.str.data, tokc.str.size - 1); - } -} - -/* push back current token and set current token to 'last_tok'. Only - identifier case handled for labels. */ -ST_INLN void unget_tok(int last_tok) -{ - TokenString *str = tcc_malloc(sizeof *str); - tok_str_new(str); - tok_str_add2(str, tok, &tokc); - tok_str_add(str, 0); - begin_macro(str, 1); - tok = last_tok; -} - -/* better than nothing, but needs extension to handle '-E' option - correctly too */ -ST_FUNC void preprocess_init(TCCState *s1) -{ - s1->include_stack_ptr = s1->include_stack; - /* XXX: move that before to avoid having to initialize - file->ifdef_stack_ptr ? */ - s1->ifdef_stack_ptr = s1->ifdef_stack; - file->ifdef_stack_ptr = s1->ifdef_stack_ptr; - - pvtop = vtop = vstack - 1; - s1->pack_stack[0] = 0; - s1->pack_stack_ptr = s1->pack_stack; - - isidnum_table['$' - CH_EOF] = (parse_flags & PARSE_FLAG_ASM_FILE) || - tcc_state->dollars_in_identifiers ? IS_ID : 0; - isidnum_table['.' - CH_EOF] = (parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0; -} - -ST_FUNC void preprocess_new(void) -{ - int i, c; - const char *p, *r; - - /* init isid table */ - for(i = CH_EOF; i<256; i++) - isidnum_table[i - CH_EOF] - = is_space(i) ? IS_SPC - : isid(i) ? IS_ID - : isnum(i) ? IS_NUM - : 0; - - memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *)); - - tok_ident = TOK_IDENT; - p = tcc_keywords; - while (*p) { - r = p; - for(;;) { - c = *r++; - if (c == '\0') - break; - } - tok_alloc(p, r - p - 1); - p = r; - } -} - -ST_FUNC void preprocess_delete(void) -{ - int i, n; - - /* free -D and compiler defines */ - free_defines(NULL); - - /* cleanup from error/setjmp */ - while (macro_stack) - end_macro(); - macro_ptr = NULL; - - /* free tokens */ - n = tok_ident - TOK_IDENT; - for(i = 0; i < n; i++) - tcc_free(table_ident[i]); - tcc_free(table_ident); - table_ident = NULL; -} - -/* Preprocess the current file */ -ST_FUNC int tcc_preprocess(TCCState *s1) -{ - BufferedFile **iptr; - int token_seen, spcs, level; - - preprocess_init(s1); - ch = file->buf_ptr[0]; - tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; - parse_flags = PARSE_FLAG_PREPROCESS - | (parse_flags & PARSE_FLAG_ASM_FILE) - | PARSE_FLAG_LINEFEED - | PARSE_FLAG_SPACES - | PARSE_FLAG_ACCEPT_STRAYS - ; - -#ifdef PP_BENCH - do next(); while (tok != TOK_EOF); return 0; -#endif - - token_seen = spcs = 0; - pp_line(s1, file, 0); - - for (;;) { - iptr = s1->include_stack_ptr; - next(); - if (tok == TOK_EOF) - break; - level = s1->include_stack_ptr - iptr; - if (level) { - if (level > 0) - pp_line(s1, *iptr, 0); - pp_line(s1, file, level); - } - - if (0 == token_seen) { - if (tok == ' ') { - ++spcs; - continue; - } - if (tok == TOK_LINEFEED) { - spcs = 0; - continue; - } - pp_line(s1, file, 0); - while (spcs) - fputs(" ", s1->ppfp), --spcs; - token_seen = 1; - - } else if (tok == TOK_LINEFEED) { - ++file->line_ref; - token_seen = 0; - } - - fputs(get_tok_str(tok, &tokc), s1->ppfp); - } - - return 0; -} diff --git a/external/TCC/tccrun.c b/external/TCC/tccrun.c deleted file mode 100644 index 25191053..00000000 --- a/external/TCC/tccrun.c +++ /dev/null @@ -1,772 +0,0 @@ -/* - * TCC - Tiny C Compiler - Support for -run switch - * - * Copyright (c) 2001-2004 Fabrice Bellard - * - * 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "tcc.h" - -/* only native compiler supports -run */ -#ifdef TCC_IS_NATIVE - -#ifdef CONFIG_TCC_BACKTRACE -ST_DATA int rt_num_callers = 6; -ST_DATA const char **rt_bound_error_msg; -ST_DATA void *rt_prog_main; -#endif - -#ifdef _WIN32 -#define ucontext_t CONTEXT -#endif - -static void set_pages_executable(void *ptr, unsigned long length); -static void set_exception_handler(void); -static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level); -static void rt_error(ucontext_t *uc, const char *fmt, ...); -static int tcc_relocate_ex(TCCState *s1, void *ptr); - -#ifdef _WIN64 -static void win64_add_function_table(TCCState *s1); -#endif - -/* ------------------------------------------------------------- */ -/* Do all relocations (needed before using tcc_get_symbol()) - Returns -1 on error. */ - -LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr) -{ - int ret; - - if (TCC_RELOCATE_AUTO != ptr) - return tcc_relocate_ex(s1, ptr); - - ret = tcc_relocate_ex(s1, NULL); - if (ret < 0) - return ret; - -#ifdef HAVE_SELINUX - { /* Use mmap instead of malloc for Selinux. Ref: - http://www.gnu.org/s/libc/manual/html_node/File-Size.html */ - - char tmpfname[] = "/tmp/.tccrunXXXXXX"; - int fd = mkstemp (tmpfname); - - s1->mem_size = ret; - unlink (tmpfname); - ftruncate (fd, s1->mem_size); - - s1->write_mem = mmap (NULL, ret, PROT_READ|PROT_WRITE, - MAP_SHARED, fd, 0); - if (s1->write_mem == MAP_FAILED) - tcc_error("/tmp not writeable"); - - s1->runtime_mem = mmap (NULL, ret, PROT_READ|PROT_EXEC, - MAP_SHARED, fd, 0); - if (s1->runtime_mem == MAP_FAILED) - tcc_error("/tmp not executable"); - - ret = tcc_relocate_ex(s1, s1->write_mem); - } -#else - s1->runtime_mem = tcc_malloc(ret); - ret = tcc_relocate_ex(s1, s1->runtime_mem); -#endif - return ret; -} - -/* launch the compiled program with the given arguments */ -LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) -{ - int (*prog_main)(int, char **); - int ret; - - if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0) - return -1; - - prog_main = tcc_get_symbol_err(s1, s1->runtime_main); - -#ifdef CONFIG_TCC_BACKTRACE - if (s1->do_debug) { - set_exception_handler(); - rt_prog_main = prog_main; - } -#endif - -#ifdef CONFIG_TCC_BCHECK - if (s1->do_bounds_check) { - void (*bound_init)(void); - void (*bound_exit)(void); - void (*bound_new_region)(void *p, addr_t size); - int (*bound_delete_region)(void *p); - int i; - - /* set error function */ - rt_bound_error_msg = tcc_get_symbol_err(s1, "__bound_error_msg"); - /* XXX: use .init section so that it also work in binary ? */ - bound_init = tcc_get_symbol_err(s1, "__bound_init"); - bound_exit = tcc_get_symbol_err(s1, "__bound_exit"); - bound_new_region = tcc_get_symbol_err(s1, "__bound_new_region"); - bound_delete_region = tcc_get_symbol_err(s1, "__bound_delete_region"); - bound_init(); - /* mark argv area as valid */ - bound_new_region(argv, argc*sizeof(argv[0])); - for (i=0; inb_errors = 0; -#ifdef TCC_TARGET_PE - pe_output_file(s1, NULL); -#else - tcc_add_runtime(s1); - relocate_common_syms(); - tcc_add_linker_symbols(s1); - build_got_entries(s1); -#endif - if (s1->nb_errors) - return -1; - } - - offset = 0, mem = (addr_t)ptr; - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; - if (0 == (s->sh_flags & SHF_ALLOC)) - continue; - length = s->data_offset; - s->sh_addr = mem ? (mem + offset + 15) & ~15 : 0; - offset = (offset + length + 15) & ~15; - } - offset += 16; - - /* relocate symbols */ - relocate_syms(s1, 1); - if (s1->nb_errors) - return -1; - - if (0 == mem) - return offset; - - /* relocate each section */ - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; - if (s->reloc) - relocate_section(s1, s); - } - relocate_plt(s1); - - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; - if (0 == (s->sh_flags & SHF_ALLOC)) - continue; - length = s->data_offset; - // printf("%-12s %08lx %04x\n", s->name, s->sh_addr, length); - ptr = (void*)s->sh_addr; - if (NULL == s->data || s->sh_type == SHT_NOBITS) - memset(ptr, 0, length); - else - memcpy(ptr, s->data, length); - /* mark executable sections as executable in memory */ - if (s->sh_flags & SHF_EXECINSTR) - set_pages_executable(ptr, length); - } - -#ifdef _WIN64 - win64_add_function_table(s1); -#endif - return 0; -} - -/* ------------------------------------------------------------- */ -/* allow to run code in memory */ - -static void set_pages_executable(void *ptr, unsigned long length) -{ -#ifdef _WIN32 - unsigned long old_protect; - VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect); -#else - extern void __clear_cache(void *beginning, void *end); -#ifndef PAGESIZE -# define PAGESIZE 4096 -#endif - addr_t start, end; - start = (addr_t)ptr & ~(PAGESIZE - 1); - end = (addr_t)ptr + length; - end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1); - mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC); - __clear_cache(ptr, (char *)ptr + length); -#endif -} - -/* ------------------------------------------------------------- */ -#ifdef CONFIG_TCC_BACKTRACE - -ST_FUNC void tcc_set_num_callers(int n) -{ - rt_num_callers = n; -} - -/* print the position in the source file of PC value 'pc' by reading - the stabs debug information */ -static addr_t rt_printline(addr_t wanted_pc, const char *msg) -{ - char func_name[128], last_func_name[128]; - addr_t func_addr, last_pc, pc; - const char *incl_files[INCLUDE_STACK_SIZE]; - int incl_index, len, last_line_num, i; - const char *str, *p; - - Stab_Sym *stab_sym = NULL, *stab_sym_end, *sym; - int stab_len = 0; - char *stab_str = NULL; - - if (stab_section) { - stab_len = stab_section->data_offset; - stab_sym = (Stab_Sym *)stab_section->data; - stab_str = (char *) stabstr_section->data; - } - - func_name[0] = '\0'; - func_addr = 0; - incl_index = 0; - last_func_name[0] = '\0'; - last_pc = (addr_t)-1; - last_line_num = 1; - - if (!stab_sym) - goto no_stabs; - - stab_sym_end = (Stab_Sym*)((char*)stab_sym + stab_len); - for (sym = stab_sym + 1; sym < stab_sym_end; ++sym) { - switch(sym->n_type) { - /* function start or end */ - case N_FUN: - if (sym->n_strx == 0) { - /* we test if between last line and end of function */ - pc = sym->n_value + func_addr; - if (wanted_pc >= last_pc && wanted_pc < pc) - goto found; - func_name[0] = '\0'; - func_addr = 0; - } else { - str = stab_str + sym->n_strx; - p = strchr(str, ':'); - if (!p) { - pstrcpy(func_name, sizeof(func_name), str); - } else { - len = p - str; - if (len > sizeof(func_name) - 1) - len = sizeof(func_name) - 1; - memcpy(func_name, str, len); - func_name[len] = '\0'; - } - func_addr = sym->n_value; - } - break; - /* line number info */ - case N_SLINE: - pc = sym->n_value + func_addr; - if (wanted_pc >= last_pc && wanted_pc < pc) - goto found; - last_pc = pc; - last_line_num = sym->n_desc; - /* XXX: slow! */ - strcpy(last_func_name, func_name); - break; - /* include files */ - case N_BINCL: - str = stab_str + sym->n_strx; - add_incl: - if (incl_index < INCLUDE_STACK_SIZE) { - incl_files[incl_index++] = str; - } - break; - case N_EINCL: - if (incl_index > 1) - incl_index--; - break; - case N_SO: - if (sym->n_strx == 0) { - incl_index = 0; /* end of translation unit */ - } else { - str = stab_str + sym->n_strx; - /* do not add path */ - len = strlen(str); - if (len > 0 && str[len - 1] != '/') - goto add_incl; - } - break; - } - } - -no_stabs: - /* second pass: we try symtab symbols (no line number info) */ - incl_index = 0; - if (symtab_section) - { - ElfW(Sym) *sym, *sym_end; - int type; - - sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset); - for(sym = (ElfW(Sym) *)symtab_section->data + 1; - sym < sym_end; - sym++) { - type = ELFW(ST_TYPE)(sym->st_info); - if (type == STT_FUNC || type == STT_GNU_IFUNC) { - if (wanted_pc >= sym->st_value && - wanted_pc < sym->st_value + sym->st_size) { - pstrcpy(last_func_name, sizeof(last_func_name), - (char *) strtab_section->data + sym->st_name); - func_addr = sym->st_value; - goto found; - } - } - } - } - /* did not find any info: */ - fprintf(stderr, "%s %p ???\n", msg, (void*)wanted_pc); - fflush(stderr); - return 0; - found: - i = incl_index; - if (i > 0) - fprintf(stderr, "%s:%d: ", incl_files[--i], last_line_num); - fprintf(stderr, "%s %p", msg, (void*)wanted_pc); - if (last_func_name[0] != '\0') - fprintf(stderr, " %s()", last_func_name); - if (--i >= 0) { - fprintf(stderr, " (included from "); - for (;;) { - fprintf(stderr, "%s", incl_files[i]); - if (--i < 0) - break; - fprintf(stderr, ", "); - } - fprintf(stderr, ")"); - } - fprintf(stderr, "\n"); - fflush(stderr); - return func_addr; -} - -/* emit a run time error at position 'pc' */ -static void rt_error(ucontext_t *uc, const char *fmt, ...) -{ - va_list ap; - addr_t pc; - int i; - - fprintf(stderr, "Runtime error: "); - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fprintf(stderr, "\n"); - - for(i=0;isi_code) { - case FPE_INTDIV: - case FPE_FLTDIV: - rt_error(uc, "division by zero"); - break; - default: - rt_error(uc, "floating point exception"); - break; - } - break; - case SIGBUS: - case SIGSEGV: - if (rt_bound_error_msg && *rt_bound_error_msg) - rt_error(uc, *rt_bound_error_msg); - else - rt_error(uc, "dereferencing invalid pointer"); - break; - case SIGILL: - rt_error(uc, "illegal instruction"); - break; - case SIGABRT: - rt_error(uc, "abort() called"); - break; - default: - rt_error(uc, "caught signal %d", signum); - break; - } - exit(255); -} - -#ifndef SA_SIGINFO -# define SA_SIGINFO 0x00000004u -#endif - -/* Generate a stack backtrace when a CPU exception occurs. */ -static void set_exception_handler(void) -{ - struct sigaction sigact; - /* install TCC signal handlers to print debug info on fatal - runtime errors */ - sigact.sa_flags = SA_SIGINFO | SA_RESETHAND; - sigact.sa_sigaction = sig_error; - sigemptyset(&sigact.sa_mask); - sigaction(SIGFPE, &sigact, NULL); - sigaction(SIGILL, &sigact, NULL); - sigaction(SIGSEGV, &sigact, NULL); - sigaction(SIGBUS, &sigact, NULL); - sigaction(SIGABRT, &sigact, NULL); -} - -/* ------------------------------------------------------------- */ -#ifdef __i386__ - -/* fix for glibc 2.1 */ -#ifndef REG_EIP -#define REG_EIP EIP -#define REG_EBP EBP -#endif - -/* return the PC at frame level 'level'. Return negative if not found */ -static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level) -{ - addr_t fp; - int i; - - if (level == 0) { -#if defined(__APPLE__) - *paddr = uc->uc_mcontext->__ss.__eip; -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) - *paddr = uc->uc_mcontext.mc_eip; -#elif defined(__dietlibc__) - *paddr = uc->uc_mcontext.eip; -#elif defined(__NetBSD__) - *paddr = uc->uc_mcontext.__gregs[_REG_EIP]; -#else - *paddr = uc->uc_mcontext.gregs[REG_EIP]; -#endif - return 0; - } else { -#if defined(__APPLE__) - fp = uc->uc_mcontext->__ss.__ebp; -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) - fp = uc->uc_mcontext.mc_ebp; -#elif defined(__dietlibc__) - fp = uc->uc_mcontext.ebp; -#elif defined(__NetBSD__) - fp = uc->uc_mcontext.__gregs[_REG_EBP]; -#else - fp = uc->uc_mcontext.gregs[REG_EBP]; -#endif - for(i=1;i= 0xc0000000) - return -1; - fp = ((addr_t *)fp)[0]; - } - *paddr = ((addr_t *)fp)[1]; - return 0; - } -} - -/* ------------------------------------------------------------- */ -#elif defined(__x86_64__) - -/* return the PC at frame level 'level'. Return negative if not found */ -static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level) -{ - addr_t fp; - int i; - - if (level == 0) { - /* XXX: only support linux */ -#if defined(__APPLE__) - *paddr = uc->uc_mcontext->__ss.__rip; -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) - *paddr = uc->uc_mcontext.mc_rip; -#elif defined(__NetBSD__) - *paddr = uc->uc_mcontext.__gregs[_REG_RIP]; -#else - *paddr = uc->uc_mcontext.gregs[REG_RIP]; -#endif - return 0; - } else { -#if defined(__APPLE__) - fp = uc->uc_mcontext->__ss.__rbp; -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) - fp = uc->uc_mcontext.mc_rbp; -#elif defined(__NetBSD__) - fp = uc->uc_mcontext.__gregs[_REG_RBP]; -#else - fp = uc->uc_mcontext.gregs[REG_RBP]; -#endif - for(i=1;iuc_mcontext.arm_pc; -#else - return -1; -#endif - return 0; - } else { -#if defined(__linux__) - fp = uc->uc_mcontext.arm_fp; - sp = uc->uc_mcontext.arm_sp; - if (sp < 0x1000) - sp = 0x1000; -#else - return -1; -#endif - /* XXX: specific to tinycc stack frames */ - if (fp < sp + 12 || fp & 3) - return -1; - for(i = 1; i < level; i++) { - sp = ((addr_t *)fp)[-2]; - if (sp < fp || sp - fp > 16 || sp & 3) - return -1; - fp = ((addr_t *)fp)[-3]; - if (fp <= sp || fp - sp < 12 || fp & 3) - return -1; - } - /* XXX: check address validity with program info */ - *paddr = ((addr_t *)fp)[-1]; - return 0; - } -} - -/* ------------------------------------------------------------- */ -#elif defined(__aarch64__) - -static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level) -{ - if (level < 0) - return -1; - else if (level == 0) { - *paddr = uc->uc_mcontext.pc; - return 0; - } - else { - addr_t *fp = (addr_t *)uc->uc_mcontext.regs[29]; - int i; - for (i = 1; i < level; i++) - fp = (addr_t *)fp[0]; - *paddr = fp[1]; - return 0; - } -} - -/* ------------------------------------------------------------- */ -#else - -#warning add arch specific rt_get_caller_pc() -static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level) -{ - return -1; -} - -#endif /* !__i386__ */ - -/* ------------------------------------------------------------- */ -#else /* WIN32 */ - -static long __stdcall cpu_exception_handler(EXCEPTION_POINTERS *ex_info) -{ - EXCEPTION_RECORD *er = ex_info->ExceptionRecord; - CONTEXT *uc = ex_info->ContextRecord; - switch (er->ExceptionCode) { - case EXCEPTION_ACCESS_VIOLATION: - if (rt_bound_error_msg && *rt_bound_error_msg) - rt_error(uc, *rt_bound_error_msg); - else - rt_error(uc, "access violation"); - break; - case EXCEPTION_STACK_OVERFLOW: - rt_error(uc, "stack overflow"); - break; - case EXCEPTION_INT_DIVIDE_BY_ZERO: - rt_error(uc, "division by zero"); - break; - default: - rt_error(uc, "exception caught"); - break; - } - return EXCEPTION_EXECUTE_HANDLER; -} - -/* Generate a stack backtrace when a CPU exception occurs. */ -static void set_exception_handler(void) -{ - SetUnhandledExceptionFilter(cpu_exception_handler); -} - -#ifdef _WIN64 -static void win64_add_function_table(TCCState *s1) -{ - RtlAddFunctionTable( - (RUNTIME_FUNCTION*)s1->uw_pdata->sh_addr, - s1->uw_pdata->data_offset / sizeof (RUNTIME_FUNCTION), - text_section->sh_addr - ); -} -#endif - -/* return the PC at frame level 'level'. Return non zero if not found */ -static int rt_get_caller_pc(addr_t *paddr, CONTEXT *uc, int level) -{ - addr_t fp, pc; - int i; -#ifdef _WIN64 - pc = uc->Rip; - fp = uc->Rbp; -#else - pc = uc->Eip; - fp = uc->Ebp; -#endif - if (level > 0) { - for(i=1;i= 0xc0000000) - return -1; - fp = ((addr_t*)fp)[0]; - } - pc = ((addr_t*)fp)[1]; - } - *paddr = pc; - return 0; -} - -#endif /* _WIN32 */ -#endif /* CONFIG_TCC_BACKTRACE */ -/* ------------------------------------------------------------- */ -#ifdef CONFIG_TCC_STATIC - -/* dummy function for profiling */ -ST_FUNC void *dlopen(const char *filename, int flag) -{ - return NULL; -} - -ST_FUNC void dlclose(void *p) -{ -} - -ST_FUNC const char *dlerror(void) -{ - return "error"; -} - -typedef struct TCCSyms { - char *str; - void *ptr; -} TCCSyms; - - -/* add the symbol you want here if no dynamic linking is done */ -static TCCSyms tcc_syms[] = { -#if !defined(CONFIG_TCCBOOT) -#define TCCSYM(a) { #a, &a, }, - TCCSYM(printf) - TCCSYM(fprintf) - TCCSYM(fopen) - TCCSYM(fclose) -#undef TCCSYM -#endif - { NULL, NULL }, -}; - -ST_FUNC void *resolve_sym(TCCState *s1, const char *symbol) -{ - TCCSyms *p; - p = tcc_syms; - while (p->str != NULL) { - if (!strcmp(p->str, symbol)) - return p->ptr; - p++; - } - return NULL; -} - -#elif !defined(_WIN32) - -ST_FUNC void *resolve_sym(TCCState *s1, const char *sym) -{ - return dlsym(RTLD_DEFAULT, sym); -} - -#endif /* CONFIG_TCC_STATIC */ -#endif /* TCC_IS_NATIVE */ -/* ------------------------------------------------------------- */ diff --git a/external/TCC/tcctok.h b/external/TCC/tcctok.h deleted file mode 100644 index b2fbebf6..00000000 --- a/external/TCC/tcctok.h +++ /dev/null @@ -1,341 +0,0 @@ -/* keywords */ - DEF(TOK_INT, "int") - DEF(TOK_VOID, "void") - DEF(TOK_CHAR, "char") - DEF(TOK_IF, "if") - DEF(TOK_ELSE, "else") - DEF(TOK_WHILE, "while") - DEF(TOK_BREAK, "break") - DEF(TOK_RETURN, "return") - DEF(TOK_FOR, "for") - DEF(TOK_EXTERN, "extern") - DEF(TOK_STATIC, "static") - DEF(TOK_UNSIGNED, "unsigned") - DEF(TOK_GOTO, "goto") - DEF(TOK_DO, "do") - DEF(TOK_CONTINUE, "continue") - DEF(TOK_SWITCH, "switch") - DEF(TOK_CASE, "case") - - DEF(TOK_CONST1, "const") - DEF(TOK_CONST2, "__const") /* gcc keyword */ - DEF(TOK_CONST3, "__const__") /* gcc keyword */ - DEF(TOK_VOLATILE1, "volatile") - DEF(TOK_VOLATILE2, "__volatile") /* gcc keyword */ - DEF(TOK_VOLATILE3, "__volatile__") /* gcc keyword */ - DEF(TOK_LONG, "long") - DEF(TOK_REGISTER, "register") - DEF(TOK_SIGNED1, "signed") - DEF(TOK_SIGNED2, "__signed") /* gcc keyword */ - DEF(TOK_SIGNED3, "__signed__") /* gcc keyword */ - DEF(TOK_AUTO, "auto") - DEF(TOK_INLINE1, "inline") - DEF(TOK_INLINE2, "__inline") /* gcc keyword */ - DEF(TOK_INLINE3, "__inline__") /* gcc keyword */ - DEF(TOK_RESTRICT1, "restrict") - DEF(TOK_RESTRICT2, "__restrict") - DEF(TOK_RESTRICT3, "__restrict__") - DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */ - - DEF(TOK_FLOAT, "float") - DEF(TOK_DOUBLE, "double") - DEF(TOK_BOOL, "_Bool") - DEF(TOK_SHORT, "short") - DEF(TOK_STRUCT, "struct") - DEF(TOK_UNION, "union") - DEF(TOK_TYPEDEF, "typedef") - DEF(TOK_DEFAULT, "default") - DEF(TOK_ENUM, "enum") - DEF(TOK_SIZEOF, "sizeof") - DEF(TOK_ATTRIBUTE1, "__attribute") - DEF(TOK_ATTRIBUTE2, "__attribute__") - DEF(TOK_ALIGNOF1, "__alignof") - DEF(TOK_ALIGNOF2, "__alignof__") - DEF(TOK_TYPEOF1, "typeof") - DEF(TOK_TYPEOF2, "__typeof") - DEF(TOK_TYPEOF3, "__typeof__") - DEF(TOK_LABEL, "__label__") - DEF(TOK_ASM1, "asm") - DEF(TOK_ASM2, "__asm") - DEF(TOK_ASM3, "__asm__") - -#ifdef TCC_TARGET_ARM64 - DEF(TOK_UINT128, "__uint128_t") -#endif - -/*********************************************************************/ -/* the following are not keywords. They are included to ease parsing */ -/* preprocessor only */ - DEF(TOK_DEFINE, "define") - DEF(TOK_INCLUDE, "include") - DEF(TOK_INCLUDE_NEXT, "include_next") - DEF(TOK_IFDEF, "ifdef") - DEF(TOK_IFNDEF, "ifndef") - DEF(TOK_ELIF, "elif") - DEF(TOK_ENDIF, "endif") - DEF(TOK_DEFINED, "defined") - DEF(TOK_UNDEF, "undef") - DEF(TOK_ERROR, "error") - DEF(TOK_WARNING, "warning") - DEF(TOK_LINE, "line") - DEF(TOK_PRAGMA, "pragma") - DEF(TOK___LINE__, "__LINE__") - DEF(TOK___FILE__, "__FILE__") - DEF(TOK___DATE__, "__DATE__") - DEF(TOK___TIME__, "__TIME__") - DEF(TOK___FUNCTION__, "__FUNCTION__") - DEF(TOK___VA_ARGS__, "__VA_ARGS__") - -/* special identifiers */ - DEF(TOK___FUNC__, "__func__") - -/* special floating point values */ - DEF(TOK___NAN__, "__nan__") - DEF(TOK___SNAN__, "__snan__") - DEF(TOK___INF__, "__inf__") - -/* attribute identifiers */ -/* XXX: handle all tokens generically since speed is not critical */ - DEF(TOK_SECTION1, "section") - DEF(TOK_SECTION2, "__section__") - DEF(TOK_ALIGNED1, "aligned") - DEF(TOK_ALIGNED2, "__aligned__") - DEF(TOK_PACKED1, "packed") - DEF(TOK_PACKED2, "__packed__") - DEF(TOK_WEAK1, "weak") - DEF(TOK_WEAK2, "__weak__") - DEF(TOK_ALIAS1, "alias") - DEF(TOK_ALIAS2, "__alias__") - DEF(TOK_UNUSED1, "unused") - DEF(TOK_UNUSED2, "__unused__") - DEF(TOK_CDECL1, "cdecl") - DEF(TOK_CDECL2, "__cdecl") - DEF(TOK_CDECL3, "__cdecl__") - DEF(TOK_STDCALL1, "stdcall") - DEF(TOK_STDCALL2, "__stdcall") - DEF(TOK_STDCALL3, "__stdcall__") - DEF(TOK_FASTCALL1, "fastcall") - DEF(TOK_FASTCALL2, "__fastcall") - DEF(TOK_FASTCALL3, "__fastcall__") - DEF(TOK_MODE, "__mode__") - DEF(TOK_MODE_DI, "__DI__") - DEF(TOK_MODE_HI, "__HI__") - DEF(TOK_MODE_SI, "__SI__") - DEF(TOK_DLLEXPORT, "dllexport") - DEF(TOK_DLLIMPORT, "dllimport") - DEF(TOK_NORETURN1, "noreturn") - DEF(TOK_NORETURN2, "__noreturn__") - DEF(TOK_VISIBILITY1, "visibility") - DEF(TOK_VISIBILITY2, "__visibility__") - DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p") - DEF(TOK_builtin_constant_p, "__builtin_constant_p") - DEF(TOK_builtin_frame_address, "__builtin_frame_address") - DEF(TOK_builtin_return_address, "__builtin_return_address") -#ifdef TCC_TARGET_X86_64 -#ifdef TCC_TARGET_PE - DEF(TOK_builtin_va_start, "__builtin_va_start") -#else - DEF(TOK_builtin_va_arg_types, "__builtin_va_arg_types") -#endif -#endif - DEF(TOK_REGPARM1, "regparm") - DEF(TOK_REGPARM2, "__regparm__") - -#ifdef TCC_TARGET_ARM64 - DEF(TOK___va_start, "__va_start") - DEF(TOK___va_arg, "__va_arg") -#endif - -/* pragma */ - DEF(TOK_pack, "pack") -#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_X86_64) - /* already defined for assembler */ - DEF(TOK_ASM_push, "push") - DEF(TOK_ASM_pop, "pop") -#endif - DEF(TOK_comment, "comment") - DEF(TOK_lib, "lib") - DEF(TOK_push_macro, "push_macro") - DEF(TOK_pop_macro, "pop_macro") - DEF(TOK_once, "once") - -/* builtin functions or variables */ -#ifndef TCC_ARM_EABI - DEF(TOK_memcpy, "memcpy") - DEF(TOK_memmove, "memmove") - DEF(TOK_memset, "memset") - DEF(TOK___divdi3, "__divdi3") - DEF(TOK___moddi3, "__moddi3") - DEF(TOK___udivdi3, "__udivdi3") - DEF(TOK___umoddi3, "__umoddi3") - DEF(TOK___ashrdi3, "__ashrdi3") - DEF(TOK___lshrdi3, "__lshrdi3") - DEF(TOK___ashldi3, "__ashldi3") - DEF(TOK___floatundisf, "__floatundisf") - DEF(TOK___floatundidf, "__floatundidf") -# ifndef TCC_ARM_VFP - DEF(TOK___floatundixf, "__floatundixf") - DEF(TOK___fixunsxfdi, "__fixunsxfdi") -# endif - DEF(TOK___fixunssfdi, "__fixunssfdi") - DEF(TOK___fixunsdfdi, "__fixunsdfdi") -#endif - -#if defined TCC_TARGET_ARM -# ifdef TCC_ARM_EABI - DEF(TOK_memcpy, "__aeabi_memcpy") - DEF(TOK_memcpy4, "__aeabi_memcpy4") - DEF(TOK_memcpy8, "__aeabi_memcpy8") - DEF(TOK_memmove, "__aeabi_memmove") - DEF(TOK_memset, "__aeabi_memset") - DEF(TOK___aeabi_ldivmod, "__aeabi_ldivmod") - DEF(TOK___aeabi_uldivmod, "__aeabi_uldivmod") - DEF(TOK___aeabi_idivmod, "__aeabi_idivmod") - DEF(TOK___aeabi_uidivmod, "__aeabi_uidivmod") - DEF(TOK___divsi3, "__aeabi_idiv") - DEF(TOK___udivsi3, "__aeabi_uidiv") - DEF(TOK___floatdisf, "__aeabi_l2f") - DEF(TOK___floatdidf, "__aeabi_l2d") - DEF(TOK___fixsfdi, "__aeabi_f2lz") - DEF(TOK___fixdfdi, "__aeabi_d2lz") - DEF(TOK___ashrdi3, "__aeabi_lasr") - DEF(TOK___lshrdi3, "__aeabi_llsr") - DEF(TOK___ashldi3, "__aeabi_llsl") - DEF(TOK___floatundisf, "__aeabi_ul2f") - DEF(TOK___floatundidf, "__aeabi_ul2d") - DEF(TOK___fixunssfdi, "__aeabi_f2ulz") - DEF(TOK___fixunsdfdi, "__aeabi_d2ulz") -# else - DEF(TOK___modsi3, "__modsi3") - DEF(TOK___umodsi3, "__umodsi3") - DEF(TOK___divsi3, "__divsi3") - DEF(TOK___udivsi3, "__udivsi3") - DEF(TOK___floatdisf, "__floatdisf") - DEF(TOK___floatdidf, "__floatdidf") -# ifndef TCC_ARM_VFP - DEF(TOK___floatdixf, "__floatdixf") - DEF(TOK___fixunssfsi, "__fixunssfsi") - DEF(TOK___fixunsdfsi, "__fixunsdfsi") - DEF(TOK___fixunsxfsi, "__fixunsxfsi") - DEF(TOK___fixxfdi, "__fixxfdi") -# endif - DEF(TOK___fixsfdi, "__fixsfdi") - DEF(TOK___fixdfdi, "__fixdfdi") -# endif -#endif - -#if defined TCC_TARGET_C67 - DEF(TOK__divi, "_divi") - DEF(TOK__divu, "_divu") - DEF(TOK__divf, "_divf") - DEF(TOK__divd, "_divd") - DEF(TOK__remi, "_remi") - DEF(TOK__remu, "_remu") -#endif - -#if defined TCC_TARGET_I386 - DEF(TOK___fixsfdi, "__fixsfdi") - DEF(TOK___fixdfdi, "__fixdfdi") - DEF(TOK___fixxfdi, "__fixxfdi") - - #ifndef COMMIT_4ad186c5ef61_IS_FIXED - DEF(TOK___tcc_cvt_ftol, "__tcc_cvt_ftol") - #endif -#endif - -#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 - DEF(TOK_alloca, "alloca") -#endif - -#if defined TCC_TARGET_PE - DEF(TOK___chkstk, "__chkstk") -#endif -#ifdef TCC_TARGET_ARM64 - DEF(TOK___arm64_clear_cache, "__arm64_clear_cache") - DEF(TOK___addtf3, "__addtf3") - DEF(TOK___subtf3, "__subtf3") - DEF(TOK___multf3, "__multf3") - DEF(TOK___divtf3, "__divtf3") - DEF(TOK___extendsftf2, "__extendsftf2") - DEF(TOK___extenddftf2, "__extenddftf2") - DEF(TOK___trunctfsf2, "__trunctfsf2") - DEF(TOK___trunctfdf2, "__trunctfdf2") - DEF(TOK___fixtfsi, "__fixtfsi") - DEF(TOK___fixtfdi, "__fixtfdi") - DEF(TOK___fixunstfsi, "__fixunstfsi") - DEF(TOK___fixunstfdi, "__fixunstfdi") - DEF(TOK___floatsitf, "__floatsitf") - DEF(TOK___floatditf, "__floatditf") - DEF(TOK___floatunsitf, "__floatunsitf") - DEF(TOK___floatunditf, "__floatunditf") - DEF(TOK___eqtf2, "__eqtf2") - DEF(TOK___netf2, "__netf2") - DEF(TOK___lttf2, "__lttf2") - DEF(TOK___letf2, "__letf2") - DEF(TOK___gttf2, "__gttf2") - DEF(TOK___getf2, "__getf2") -#endif - -/* bound checking symbols */ -#ifdef CONFIG_TCC_BCHECK - DEF(TOK___bound_ptr_add, "__bound_ptr_add") - DEF(TOK___bound_ptr_indir1, "__bound_ptr_indir1") - DEF(TOK___bound_ptr_indir2, "__bound_ptr_indir2") - DEF(TOK___bound_ptr_indir4, "__bound_ptr_indir4") - DEF(TOK___bound_ptr_indir8, "__bound_ptr_indir8") - DEF(TOK___bound_ptr_indir12, "__bound_ptr_indir12") - DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16") - DEF(TOK___bound_main_arg, "__bound_main_arg") - DEF(TOK___bound_local_new, "__bound_local_new") - DEF(TOK___bound_local_delete, "__bound_local_delete") - DEF(TOK___bound_init, "__bound_init") -# ifdef TCC_TARGET_PE - DEF(TOK_malloc, "malloc") - DEF(TOK_free, "free") - DEF(TOK_realloc, "realloc") - DEF(TOK_memalign, "memalign") - DEF(TOK_calloc, "calloc") -# endif - DEF(TOK_strlen, "strlen") - DEF(TOK_strcpy, "strcpy") -#endif - -/* Tiny Assembler */ - DEF_ASMDIR(byte) /* must be first directive */ - DEF_ASMDIR(word) - DEF_ASMDIR(align) - DEF_ASMDIR(p2align) - DEF_ASMDIR(skip) - DEF_ASMDIR(space) - DEF_ASMDIR(string) - DEF_ASMDIR(asciz) - DEF_ASMDIR(ascii) - DEF_ASMDIR(file) - DEF_ASMDIR(globl) - DEF_ASMDIR(global) - DEF_ASMDIR(weak) - DEF_ASMDIR(hidden) - DEF_ASMDIR(ident) - DEF_ASMDIR(size) - DEF_ASMDIR(type) - DEF_ASMDIR(text) - DEF_ASMDIR(data) - DEF_ASMDIR(bss) - DEF_ASMDIR(previous) - DEF_ASMDIR(fill) - DEF_ASMDIR(org) - DEF_ASMDIR(quad) -#if defined(TCC_TARGET_I386) - DEF_ASMDIR(code16) - DEF_ASMDIR(code32) -#elif defined(TCC_TARGET_X86_64) - DEF_ASMDIR(code64) -#endif - DEF_ASMDIR(short) - DEF_ASMDIR(long) - DEF_ASMDIR(int) - DEF_ASMDIR(section) /* must be last directive */ - -#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 -#include "i386-tok.h" -#endif diff --git a/external/TCC/win32/tools/tiny_impdef.c b/external/TCC/win32/tools/tiny_impdef.c deleted file mode 100644 index 48de44f3..00000000 --- a/external/TCC/win32/tools/tiny_impdef.c +++ /dev/null @@ -1,249 +0,0 @@ -/* -------------------------------------------------------------- */ -/* - * tiny_impdef creates an export definition file (.def) from a dll - * on MS-Windows. Usage: tiny_impdef library.dll [-o outputfile]" - * - * Copyright (c) 2005,2007 grischka - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef TINY_IMPDEF_GET_EXPORT_NAMES_ONLY - -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include - -char *get_export_names(int fd); -#define tcc_free free -#define tcc_realloc realloc - -/* extract the basename of a file */ -static char *file_basename(const char *name) -{ - const char *p = strchr(name, 0); - while (p > name - && p[-1] != '/' - && p[-1] != '\\' - ) - --p; - return (char*)p; -} - -int main(int argc, char **argv) -{ - int ret, v, i; - char infile[MAX_PATH]; - char outfile[MAX_PATH]; - - static const char *ext[] = { ".dll", ".exe", NULL }; - const char *file, **pp; - char path[MAX_PATH], *p, *q; - FILE *fp, *op; - - infile[0] = 0; - outfile[0] = 0; - fp = op = NULL; - v = 0; - ret = 1; - p = NULL; - - for (i = 1; i < argc; ++i) { - const char *a = argv[i]; - if ('-' == a[0]) { - if (0 == strcmp(a, "-v")) { - v = 1; - } else if (0 == strcmp(a, "-o")) { - if (++i == argc) - goto usage; - strcpy(outfile, argv[i]); - } else - goto usage; - } else if (0 == infile[0]) - strcpy(infile, a); - else - goto usage; - } - - if (0 == infile[0]) { -usage: - fprintf(stderr, - "tiny_impdef: create export definition file (.def) from a dll\n" - "Usage: tiny_impdef library.dll [-o outputfile]\n" - ); - goto the_end; - } - - if (0 == outfile[0]) - { - strcpy(outfile, file_basename(infile)); - q = strrchr(outfile, '.'); - if (NULL == q) - q = strchr(outfile, 0); - strcpy(q, ".def"); - } - - file = infile; - -#ifdef _WIN32 - pp = ext; - do if (SearchPath(NULL, file, *pp, sizeof path, path, NULL)) { - file = path; - break; - } while (*pp++); -#endif - - fp = fopen(file, "rb"); - if (NULL == fp) { - fprintf(stderr, "tiny_impdef: no such file: %s\n", infile); - goto the_end; - } - if (v) - printf("--> %s\n", file); - - p = get_export_names(fileno(fp)); - if (NULL == p) { - fprintf(stderr, "tiny_impdef: could not get exported function names.\n"); - goto the_end; - } - - op = fopen(outfile, "w"); - if (NULL == op) { - fprintf(stderr, "tiny_impdef: could not create output file: %s\n", outfile); - goto the_end; - } - - fprintf(op, "LIBRARY %s\n\nEXPORTS\n", file_basename(file)); - for (q = p, i = 0; *q; ++i) { - fprintf(op, "%s\n", q); - q += strlen(q) + 1; - } - - if (v) { - printf("<-- %s\n", outfile); - printf("%d symbol(s) found\n", i); - } - - ret = 0; - -the_end: - if (p) - free(p); - if (fp) - fclose(fp); - if (op) - fclose(op); - return ret; -} - -int read_mem(int fd, unsigned offset, void *buffer, unsigned len) -{ - lseek(fd, offset, SEEK_SET); - return len == read(fd, buffer, len); -} - -/* -------------------------------------------------------------- */ - -#if defined TCC_TARGET_X86_64 -# define IMAGE_FILE_MACHINE 0x8664 -#elif defined TCC_TARGET_ARM -# define IMAGE_FILE_MACHINE 0x01C0 -#elif 1 /* defined TCC_TARGET_I386 */ -# define IMAGE_FILE_MACHINE 0x014C -#endif - -/* -------------------------------------------------------------- */ -#endif - -char *get_export_names(int fd) -{ - int l, i, n, n0; - char *p; - - IMAGE_SECTION_HEADER ish; - IMAGE_EXPORT_DIRECTORY ied; - IMAGE_DOS_HEADER dh; - IMAGE_FILE_HEADER ih; - DWORD sig, ref, addr, ptr, namep; -#ifdef TCC_TARGET_X86_64 - IMAGE_OPTIONAL_HEADER64 oh; -#else - IMAGE_OPTIONAL_HEADER32 oh; -#endif - int pef_hdroffset, opt_hdroffset, sec_hdroffset; - - n = n0 = 0; - p = NULL; - - if (!read_mem(fd, 0, &dh, sizeof dh)) - goto the_end; - if (!read_mem(fd, dh.e_lfanew, &sig, sizeof sig)) - goto the_end; - if (sig != 0x00004550) - goto the_end; - pef_hdroffset = dh.e_lfanew + sizeof sig; - if (!read_mem(fd, pef_hdroffset, &ih, sizeof ih)) - goto the_end; - if (IMAGE_FILE_MACHINE != ih.Machine) - goto the_end; - opt_hdroffset = pef_hdroffset + sizeof ih; - sec_hdroffset = opt_hdroffset + sizeof oh; - if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh)) - goto the_end; - - if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes) - goto the_end; - - addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; - //printf("addr: %08x\n", addr); - for (i = 0; i < ih.NumberOfSections; ++i) { - if (!read_mem(fd, sec_hdroffset + i * sizeof ish, &ish, sizeof ish)) - goto the_end; - //printf("vaddr: %08x\n", ish.VirtualAddress); - if (addr >= ish.VirtualAddress && addr < ish.VirtualAddress + ish.SizeOfRawData) - goto found; - } - goto the_end; - -found: - ref = ish.VirtualAddress - ish.PointerToRawData; - if (!read_mem(fd, addr - ref, &ied, sizeof ied)) - goto the_end; - - namep = ied.AddressOfNames - ref; - for (i = 0; i < ied.NumberOfNames; ++i) { - if (!read_mem(fd, namep, &ptr, sizeof ptr)) - goto the_end; - namep += sizeof ptr; - for (l = 0;;) { - if (n+1 >= n0) - p = tcc_realloc(p, n0 = n0 ? n0 * 2 : 256); - if (!read_mem(fd, ptr - ref + l++, p + n, 1)) { - tcc_free(p), p = NULL; - goto the_end; - } - if (p[n++] == 0) - break; - } - } - if (p) - p[n] = 0; -the_end: - return p; -} - -/* -------------------------------------------------------------- */ diff --git a/external/TCC/win32/tools/tiny_libmaker.c b/external/TCC/win32/tools/tiny_libmaker.c deleted file mode 100644 index 62d2a2e0..00000000 --- a/external/TCC/win32/tools/tiny_libmaker.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * This program is for making libtcc1.a without ar - * tiny_libmaker - tiny elf lib maker - * usage: tiny_libmaker [lib] files... - * Copyright (c) 2007 Timppa - * - * 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 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 St, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include -#include -#include "../../elf.h" - -#ifdef TCC_TARGET_X86_64 -# define ELFCLASSW ELFCLASS64 -# define ElfW(type) Elf##64##_##type -# define ELFW(type) ELF##64##_##type -#else -# define ELFCLASSW ELFCLASS32 -# define ElfW(type) Elf##32##_##type -# define ELFW(type) ELF##32##_##type -#endif - -#define ARMAG "!\n" -#define ARFMAG "`\n" - -typedef struct ArHdr { - char ar_name[16]; - char ar_date[12]; - char ar_uid[6]; - char ar_gid[6]; - char ar_mode[8]; - char ar_size[10]; - char ar_fmag[2]; -} ArHdr; - -unsigned long le2belong(unsigned long ul) { - return ((ul & 0xFF0000)>>8)+((ul & 0xFF000000)>>24) + - ((ul & 0xFF)<<24)+((ul & 0xFF00)<<8); -} - -ArHdr arhdr = { - "/ ", - " ", - "0 ", - "0 ", - "0 ", - " ", - ARFMAG - }; - -ArHdr arhdro = { - " ", - " ", - "0 ", - "0 ", - "0 ", - " ", - ARFMAG - }; - -int main(int argc, char **argv) -{ - FILE *fi, *fh = NULL, *fo = NULL; - ElfW(Ehdr) *ehdr; - ElfW(Shdr) *shdr; - ElfW(Sym) *sym; - int i, fsize, iarg; - char *buf, *shstr, *symtab = NULL, *strtab = NULL; - int symtabsize = 0;//, strtabsize = 0; - char *anames = NULL; - int *afpos = NULL; - int istrlen, strpos = 0, fpos = 0, funccnt = 0, funcmax, hofs; - char afile[260], tfile[260], stmp[20]; - char *file, *name; - int ret = 2; - - - strcpy(afile, "ar_test.a"); - iarg = 1; - - if (argc < 2) - { - printf("usage: tiny_libmaker [lib] file...\n"); - return 1; - } - for (i=1; ie_ident[4] != ELFCLASSW) - { - fprintf(stderr, "Unsupported Elf Class: %s\n", argv[iarg]); - goto the_end; - } - - shdr = (ElfW(Shdr) *) (buf + ehdr->e_shoff + ehdr->e_shstrndx * ehdr->e_shentsize); - shstr = (char *)(buf + shdr->sh_offset); - for (i = 0; i < ehdr->e_shnum; i++) - { - shdr = (ElfW(Shdr) *) (buf + ehdr->e_shoff + i * ehdr->e_shentsize); - if (!shdr->sh_offset) - continue; - if (shdr->sh_type == SHT_SYMTAB) - { - symtab = (char *)(buf + shdr->sh_offset); - symtabsize = shdr->sh_size; - } - if (shdr->sh_type == SHT_STRTAB) - { - if (!strcmp(shstr + shdr->sh_name, ".strtab")) - { - strtab = (char *)(buf + shdr->sh_offset); - //strtabsize = shdr->sh_size; - } - } - } - - if (symtab && symtabsize) - { - int nsym = symtabsize / sizeof(ElfW(Sym)); - //printf("symtab: info size shndx name\n"); - for (i = 1; i < nsym; i++) - { - sym = (ElfW(Sym) *) (symtab + i * sizeof(ElfW(Sym))); - if (sym->st_shndx && - (sym->st_info == 0x10 - || sym->st_info == 0x11 - || sym->st_info == 0x12 - )) { - //printf("symtab: %2Xh %4Xh %2Xh %s\n", sym->st_info, sym->st_size, sym->st_shndx, strtab + sym->st_name); - istrlen = strlen(strtab + sym->st_name)+1; - anames = realloc(anames, strpos+istrlen); - strcpy(anames + strpos, strtab + sym->st_name); - strpos += istrlen; - if (++funccnt >= funcmax) { - funcmax += 250; - afpos = realloc(afpos, funcmax * sizeof *afpos); // 250 func more - } - afpos[funccnt] = fpos; - } - } - } - - file = argv[iarg]; - for (name = strchr(file, 0); - name > file && name[-1] != '/' && name[-1] != '\\'; - --name); - istrlen = strlen(name); - if (istrlen >= sizeof(arhdro.ar_name)) - istrlen = sizeof(arhdro.ar_name) - 1; - memset(arhdro.ar_name, ' ', sizeof(arhdro.ar_name)); - memcpy(arhdro.ar_name, name, istrlen); - arhdro.ar_name[istrlen] = '/'; - sprintf(stmp, "%-10d", fsize); - memcpy(&arhdro.ar_size, stmp, 10); - fwrite(&arhdro, sizeof(arhdro), 1, fo); - fwrite(buf, fsize, 1, fo); - free(buf); - iarg++; - fpos += (fsize + sizeof(arhdro)); - } - hofs = 8 + sizeof(arhdr) + strpos + (funccnt+1) * sizeof(int); - fpos = 0; - if ((hofs & 1)) // align - hofs++, fpos = 1; - // write header - fwrite("!\n", 8, 1, fh); - sprintf(stmp, "%-10d", (int)(strpos + (funccnt+1) * sizeof(int))); - memcpy(&arhdr.ar_size, stmp, 10); - fwrite(&arhdr, sizeof(arhdr), 1, fh); - afpos[0] = le2belong(funccnt); - for (i=1; i<=funccnt; i++) - afpos[i] = le2belong(afpos[i] + hofs); - fwrite(afpos, (funccnt+1) * sizeof(int), 1, fh); - fwrite(anames, strpos, 1, fh); - if (fpos) - fwrite("", 1, 1, fh); - // write objects - fseek(fo, 0, SEEK_END); - fsize = ftell(fo); - fseek(fo, 0, SEEK_SET); - buf = malloc(fsize + 1); - fread(buf, fsize, 1, fo); - fwrite(buf, fsize, 1, fh); - free(buf); - ret = 0; -the_end: - if (anames) - free(anames); - if (afpos) - free(afpos); - if (fh) - fclose(fh); - if (fo) - fclose(fo), remove(tfile); - return ret; -} diff --git a/external/TCC/x86_64-asm.h b/external/TCC/x86_64-asm.h deleted file mode 100644 index df76bf0f..00000000 --- a/external/TCC/x86_64-asm.h +++ /dev/null @@ -1,475 +0,0 @@ - DEF_ASM_OP0(clc, 0xf8) /* must be first OP0 */ - DEF_ASM_OP0(cld, 0xfc) - DEF_ASM_OP0(cli, 0xfa) - DEF_ASM_OP0(clts, 0x0f06) - DEF_ASM_OP0(cmc, 0xf5) - DEF_ASM_OP0(lahf, 0x9f) - DEF_ASM_OP0(sahf, 0x9e) - DEF_ASM_OP0(pushfl, 0x9c) - DEF_ASM_OP0(popfl, 0x9d) - DEF_ASM_OP0(pushf, 0x9c) - DEF_ASM_OP0(popf, 0x9d) - DEF_ASM_OP0(stc, 0xf9) - DEF_ASM_OP0(std, 0xfd) - DEF_ASM_OP0(sti, 0xfb) - DEF_ASM_OP0(aaa, 0x37) - DEF_ASM_OP0(aas, 0x3f) - DEF_ASM_OP0(daa, 0x27) - DEF_ASM_OP0(das, 0x2f) - DEF_ASM_OP0(aad, 0xd50a) - DEF_ASM_OP0(aam, 0xd40a) - DEF_ASM_OP0(cbw, 0x6698) - DEF_ASM_OP0(cwd, 0x6699) - DEF_ASM_OP0(cwde, 0x98) - DEF_ASM_OP0(cdq, 0x99) - DEF_ASM_OP0(cbtw, 0x6698) - DEF_ASM_OP0(cwtl, 0x98) - DEF_ASM_OP0(cwtd, 0x6699) - DEF_ASM_OP0(cltd, 0x99) - DEF_ASM_OP0(cqto, 0x4899) - DEF_ASM_OP0(int3, 0xcc) - DEF_ASM_OP0(into, 0xce) - DEF_ASM_OP0(iret, 0xcf) - DEF_ASM_OP0(rsm, 0x0faa) - DEF_ASM_OP0(hlt, 0xf4) - DEF_ASM_OP0(wait, 0x9b) - DEF_ASM_OP0(nop, 0x90) - DEF_ASM_OP0(xlat, 0xd7) - - /* strings */ -ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWLQ)) -ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWLQ)) - -ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWLQ)) -ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWLQ)) - -ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWLQ)) -ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWLQ)) - -ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWLQ)) -ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWLQ)) - -ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWLQ)) -ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWLQ)) - -ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWLQ)) -ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWLQ)) - - /* bits */ - -ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WLQ, OPT_REGW | OPT_EA, OPT_REGW)) -ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WLQ, OPT_REGW | OPT_EA, OPT_REGW)) - -ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WLQ, OPT_REGW, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WLQ, OPT_IM8, OPT_REGW | OPT_EA)) - -ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WLQ, OPT_REGW, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WLQ, OPT_IM8, OPT_REGW | OPT_EA)) - -ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WLQ, OPT_REGW, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WLQ, OPT_IM8, OPT_REGW | OPT_EA)) - -ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WLQ, OPT_REGW, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WLQ, OPT_IM8, OPT_REGW | OPT_EA)) - - /* prefixes */ - DEF_ASM_OP0(lock, 0xf0) - DEF_ASM_OP0(rep, 0xf3) - DEF_ASM_OP0(repe, 0xf3) - DEF_ASM_OP0(repz, 0xf3) - DEF_ASM_OP0(repne, 0xf2) - DEF_ASM_OP0(repnz, 0xf2) - - DEF_ASM_OP0(invd, 0x0f08) - DEF_ASM_OP0(wbinvd, 0x0f09) - DEF_ASM_OP0(cpuid, 0x0fa2) - DEF_ASM_OP0(wrmsr, 0x0f30) - DEF_ASM_OP0(rdtsc, 0x0f31) - DEF_ASM_OP0(rdmsr, 0x0f32) - DEF_ASM_OP0(rdpmc, 0x0f33) - DEF_ASM_OP0(ud2, 0x0f0b) - - /* NOTE: we took the same order as gas opcode definition order */ -ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWLQ, OPT_ADDR, OPT_EAX)) -ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWLQ, OPT_EAX, OPT_ADDR)) -ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWLQ, OPT_REG, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWLQ, OPT_EA | OPT_REG, OPT_REG)) -ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWLQ, OPT_IM, OPT_REG)) -ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWLQ, OPT_IM, OPT_REG | OPT_EA)) - -ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WLQ, OPT_SEG, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WLQ, OPT_EA | OPT_REG, OPT_SEG)) - -ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WLQ, OPT_CR, OPT_REG64)) -ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WLQ, OPT_DB, OPT_REG64)) -ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WLQ, OPT_TR, OPT_REG64)) -ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WLQ, OPT_REG64, OPT_CR)) -ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WLQ, OPT_REG64, OPT_DB)) -ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WLQ, OPT_REG64, OPT_TR)) - -ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16)) -ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(movslq, 0x4863, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG)) -ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW)) -ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32)) - -ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WLQ, OPT_REG64)) -ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WLQ, OPT_REG64 | OPT_EA)) -ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WLQ, OPT_IM32)) -ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WLQ, OPT_SEG)) - DEF_ASM_OP1(pushb, 0x6a, 0, OPC_B, OPT_IM8S) - -ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WLQ, OPT_REGW)) -ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WLQ, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WLQ, OPT_SEG)) - -ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLQ, OPT_REG, OPT_EAX)) -ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLQ, OPT_EAX, OPT_REG)) -ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLQ, OPT_REG, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLQ, OPT_EA | OPT_REG, OPT_REG)) - -ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX)) -ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8)) -ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX)) -ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX)) - -ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8)) -ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8)) -ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX)) -ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX)) - -ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WLQ, OPT_EA, OPT_REG)) - -ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32)) - - /* arith */ -ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWLQ, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */ -ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWLQ, OPT_EA | OPT_REG, OPT_REG)) -ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWLQ, OPT_IMNO64, OPT_EAX)) -ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWLQ, OPT_IMNO64, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WLQ, OPT_IM8S, OPT_EA | OPT_REG)) - -ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLQ, OPT_EA | OPT_REG, OPT_REG)) -ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLQ, OPT_REG, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWLQ, OPT_IMNO64, OPT_EAX)) -ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWLQ, OPT_IMNO64, OPT_EA | OPT_REG)) - -ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WLQ, OPT_REGW)) -ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA)) -ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WLQ, OPT_REGW)) -ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA)) - -ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA)) -ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA)) - -ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA)) -ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA)) - -ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WLQ, OPT_REG | OPT_EA, OPT_REG)) -ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WLQ, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW)) -ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WLQ, OPT_IM8S, OPT_REGW)) -ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WLQ, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW)) -ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WLQ, OPT_IMW, OPT_REGW)) - -ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA)) -ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA, OPT_EAX)) -ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA)) -ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA, OPT_EAX)) - - /* shifts */ -ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWLQ | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWLQ | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWLQ | OPC_SHIFT, OPT_EA | OPT_REG)) - -ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WLQ, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) -ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLQ, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) -ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLQ, OPT_REGW, OPT_EA | OPT_REGW)) -ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WLQ, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) -ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLQ, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) -ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLQ, OPT_REGW, OPT_EA | OPT_REGW)) - -ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR)) -ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR)) -ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR)) -ALT(DEF_ASM_OP1(jmp, 0xff, 0, OPC_JMP | OPC_WL, OPT_REGW)) -ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR)) - -ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA)) -ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA)) - -ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8)) -ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA)) -ALT(DEF_ASM_OP1(setob, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA)) - DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8) - DEF_ASM_OP0(leave, 0xc9) - DEF_ASM_OP0(ret, 0xc3) -ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16)) - DEF_ASM_OP0(lret, 0xcb) -ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16)) - -ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR)) - DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR) - - /* float */ - /* specific fcomp handling */ -ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0)) - -ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST)) -ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0)) -ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH)) -ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST)) -ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0)) -ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST)) -ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH)) -ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) -ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) -ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) -ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) - - DEF_ASM_OP0(fucompp, 0xdae9) - DEF_ASM_OP0(ftst, 0xd9e4) - DEF_ASM_OP0(fxam, 0xd9e5) - DEF_ASM_OP0(fld1, 0xd9e8) - DEF_ASM_OP0(fldl2t, 0xd9e9) - DEF_ASM_OP0(fldl2e, 0xd9ea) - DEF_ASM_OP0(fldpi, 0xd9eb) - DEF_ASM_OP0(fldlg2, 0xd9ec) - DEF_ASM_OP0(fldln2, 0xd9ed) - DEF_ASM_OP0(fldz, 0xd9ee) - - DEF_ASM_OP0(f2xm1, 0xd9f0) - DEF_ASM_OP0(fyl2x, 0xd9f1) - DEF_ASM_OP0(fptan, 0xd9f2) - DEF_ASM_OP0(fpatan, 0xd9f3) - DEF_ASM_OP0(fxtract, 0xd9f4) - DEF_ASM_OP0(fprem1, 0xd9f5) - DEF_ASM_OP0(fdecstp, 0xd9f6) - DEF_ASM_OP0(fincstp, 0xd9f7) - DEF_ASM_OP0(fprem, 0xd9f8) - DEF_ASM_OP0(fyl2xp1, 0xd9f9) - DEF_ASM_OP0(fsqrt, 0xd9fa) - DEF_ASM_OP0(fsincos, 0xd9fb) - DEF_ASM_OP0(frndint, 0xd9fc) - DEF_ASM_OP0(fscale, 0xd9fd) - DEF_ASM_OP0(fsin, 0xd9fe) - DEF_ASM_OP0(fcos, 0xd9ff) - DEF_ASM_OP0(fchs, 0xd9e0) - DEF_ASM_OP0(fabs, 0xd9e1) - DEF_ASM_OP0(fninit, 0xdbe3) - DEF_ASM_OP0(fnclex, 0xdbe2) - DEF_ASM_OP0(fnop, 0xd9d0) - DEF_ASM_OP0(fwait, 0x9b) - - /* fp load */ - DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST) - DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST) - DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA) -ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA)) - DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA) - DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA) - - /* fp store */ - DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST) - DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST) - DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA) -ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA)) - DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA) - - DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST) - DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA) - - /* exchange */ - DEF_ASM_OP0(fxch, 0xd9c9) -ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST)) - - /* misc FPU */ - DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST ) - DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST ) - - DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT) - DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA ) - DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA ) - DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ) - DEF_ASM_OP0(fnstsw, 0xdfe0) -ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX )) -ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA )) - DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX ) -ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT)) -ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )) - DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT) - DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA ) - DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA ) - DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA ) - DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA ) - DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA ) - DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA ) - DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST ) - DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST ) - DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA ) - DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA ) - - /* segments */ - DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA) - DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32) - DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG) - DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG) -ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG)) - DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG) - DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA) - DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA) - DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA) - DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA) - DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA) - DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA) - - /* 486 */ - DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 ) -ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA )) -ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA )) - DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA ) - - DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA) - DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA) - - /* pentium */ - DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA ) - - /* pentium pro */ -ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(cmovno, 0x0f41, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(cmovc, 0x0f42, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(cmovnc, 0x0f43, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(cmovz, 0x0f44, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(cmovnz, 0x0f45, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(cmovna, 0x0f46, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(cmova, 0x0f47, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) - - DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 ) - DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 ) - DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 ) - DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 ) - DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 ) - DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 ) - DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 ) - DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 ) - - DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 ) - DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 ) - DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 ) - DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 ) - - /* mmx */ - DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */ - DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX ) -ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 )) -ALT(DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )) -ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX )) - DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - - /* sse */ - DEF_ASM_OP2(movups, 0x0f10, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE ) -ALT(DEF_ASM_OP2(movups, 0x0f11, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 )) - DEF_ASM_OP2(movaps, 0x0f28, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE ) -ALT(DEF_ASM_OP2(movaps, 0x0f29, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 )) - DEF_ASM_OP2(movhps, 0x0f16, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE ) -ALT(DEF_ASM_OP2(movhps, 0x0f17, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 )) - DEF_ASM_OP2(addps, 0x0f58, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) - DEF_ASM_OP2(cvtpi2ps, 0x0f2a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_SSE ) - DEF_ASM_OP2(cvtps2pi, 0x0f2d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX ) - DEF_ASM_OP2(cvttps2pi, 0x0f2c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX ) - DEF_ASM_OP2(divps, 0x0f5e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) - DEF_ASM_OP2(maxps, 0x0f5f, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) - DEF_ASM_OP2(minps, 0x0f5d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) - DEF_ASM_OP2(mulps, 0x0f59, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) - DEF_ASM_OP2(pavgb, 0x0fe0, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) - DEF_ASM_OP2(pavgw, 0x0fe3, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) - DEF_ASM_OP2(pmaxsw, 0x0fee, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pmaxub, 0x0fde, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pminsw, 0x0fea, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pminub, 0x0fda, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(rcpss, 0x0f53, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) - DEF_ASM_OP2(rsqrtps, 0x0f52, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) - DEF_ASM_OP2(sqrtps, 0x0f51, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) - DEF_ASM_OP2(subps, 0x0f5c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) - -#undef ALT -#undef DEF_ASM_OP0 -#undef DEF_ASM_OP0L -#undef DEF_ASM_OP1 -#undef DEF_ASM_OP2 -#undef DEF_ASM_OP3 diff --git a/external/TCC/x86_64-gen.c b/external/TCC/x86_64-gen.c deleted file mode 100644 index 692b420f..00000000 --- a/external/TCC/x86_64-gen.c +++ /dev/null @@ -1,2251 +0,0 @@ -/* - * x86-64 code generator for TCC - * - * Copyright (c) 2008 Shinichiro Hamaji - * - * Based on i386-gen.c by Fabrice Bellard - * - * 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef TARGET_DEFS_ONLY - -/* number of available registers */ -#define NB_REGS 25 -#define NB_ASM_REGS 8 - -/* a register can belong to several classes. The classes must be - sorted from more general to more precise (see gv2() code which does - assumptions on it). */ -#define RC_INT 0x0001 /* generic integer register */ -#define RC_FLOAT 0x0002 /* generic float register */ -#define RC_RAX 0x0004 -#define RC_RCX 0x0008 -#define RC_RDX 0x0010 -#define RC_ST0 0x0080 /* only for long double */ -#define RC_R8 0x0100 -#define RC_R9 0x0200 -#define RC_R10 0x0400 -#define RC_R11 0x0800 -#define RC_XMM0 0x1000 -#define RC_XMM1 0x2000 -#define RC_XMM2 0x4000 -#define RC_XMM3 0x8000 -#define RC_XMM4 0x10000 -#define RC_XMM5 0x20000 -#define RC_XMM6 0x40000 -#define RC_XMM7 0x80000 -#define RC_IRET RC_RAX /* function return: integer register */ -#define RC_LRET RC_RDX /* function return: second integer register */ -#define RC_FRET RC_XMM0 /* function return: float register */ -#define RC_QRET RC_XMM1 /* function return: second float register */ - -/* pretty names for the registers */ -enum { - TREG_RAX = 0, - TREG_RCX = 1, - TREG_RDX = 2, - TREG_RSP = 4, - TREG_RSI = 6, - TREG_RDI = 7, - - TREG_R8 = 8, - TREG_R9 = 9, - TREG_R10 = 10, - TREG_R11 = 11, - - TREG_XMM0 = 16, - TREG_XMM1 = 17, - TREG_XMM2 = 18, - TREG_XMM3 = 19, - TREG_XMM4 = 20, - TREG_XMM5 = 21, - TREG_XMM6 = 22, - TREG_XMM7 = 23, - - TREG_ST0 = 24, - - TREG_MEM = 0x20 -}; - -#define REX_BASE(reg) (((reg) >> 3) & 1) -#define REG_VALUE(reg) ((reg) & 7) - -/* return registers for function */ -#define REG_IRET TREG_RAX /* single word int return register */ -#define REG_LRET TREG_RDX /* second word return register (for long long) */ -#define REG_FRET TREG_XMM0 /* float return register */ -#define REG_QRET TREG_XMM1 /* second float return register */ - -/* defined if function parameters must be evaluated in reverse order */ -#define INVERT_FUNC_PARAMS - -/* pointer size, in bytes */ -#define PTR_SIZE 8 - -/* long double size and alignment, in bytes */ -#define LDOUBLE_SIZE 16 -#define LDOUBLE_ALIGN 16 -/* maximum alignment (for aligned attribute support) */ -#define MAX_ALIGN 16 - -/******************************************************/ -/* ELF defines */ - -#define EM_TCC_TARGET EM_X86_64 - -/* relocation type for 32 bit data relocation */ -#define R_DATA_32 R_X86_64_32 -#define R_DATA_PTR R_X86_64_64 -#define R_JMP_SLOT R_X86_64_JUMP_SLOT -#define R_COPY R_X86_64_COPY - -#define ELF_START_ADDR 0x400000 -#define ELF_PAGE_SIZE 0x200000 - -/******************************************************/ -#else /* ! TARGET_DEFS_ONLY */ -/******************************************************/ -#include "tcc.h" -#include - -ST_DATA const int reg_classes[NB_REGS] = { - /* eax */ RC_INT | RC_RAX, - /* ecx */ RC_INT | RC_RCX, - /* edx */ RC_INT | RC_RDX, - 0, - 0, - 0, - 0, - 0, - RC_R8, - RC_R9, - RC_R10, - RC_R11, - 0, - 0, - 0, - 0, - /* xmm0 */ RC_FLOAT | RC_XMM0, - /* xmm1 */ RC_FLOAT | RC_XMM1, - /* xmm2 */ RC_FLOAT | RC_XMM2, - /* xmm3 */ RC_FLOAT | RC_XMM3, - /* xmm4 */ RC_FLOAT | RC_XMM4, - /* xmm5 */ RC_FLOAT | RC_XMM5, - /* xmm6 an xmm7 are included so gv() can be used on them, - but they are not tagged with RC_FLOAT because they are - callee saved on Windows */ - RC_XMM6, - RC_XMM7, - /* st0 */ RC_ST0 -}; - -static unsigned long func_sub_sp_offset; -static int func_ret_sub; - -/* XXX: make it faster ? */ -void g(int c) -{ - int ind1; - ind1 = ind + 1; - if (ind1 > cur_text_section->data_allocated) - section_realloc(cur_text_section, ind1); - cur_text_section->data[ind] = c; - ind = ind1; -} - -void o(unsigned int c) -{ - while (c) { - g(c); - c = c >> 8; - } -} - -void gen_le16(int v) -{ - g(v); - g(v >> 8); -} - -void gen_le32(int c) -{ - g(c); - g(c >> 8); - g(c >> 16); - g(c >> 24); -} - -void gen_le64(int64_t c) -{ - g(c); - g(c >> 8); - g(c >> 16); - g(c >> 24); - g(c >> 32); - g(c >> 40); - g(c >> 48); - g(c >> 56); -} - -void orex(int ll, int r, int r2, int b) -{ - if ((r & VT_VALMASK) >= VT_CONST) - r = 0; - if ((r2 & VT_VALMASK) >= VT_CONST) - r2 = 0; - if (ll || REX_BASE(r) || REX_BASE(r2)) - o(0x40 | REX_BASE(r) | (REX_BASE(r2) << 2) | (ll << 3)); - o(b); -} - -/* output a symbol and patch all calls to it */ -void gsym_addr(int t, int a) -{ - while (t) { - unsigned char *ptr = cur_text_section->data + t; - uint32_t n = read32le(ptr); /* next value */ - write32le(ptr, a - t - 4); - t = n; - } -} - -void gsym(int t) -{ - gsym_addr(t, ind); -} - -/* psym is used to put an instruction with a data field which is a - reference to a symbol. It is in fact the same as oad ! */ -#define psym oad - -static int is64_type(int t) -{ - return ((t & VT_BTYPE) == VT_PTR || - (t & VT_BTYPE) == VT_FUNC || - (t & VT_BTYPE) == VT_LLONG); -} - -/* instruction + 4 bytes data. Return the address of the data */ -ST_FUNC int oad(int c, int s) -{ - int ind1; - - o(c); - ind1 = ind + 4; - if (ind1 > cur_text_section->data_allocated) - section_realloc(cur_text_section, ind1); - write32le(cur_text_section->data + ind, s); - s = ind; - ind = ind1; - return s; -} - -ST_FUNC void gen_addr32(int r, Sym *sym, int c) -{ - if (r & VT_SYM) - greloc(cur_text_section, sym, ind, R_X86_64_32); - gen_le32(c); -} - -/* output constant with relocation if 'r & VT_SYM' is true */ -ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c) -{ - if (r & VT_SYM) - greloc(cur_text_section, sym, ind, R_X86_64_64); - gen_le64(c); -} - -/* output constant with relocation if 'r & VT_SYM' is true */ -ST_FUNC void gen_addrpc32(int r, Sym *sym, int c) -{ - if (r & VT_SYM) - greloc(cur_text_section, sym, ind, R_X86_64_PC32); - gen_le32(c-4); -} - -/* output got address with relocation */ -static void gen_gotpcrel(int r, Sym *sym, int c) -{ -#ifndef TCC_TARGET_PE - Section *sr; - ElfW(Rela) *rel; - greloc(cur_text_section, sym, ind, R_X86_64_GOTPCREL); - sr = cur_text_section->reloc; - rel = (ElfW(Rela) *)(sr->data + sr->data_offset - sizeof(ElfW(Rela))); - rel->r_addend = -4; -#else - tcc_error("internal error: no GOT on PE: %s %x %x | %02x %02x %02x\n", - get_tok_str(sym->v, NULL), c, r, - cur_text_section->data[ind-3], - cur_text_section->data[ind-2], - cur_text_section->data[ind-1] - ); - greloc(cur_text_section, sym, ind, R_X86_64_PC32); -#endif - gen_le32(0); - if (c) { - /* we use add c, %xxx for displacement */ - orex(1, r, 0, 0x81); - o(0xc0 + REG_VALUE(r)); - gen_le32(c); - } -} - -static void gen_modrm_impl(int op_reg, int r, Sym *sym, int c, int is_got) -{ - op_reg = REG_VALUE(op_reg) << 3; - if ((r & VT_VALMASK) == VT_CONST) { - /* constant memory reference */ - o(0x05 | op_reg); - if (is_got) { - gen_gotpcrel(r, sym, c); - } else { - gen_addrpc32(r, sym, c); - } - } else if ((r & VT_VALMASK) == VT_LOCAL) { - /* currently, we use only ebp as base */ - if (c == (char)c) { - /* short reference */ - o(0x45 | op_reg); - g(c); - } else { - oad(0x85 | op_reg, c); - } - } else if ((r & VT_VALMASK) >= TREG_MEM) { - if (c) { - g(0x80 | op_reg | REG_VALUE(r)); - gen_le32(c); - } else { - g(0x00 | op_reg | REG_VALUE(r)); - } - } else { - g(0x00 | op_reg | REG_VALUE(r)); - } -} - -/* generate a modrm reference. 'op_reg' contains the addtionnal 3 - opcode bits */ -static void gen_modrm(int op_reg, int r, Sym *sym, int c) -{ - gen_modrm_impl(op_reg, r, sym, c, 0); -} - -/* generate a modrm reference. 'op_reg' contains the addtionnal 3 - opcode bits */ -static void gen_modrm64(int opcode, int op_reg, int r, Sym *sym, int c) -{ - int is_got; - is_got = (op_reg & TREG_MEM) && !(sym->type.t & VT_STATIC); - orex(1, r, op_reg, opcode); - gen_modrm_impl(op_reg, r, sym, c, is_got); -} - - -/* load 'r' from value 'sv' */ -void load(int r, SValue *sv) -{ - int v, t, ft, fc, fr; - SValue v1; - -#ifdef TCC_TARGET_PE - SValue v2; - sv = pe_getimport(sv, &v2); -#endif - - fr = sv->r; - ft = sv->type.t & ~VT_DEFSIGN; - fc = sv->c.i; - -#ifndef TCC_TARGET_PE - /* we use indirect access via got */ - if ((fr & VT_VALMASK) == VT_CONST && (fr & VT_SYM) && - (fr & VT_LVAL) && !(sv->sym->type.t & VT_STATIC)) { - /* use the result register as a temporal register */ - int tr = r | TREG_MEM; - if (is_float(ft)) { - /* we cannot use float registers as a temporal register */ - tr = get_reg(RC_INT) | TREG_MEM; - } - gen_modrm64(0x8b, tr, fr, sv->sym, 0); - - /* load from the temporal register */ - fr = tr | VT_LVAL; - } -#endif - - v = fr & VT_VALMASK; - if (fr & VT_LVAL) { - int b, ll; - if (v == VT_LLOCAL) { - v1.type.t = VT_PTR; - v1.r = VT_LOCAL | VT_LVAL; - v1.c.i = fc; - fr = r; - if (!(reg_classes[fr] & (RC_INT|RC_R11))) - fr = get_reg(RC_INT); - load(fr, &v1); - } - ll = 0; - if ((ft & VT_BTYPE) == VT_FLOAT) { - b = 0x6e0f66; - r = REG_VALUE(r); /* movd */ - } else if ((ft & VT_BTYPE) == VT_DOUBLE) { - b = 0x7e0ff3; /* movq */ - r = REG_VALUE(r); - } else if ((ft & VT_BTYPE) == VT_LDOUBLE) { - b = 0xdb, r = 5; /* fldt */ - } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) { - b = 0xbe0f; /* movsbl */ - } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) { - b = 0xb60f; /* movzbl */ - } else if ((ft & VT_TYPE) == VT_SHORT) { - b = 0xbf0f; /* movswl */ - } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) { - b = 0xb70f; /* movzwl */ - } else { - assert(((ft & VT_BTYPE) == VT_INT) || ((ft & VT_BTYPE) == VT_LLONG) - || ((ft & VT_BTYPE) == VT_PTR) || ((ft & VT_BTYPE) == VT_ENUM) - || ((ft & VT_BTYPE) == VT_FUNC)); - ll = is64_type(ft); - b = 0x8b; - } - if (ll) { - gen_modrm64(b, r, fr, sv->sym, fc); - } else { - orex(ll, fr, r, b); - gen_modrm(r, fr, sv->sym, fc); - } - } else { - if (v == VT_CONST) { - if (fr & VT_SYM) { -#ifdef TCC_TARGET_PE - orex(1,0,r,0x8d); - o(0x05 + REG_VALUE(r) * 8); /* lea xx(%rip), r */ - gen_addrpc32(fr, sv->sym, fc); -#else - if (sv->sym->type.t & VT_STATIC) { - orex(1,0,r,0x8d); - o(0x05 + REG_VALUE(r) * 8); /* lea xx(%rip), r */ - gen_addrpc32(fr, sv->sym, fc); - } else { - orex(1,0,r,0x8b); - o(0x05 + REG_VALUE(r) * 8); /* mov xx(%rip), r */ - gen_gotpcrel(r, sv->sym, fc); - } -#endif - } else if (is64_type(ft)) { - orex(1,r,0, 0xb8 + REG_VALUE(r)); /* mov $xx, r */ - gen_le64(sv->c.i); - } else { - orex(0,r,0, 0xb8 + REG_VALUE(r)); /* mov $xx, r */ - gen_le32(fc); - } - } else if (v == VT_LOCAL) { - orex(1,0,r,0x8d); /* lea xxx(%ebp), r */ - gen_modrm(r, VT_LOCAL, sv->sym, fc); - } else if (v == VT_CMP) { - orex(0,r,0,0); - if ((fc & ~0x100) != TOK_NE) - oad(0xb8 + REG_VALUE(r), 0); /* mov $0, r */ - else - oad(0xb8 + REG_VALUE(r), 1); /* mov $1, r */ - if (fc & 0x100) - { - /* This was a float compare. If the parity bit is - set the result was unordered, meaning false for everything - except TOK_NE, and true for TOK_NE. */ - fc &= ~0x100; - o(0x037a + (REX_BASE(r) << 8)); - } - orex(0,r,0, 0x0f); /* setxx %br */ - o(fc); - o(0xc0 + REG_VALUE(r)); - } else if (v == VT_JMP || v == VT_JMPI) { - t = v & 1; - orex(0,r,0,0); - oad(0xb8 + REG_VALUE(r), t); /* mov $1, r */ - o(0x05eb + (REX_BASE(r) << 8)); /* jmp after */ - gsym(fc); - orex(0,r,0,0); - oad(0xb8 + REG_VALUE(r), t ^ 1); /* mov $0, r */ - } else if (v != r) { - if ((r >= TREG_XMM0) && (r <= TREG_XMM7)) { - if (v == TREG_ST0) { - /* gen_cvt_ftof(VT_DOUBLE); */ - o(0xf0245cdd); /* fstpl -0x10(%rsp) */ - /* movsd -0x10(%rsp),%xmmN */ - o(0x100ff2); - o(0x44 + REG_VALUE(r)*8); /* %xmmN */ - o(0xf024); - } else { - assert((v >= TREG_XMM0) && (v <= TREG_XMM7)); - if ((ft & VT_BTYPE) == VT_FLOAT) { - o(0x100ff3); - } else { - assert((ft & VT_BTYPE) == VT_DOUBLE); - o(0x100ff2); - } - o(0xc0 + REG_VALUE(v) + REG_VALUE(r)*8); - } - } else if (r == TREG_ST0) { - assert((v >= TREG_XMM0) && (v <= TREG_XMM7)); - /* gen_cvt_ftof(VT_LDOUBLE); */ - /* movsd %xmmN,-0x10(%rsp) */ - o(0x110ff2); - o(0x44 + REG_VALUE(r)*8); /* %xmmN */ - o(0xf024); - o(0xf02444dd); /* fldl -0x10(%rsp) */ - } else { - orex(1,r,v, 0x89); - o(0xc0 + REG_VALUE(r) + REG_VALUE(v) * 8); /* mov v, r */ - } - } - } -} - -/* store register 'r' in lvalue 'v' */ -void store(int r, SValue *v) -{ - int fr, bt, ft, fc; - int op64 = 0; - /* store the REX prefix in this variable when PIC is enabled */ - int pic = 0; - -#ifdef TCC_TARGET_PE - SValue v2; - v = pe_getimport(v, &v2); -#endif - - ft = v->type.t; - fc = v->c.i; - fr = v->r & VT_VALMASK; - bt = ft & VT_BTYPE; - -#ifndef TCC_TARGET_PE - /* we need to access the variable via got */ - if (fr == VT_CONST && (v->r & VT_SYM)) { - /* mov xx(%rip), %r11 */ - o(0x1d8b4c); - gen_gotpcrel(TREG_R11, v->sym, v->c.i); - pic = is64_type(bt) ? 0x49 : 0x41; - } -#endif - - /* XXX: incorrect if float reg to reg */ - if (bt == VT_FLOAT) { - o(0x66); - o(pic); - o(0x7e0f); /* movd */ - r = REG_VALUE(r); - } else if (bt == VT_DOUBLE) { - o(0x66); - o(pic); - o(0xd60f); /* movq */ - r = REG_VALUE(r); - } else if (bt == VT_LDOUBLE) { - o(0xc0d9); /* fld %st(0) */ - o(pic); - o(0xdb); /* fstpt */ - r = 7; - } else { - if (bt == VT_SHORT) - o(0x66); - o(pic); - if (bt == VT_BYTE || bt == VT_BOOL) - orex(0, 0, r, 0x88); - else if (is64_type(bt)) - op64 = 0x89; - else - orex(0, 0, r, 0x89); - } - if (pic) { - /* xxx r, (%r11) where xxx is mov, movq, fld, or etc */ - if (op64) - o(op64); - o(3 + (r << 3)); - } else if (op64) { - if (fr == VT_CONST || fr == VT_LOCAL || (v->r & VT_LVAL)) { - gen_modrm64(op64, r, v->r, v->sym, fc); - } else if (fr != r) { - /* XXX: don't we really come here? */ - abort(); - o(0xc0 + fr + r * 8); /* mov r, fr */ - } - } else { - if (fr == VT_CONST || fr == VT_LOCAL || (v->r & VT_LVAL)) { - gen_modrm(r, v->r, v->sym, fc); - } else if (fr != r) { - /* XXX: don't we really come here? */ - abort(); - o(0xc0 + fr + r * 8); /* mov r, fr */ - } - } -} - -/* 'is_jmp' is '1' if it is a jump */ -static void gcall_or_jmp(int is_jmp) -{ - int r; - if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && - ((vtop->r & VT_SYM) || (vtop->c.i-4) == (int)(vtop->c.i-4))) { - /* constant case */ - if (vtop->r & VT_SYM) { - /* relocation case */ -#ifdef TCC_TARGET_PE - greloc(cur_text_section, vtop->sym, ind + 1, R_X86_64_PC32); -#else - greloc(cur_text_section, vtop->sym, ind + 1, R_X86_64_PLT32); -#endif - } else { - /* put an empty PC32 relocation */ - put_elf_reloc(symtab_section, cur_text_section, - ind + 1, R_X86_64_PC32, 0); - } - oad(0xe8 + is_jmp, vtop->c.i - 4); /* call/jmp im */ - } else { - /* otherwise, indirect call */ - r = TREG_R11; - load(r, vtop); - o(0x41); /* REX */ - o(0xff); /* call/jmp *r */ - o(0xd0 + REG_VALUE(r) + (is_jmp << 4)); - } -} - -#if defined(CONFIG_TCC_BCHECK) -#ifndef TCC_TARGET_PE -static addr_t func_bound_offset; -static unsigned long func_bound_ind; -#endif - -static void gen_static_call(int v) -{ - Sym *sym = external_global_sym(v, &func_old_type, 0); - oad(0xe8, -4); - greloc(cur_text_section, sym, ind-4, R_X86_64_PC32); -} - -/* generate a bounded pointer addition */ -ST_FUNC void gen_bounded_ptr_add(void) -{ - /* save all temporary registers */ - save_regs(0); - - /* prepare fast x86_64 function call */ - gv(RC_RAX); - o(0xc68948); // mov %rax,%rsi ## second arg in %rsi, this must be size - vtop--; - - gv(RC_RAX); - o(0xc78948); // mov %rax,%rdi ## first arg in %rdi, this must be ptr - vtop--; - - /* do a fast function call */ - gen_static_call(TOK___bound_ptr_add); - - /* returned pointer is in rax */ - vtop++; - vtop->r = TREG_RAX | VT_BOUNDED; - - - /* relocation offset of the bounding function call point */ - vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(ElfW(Rela))); -} - -/* patch pointer addition in vtop so that pointer dereferencing is - also tested */ -ST_FUNC void gen_bounded_ptr_deref(void) -{ - addr_t func; - int size, align; - ElfW(Rela) *rel; - Sym *sym; - - size = 0; - /* XXX: put that code in generic part of tcc */ - if (!is_float(vtop->type.t)) { - if (vtop->r & VT_LVAL_BYTE) - size = 1; - else if (vtop->r & VT_LVAL_SHORT) - size = 2; - } - if (!size) - size = type_size(&vtop->type, &align); - switch(size) { - case 1: func = TOK___bound_ptr_indir1; break; - case 2: func = TOK___bound_ptr_indir2; break; - case 4: func = TOK___bound_ptr_indir4; break; - case 8: func = TOK___bound_ptr_indir8; break; - case 12: func = TOK___bound_ptr_indir12; break; - case 16: func = TOK___bound_ptr_indir16; break; - default: - tcc_error("unhandled size when dereferencing bounded pointer"); - func = 0; - break; - } - - sym = external_global_sym(func, &func_old_type, 0); - if (!sym->c) - put_extern_sym(sym, NULL, 0, 0); - - /* patch relocation */ - /* XXX: find a better solution ? */ - - rel = (ElfW(Rela) *)(cur_text_section->reloc->data + vtop->c.i); - rel->r_info = ELF64_R_INFO(sym->c, ELF64_R_TYPE(rel->r_info)); -} -#endif - -#ifdef TCC_TARGET_PE - -#define REGN 4 -static const uint8_t arg_regs[REGN] = { - TREG_RCX, TREG_RDX, TREG_R8, TREG_R9 -}; - -/* Prepare arguments in R10 and R11 rather than RCX and RDX - because gv() will not ever use these */ -static int arg_prepare_reg(int idx) { - if (idx == 0 || idx == 1) - /* idx=0: r10, idx=1: r11 */ - return idx + 10; - else - return arg_regs[idx]; -} - -static int func_scratch; - -/* Generate function call. The function address is pushed first, then - all the parameters in call order. This functions pops all the - parameters and the function address. */ - -void gen_offs_sp(int b, int r, int d) -{ - orex(1,0,r & 0x100 ? 0 : r, b); - if (d == (char)d) { - o(0x2444 | (REG_VALUE(r) << 3)); - g(d); - } else { - o(0x2484 | (REG_VALUE(r) << 3)); - gen_le32(d); - } -} - -/* Return the number of registers needed to return the struct, or 0 if - returning via struct pointer. */ -ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize) -{ - int size, align; - *regsize = 8; - *ret_align = 1; // Never have to re-align return values for x86-64 - size = type_size(vt, &align); - ret->ref = NULL; - if (size > 8) { - return 0; - } else if (size > 4) { - ret->t = VT_LLONG; - return 1; - } else if (size > 2) { - ret->t = VT_INT; - return 1; - } else if (size > 1) { - ret->t = VT_SHORT; - return 1; - } else { - ret->t = VT_BYTE; - return 1; - } -} - -static int is_sse_float(int t) { - int bt; - bt = t & VT_BTYPE; - return bt == VT_DOUBLE || bt == VT_FLOAT; -} - -int gfunc_arg_size(CType *type) { - int align; - if (type->t & (VT_ARRAY|VT_BITFIELD)) - return 8; - return type_size(type, &align); -} - -void gfunc_call(int nb_args) -{ - int size, r, args_size, i, d, bt, struct_size; - int arg; - - args_size = (nb_args < REGN ? REGN : nb_args) * PTR_SIZE; - arg = nb_args; - - /* for struct arguments, we need to call memcpy and the function - call breaks register passing arguments we are preparing. - So, we process arguments which will be passed by stack first. */ - struct_size = args_size; - for(i = 0; i < nb_args; i++) { - SValue *sv; - - --arg; - sv = &vtop[-i]; - bt = (sv->type.t & VT_BTYPE); - size = gfunc_arg_size(&sv->type); - - if (size <= 8) - continue; /* arguments smaller than 8 bytes passed in registers or on stack */ - - if (bt == VT_STRUCT) { - /* align to stack align size */ - size = (size + 15) & ~15; - /* generate structure store */ - r = get_reg(RC_INT); - gen_offs_sp(0x8d, r, struct_size); - struct_size += size; - - /* generate memcpy call */ - vset(&sv->type, r | VT_LVAL, 0); - vpushv(sv); - vstore(); - --vtop; - } else if (bt == VT_LDOUBLE) { - gv(RC_ST0); - gen_offs_sp(0xdb, 0x107, struct_size); - struct_size += 16; - } - } - - if (func_scratch < struct_size) - func_scratch = struct_size; - - arg = nb_args; - struct_size = args_size; - - for(i = 0; i < nb_args; i++) { - --arg; - bt = (vtop->type.t & VT_BTYPE); - - size = gfunc_arg_size(&vtop->type); - if (size > 8) { - /* align to stack align size */ - size = (size + 15) & ~15; - if (arg >= REGN) { - d = get_reg(RC_INT); - gen_offs_sp(0x8d, d, struct_size); - gen_offs_sp(0x89, d, arg*8); - } else { - d = arg_prepare_reg(arg); - gen_offs_sp(0x8d, d, struct_size); - } - struct_size += size; - } else { - if (is_sse_float(vtop->type.t)) { - gv(RC_XMM0); /* only use one float register */ - if (arg >= REGN) { - /* movq %xmm0, j*8(%rsp) */ - gen_offs_sp(0xd60f66, 0x100, arg*8); - } else { - /* movaps %xmm0, %xmmN */ - o(0x280f); - o(0xc0 + (arg << 3)); - d = arg_prepare_reg(arg); - /* mov %xmm0, %rxx */ - o(0x66); - orex(1,d,0, 0x7e0f); - o(0xc0 + REG_VALUE(d)); - } - } else { - if (bt == VT_STRUCT) { - vtop->type.ref = NULL; - vtop->type.t = size > 4 ? VT_LLONG : size > 2 ? VT_INT - : size > 1 ? VT_SHORT : VT_BYTE; - } - - r = gv(RC_INT); - if (arg >= REGN) { - gen_offs_sp(0x89, r, arg*8); - } else { - d = arg_prepare_reg(arg); - orex(1,d,r,0x89); /* mov */ - o(0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d)); - } - } - } - vtop--; - } - save_regs(0); - - /* Copy R10 and R11 into RCX and RDX, respectively */ - if (nb_args > 0) { - o(0xd1894c); /* mov %r10, %rcx */ - if (nb_args > 1) { - o(0xda894c); /* mov %r11, %rdx */ - } - } - - gcall_or_jmp(0); - vtop--; -} - - -#define FUNC_PROLOG_SIZE 11 - -/* generate function prolog of type 't' */ -void gfunc_prolog(CType *func_type) -{ - int addr, reg_param_index, bt, size; - Sym *sym; - CType *type; - - func_ret_sub = 0; - func_scratch = 0; - loc = 0; - - addr = PTR_SIZE * 2; - ind += FUNC_PROLOG_SIZE; - func_sub_sp_offset = ind; - reg_param_index = 0; - - sym = func_type->ref; - - /* if the function returns a structure, then add an - implicit pointer parameter */ - func_vt = sym->type; - func_var = (sym->c == FUNC_ELLIPSIS); - size = gfunc_arg_size(&func_vt); - if (size > 8) { - gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr); - func_vc = addr; - reg_param_index++; - addr += 8; - } - - /* define parameters */ - while ((sym = sym->next) != NULL) { - type = &sym->type; - bt = type->t & VT_BTYPE; - size = gfunc_arg_size(type); - if (size > 8) { - if (reg_param_index < REGN) { - gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr); - } - sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL | VT_REF, addr); - } else { - if (reg_param_index < REGN) { - /* save arguments passed by register */ - if ((bt == VT_FLOAT) || (bt == VT_DOUBLE)) { - o(0xd60f66); /* movq */ - gen_modrm(reg_param_index, VT_LOCAL, NULL, addr); - } else { - gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr); - } - } - sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL, addr); - } - addr += 8; - reg_param_index++; - } - - while (reg_param_index < REGN) { - if (func_type->ref->c == FUNC_ELLIPSIS) { - gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr); - addr += 8; - } - reg_param_index++; - } -} - -/* generate function epilog */ -void gfunc_epilog(void) -{ - int v, saved_ind; - - o(0xc9); /* leave */ - if (func_ret_sub == 0) { - o(0xc3); /* ret */ - } else { - o(0xc2); /* ret n */ - g(func_ret_sub); - g(func_ret_sub >> 8); - } - - saved_ind = ind; - ind = func_sub_sp_offset - FUNC_PROLOG_SIZE; - /* align local size to word & save local variables */ - v = (func_scratch + -loc + 15) & -16; - - if (v >= 4096) { - Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0); - oad(0xb8, v); /* mov stacksize, %eax */ - oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */ - greloc(cur_text_section, sym, ind-4, R_X86_64_PC32); - o(0x90); /* fill for FUNC_PROLOG_SIZE = 11 bytes */ - } else { - o(0xe5894855); /* push %rbp, mov %rsp, %rbp */ - o(0xec8148); /* sub rsp, stacksize */ - gen_le32(v); - } - - cur_text_section->data_offset = saved_ind; - pe_add_unwind_data(ind, saved_ind, v); - ind = cur_text_section->data_offset; -} - -#else - -static void gadd_sp(int val) -{ - if (val == (char)val) { - o(0xc48348); - g(val); - } else { - oad(0xc48148, val); /* add $xxx, %rsp */ - } -} - -typedef enum X86_64_Mode { - x86_64_mode_none, - x86_64_mode_memory, - x86_64_mode_integer, - x86_64_mode_sse, - x86_64_mode_x87 -} X86_64_Mode; - -static X86_64_Mode classify_x86_64_merge(X86_64_Mode a, X86_64_Mode b) -{ - if (a == b) - return a; - else if (a == x86_64_mode_none) - return b; - else if (b == x86_64_mode_none) - return a; - else if ((a == x86_64_mode_memory) || (b == x86_64_mode_memory)) - return x86_64_mode_memory; - else if ((a == x86_64_mode_integer) || (b == x86_64_mode_integer)) - return x86_64_mode_integer; - else if ((a == x86_64_mode_x87) || (b == x86_64_mode_x87)) - return x86_64_mode_memory; - else - return x86_64_mode_sse; -} - -static X86_64_Mode classify_x86_64_inner(CType *ty) -{ - X86_64_Mode mode; - Sym *f; - - switch (ty->t & VT_BTYPE) { - case VT_VOID: return x86_64_mode_none; - - case VT_INT: - case VT_BYTE: - case VT_SHORT: - case VT_LLONG: - case VT_BOOL: - case VT_PTR: - case VT_FUNC: - case VT_ENUM: return x86_64_mode_integer; - - case VT_FLOAT: - case VT_DOUBLE: return x86_64_mode_sse; - - case VT_LDOUBLE: return x86_64_mode_x87; - - case VT_STRUCT: - f = ty->ref; - - mode = x86_64_mode_none; - for (f = f->next; f; f = f->next) - mode = classify_x86_64_merge(mode, classify_x86_64_inner(&f->type)); - - return mode; - } - - assert(0); -} - -static X86_64_Mode classify_x86_64_arg(CType *ty, CType *ret, int *psize, int *palign, int *reg_count) -{ - X86_64_Mode mode; - int size, align, ret_t = 0; - - if (ty->t & (VT_BITFIELD|VT_ARRAY)) { - *psize = 8; - *palign = 8; - *reg_count = 1; - ret_t = ty->t; - mode = x86_64_mode_integer; - } else { - size = type_size(ty, &align); - *psize = (size + 7) & ~7; - *palign = (align + 7) & ~7; - - if (size > 16) { - mode = x86_64_mode_memory; - } else { - mode = classify_x86_64_inner(ty); - switch (mode) { - case x86_64_mode_integer: - if (size > 8) { - *reg_count = 2; - ret_t = VT_QLONG; - } else { - *reg_count = 1; - ret_t = (size > 4) ? VT_LLONG : VT_INT; - } - break; - - case x86_64_mode_x87: - *reg_count = 1; - ret_t = VT_LDOUBLE; - break; - - case x86_64_mode_sse: - if (size > 8) { - *reg_count = 2; - ret_t = VT_QFLOAT; - } else { - *reg_count = 1; - ret_t = (size > 4) ? VT_DOUBLE : VT_FLOAT; - } - break; - default: break; /* nothing to be done for x86_64_mode_memory and x86_64_mode_none*/ - } - } - } - - if (ret) { - ret->ref = NULL; - ret->t = ret_t; - } - - return mode; -} - -ST_FUNC int classify_x86_64_va_arg(CType *ty) -{ - /* This definition must be synced with stdarg.h */ - enum __va_arg_type { - __va_gen_reg, __va_float_reg, __va_stack - }; - int size, align, reg_count; - X86_64_Mode mode = classify_x86_64_arg(ty, NULL, &size, &align, ®_count); - switch (mode) { - default: return __va_stack; - case x86_64_mode_integer: return __va_gen_reg; - case x86_64_mode_sse: return __va_float_reg; - } -} - -/* Return the number of registers needed to return the struct, or 0 if - returning via struct pointer. */ -ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize) -{ - int size, align, reg_count; - *ret_align = 1; // Never have to re-align return values for x86-64 - *regsize = 8; - return (classify_x86_64_arg(vt, ret, &size, &align, ®_count) != x86_64_mode_memory); -} - -#define REGN 6 -static const uint8_t arg_regs[REGN] = { - TREG_RDI, TREG_RSI, TREG_RDX, TREG_RCX, TREG_R8, TREG_R9 -}; - -static int arg_prepare_reg(int idx) { - if (idx == 2 || idx == 3) - /* idx=2: r10, idx=3: r11 */ - return idx + 8; - else - return arg_regs[idx]; -} - -/* Generate function call. The function address is pushed first, then - all the parameters in call order. This functions pops all the - parameters and the function address. */ -void gfunc_call(int nb_args) -{ - X86_64_Mode mode; - CType type; - int size, align, r, args_size, stack_adjust, run_start, run_end, i, reg_count; - int nb_reg_args = 0; - int nb_sse_args = 0; - int sse_reg, gen_reg; - - /* calculate the number of integer/float register arguments */ - for(i = 0; i < nb_args; i++) { - mode = classify_x86_64_arg(&vtop[-i].type, NULL, &size, &align, ®_count); - if (mode == x86_64_mode_sse) - nb_sse_args += reg_count; - else if (mode == x86_64_mode_integer) - nb_reg_args += reg_count; - } - - /* arguments are collected in runs. Each run is a collection of 8-byte aligned arguments - and ended by a 16-byte aligned argument. This is because, from the point of view of - the callee, argument alignment is computed from the bottom up. */ - /* for struct arguments, we need to call memcpy and the function - call breaks register passing arguments we are preparing. - So, we process arguments which will be passed by stack first. */ - gen_reg = nb_reg_args; - sse_reg = nb_sse_args; - run_start = 0; - args_size = 0; - while (run_start != nb_args) { - int run_gen_reg = gen_reg, run_sse_reg = sse_reg; - - run_end = nb_args; - stack_adjust = 0; - for(i = run_start; (i < nb_args) && (run_end == nb_args); i++) { - mode = classify_x86_64_arg(&vtop[-i].type, NULL, &size, &align, ®_count); - switch (mode) { - case x86_64_mode_memory: - case x86_64_mode_x87: - stack_arg: - if (align == 16) - run_end = i; - else - stack_adjust += size; - break; - - case x86_64_mode_sse: - sse_reg -= reg_count; - if (sse_reg + reg_count > 8) goto stack_arg; - break; - - case x86_64_mode_integer: - gen_reg -= reg_count; - if (gen_reg + reg_count > REGN) goto stack_arg; - break; - default: break; /* nothing to be done for x86_64_mode_none */ - } - } - - gen_reg = run_gen_reg; - sse_reg = run_sse_reg; - - /* adjust stack to align SSE boundary */ - if (stack_adjust &= 15) { - /* fetch cpu flag before the following sub will change the value */ - if (vtop >= vstack && (vtop->r & VT_VALMASK) == VT_CMP) - gv(RC_INT); - - stack_adjust = 16 - stack_adjust; - o(0x48); - oad(0xec81, stack_adjust); /* sub $xxx, %rsp */ - args_size += stack_adjust; - } - - for(i = run_start; i < run_end;) { - /* Swap argument to top, it will possibly be changed here, - and might use more temps. At the end of the loop we keep - in on the stack and swap it back to its original position - if it is a register. */ - SValue tmp = vtop[0]; - int arg_stored = 1; - - vtop[0] = vtop[-i]; - vtop[-i] = tmp; - mode = classify_x86_64_arg(&vtop->type, NULL, &size, &align, ®_count); - - switch (vtop->type.t & VT_BTYPE) { - case VT_STRUCT: - if (mode == x86_64_mode_sse) { - if (sse_reg > 8) - sse_reg -= reg_count; - else - arg_stored = 0; - } else if (mode == x86_64_mode_integer) { - if (gen_reg > REGN) - gen_reg -= reg_count; - else - arg_stored = 0; - } - - if (arg_stored) { - /* allocate the necessary size on stack */ - o(0x48); - oad(0xec81, size); /* sub $xxx, %rsp */ - /* generate structure store */ - r = get_reg(RC_INT); - orex(1, r, 0, 0x89); /* mov %rsp, r */ - o(0xe0 + REG_VALUE(r)); - vset(&vtop->type, r | VT_LVAL, 0); - vswap(); - vstore(); - args_size += size; - } - break; - - case VT_LDOUBLE: - assert(0); - break; - - case VT_FLOAT: - case VT_DOUBLE: - assert(mode == x86_64_mode_sse); - if (sse_reg > 8) { - --sse_reg; - r = gv(RC_FLOAT); - o(0x50); /* push $rax */ - /* movq %xmmN, (%rsp) */ - o(0xd60f66); - o(0x04 + REG_VALUE(r)*8); - o(0x24); - args_size += size; - } else { - arg_stored = 0; - } - break; - - default: - assert(mode == x86_64_mode_integer); - /* simple type */ - /* XXX: implicit cast ? */ - if (gen_reg > REGN) { - --gen_reg; - r = gv(RC_INT); - orex(0,r,0,0x50 + REG_VALUE(r)); /* push r */ - args_size += size; - } else { - arg_stored = 0; - } - break; - } - - /* And swap the argument back to it's original position. */ - tmp = vtop[0]; - vtop[0] = vtop[-i]; - vtop[-i] = tmp; - - if (arg_stored) { - vrotb(i+1); - assert((vtop->type.t == tmp.type.t) && (vtop->r == tmp.r)); - vpop(); - --nb_args; - --run_end; - } else { - ++i; - } - } - - /* handle 16 byte aligned arguments at end of run */ - run_start = i = run_end; - while (i < nb_args) { - /* Rotate argument to top since it will always be popped */ - mode = classify_x86_64_arg(&vtop[-i].type, NULL, &size, &align, ®_count); - if (align != 16) - break; - - vrotb(i+1); - - if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { - gv(RC_ST0); - oad(0xec8148, size); /* sub $xxx, %rsp */ - o(0x7cdb); /* fstpt 0(%rsp) */ - g(0x24); - g(0x00); - args_size += size; - } else { - assert(mode == x86_64_mode_memory); - - /* allocate the necessary size on stack */ - o(0x48); - oad(0xec81, size); /* sub $xxx, %rsp */ - /* generate structure store */ - r = get_reg(RC_INT); - orex(1, r, 0, 0x89); /* mov %rsp, r */ - o(0xe0 + REG_VALUE(r)); - vset(&vtop->type, r | VT_LVAL, 0); - vswap(); - vstore(); - args_size += size; - } - - vpop(); - --nb_args; - } - } - - /* XXX This should be superfluous. */ - save_regs(0); /* save used temporary registers */ - - /* then, we prepare register passing arguments. - Note that we cannot set RDX and RCX in this loop because gv() - may break these temporary registers. Let's use R10 and R11 - instead of them */ - assert(gen_reg <= REGN); - assert(sse_reg <= 8); - for(i = 0; i < nb_args; i++) { - mode = classify_x86_64_arg(&vtop->type, &type, &size, &align, ®_count); - /* Alter stack entry type so that gv() knows how to treat it */ - vtop->type = type; - if (mode == x86_64_mode_sse) { - if (reg_count == 2) { - sse_reg -= 2; - gv(RC_FRET); /* Use pair load into xmm0 & xmm1 */ - if (sse_reg) { /* avoid redundant movaps %xmm0, %xmm0 */ - /* movaps %xmm0, %xmmN */ - o(0x280f); - o(0xc0 + (sse_reg << 3)); - /* movaps %xmm1, %xmmN */ - o(0x280f); - o(0xc1 + ((sse_reg+1) << 3)); - } - } else { - assert(reg_count == 1); - --sse_reg; - /* Load directly to register */ - gv(RC_XMM0 << sse_reg); - } - } else if (mode == x86_64_mode_integer) { - /* simple type */ - /* XXX: implicit cast ? */ - int d; - gen_reg -= reg_count; - r = gv(RC_INT); - d = arg_prepare_reg(gen_reg); - orex(1,d,r,0x89); /* mov */ - o(0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d)); - if (reg_count == 2) { - d = arg_prepare_reg(gen_reg+1); - orex(1,d,vtop->r2,0x89); /* mov */ - o(0xc0 + REG_VALUE(vtop->r2) * 8 + REG_VALUE(d)); - } - } - vtop--; - } - assert(gen_reg == 0); - assert(sse_reg == 0); - - /* We shouldn't have many operands on the stack anymore, but the - call address itself is still there, and it might be in %eax - (or edx/ecx) currently, which the below writes would clobber. - So evict all remaining operands here. */ - save_regs(0); - - /* Copy R10 and R11 into RDX and RCX, respectively */ - if (nb_reg_args > 2) { - o(0xd2894c); /* mov %r10, %rdx */ - if (nb_reg_args > 3) { - o(0xd9894c); /* mov %r11, %rcx */ - } - } - - oad(0xb8, nb_sse_args < 8 ? nb_sse_args : 8); /* mov nb_sse_args, %eax */ - gcall_or_jmp(0); - if (args_size) - gadd_sp(args_size); - vtop--; -} - - -#define FUNC_PROLOG_SIZE 11 - -static void push_arg_reg(int i) { - loc -= 8; - gen_modrm64(0x89, arg_regs[i], VT_LOCAL, NULL, loc); -} - -/* generate function prolog of type 't' */ -void gfunc_prolog(CType *func_type) -{ - X86_64_Mode mode; - int i, addr, align, size, reg_count; - int param_addr = 0, reg_param_index, sse_param_index; - Sym *sym; - CType *type; - - sym = func_type->ref; - addr = PTR_SIZE * 2; - loc = 0; - ind += FUNC_PROLOG_SIZE; - func_sub_sp_offset = ind; - func_ret_sub = 0; - - if (func_type->ref->c == FUNC_ELLIPSIS) { - int seen_reg_num, seen_sse_num, seen_stack_size; - seen_reg_num = seen_sse_num = 0; - /* frame pointer and return address */ - seen_stack_size = PTR_SIZE * 2; - /* count the number of seen parameters */ - sym = func_type->ref; - while ((sym = sym->next) != NULL) { - type = &sym->type; - mode = classify_x86_64_arg(type, NULL, &size, &align, ®_count); - switch (mode) { - default: - stack_arg: - seen_stack_size = ((seen_stack_size + align - 1) & -align) + size; - break; - - case x86_64_mode_integer: - if (seen_reg_num + reg_count <= 8) { - seen_reg_num += reg_count; - } else { - seen_reg_num = 8; - goto stack_arg; - } - break; - - case x86_64_mode_sse: - if (seen_sse_num + reg_count <= 8) { - seen_sse_num += reg_count; - } else { - seen_sse_num = 8; - goto stack_arg; - } - break; - } - } - - loc -= 16; - /* movl $0x????????, -0x10(%rbp) */ - o(0xf045c7); - gen_le32(seen_reg_num * 8); - /* movl $0x????????, -0xc(%rbp) */ - o(0xf445c7); - gen_le32(seen_sse_num * 16 + 48); - /* movl $0x????????, -0x8(%rbp) */ - o(0xf845c7); - gen_le32(seen_stack_size); - - /* save all register passing arguments */ - for (i = 0; i < 8; i++) { - loc -= 16; - o(0xd60f66); /* movq */ - gen_modrm(7 - i, VT_LOCAL, NULL, loc); - /* movq $0, loc+8(%rbp) */ - o(0x85c748); - gen_le32(loc + 8); - gen_le32(0); - } - for (i = 0; i < REGN; i++) { - push_arg_reg(REGN-1-i); - } - } - - sym = func_type->ref; - reg_param_index = 0; - sse_param_index = 0; - - /* if the function returns a structure, then add an - implicit pointer parameter */ - func_vt = sym->type; - mode = classify_x86_64_arg(&func_vt, NULL, &size, &align, ®_count); - if (mode == x86_64_mode_memory) { - push_arg_reg(reg_param_index); - func_vc = loc; - reg_param_index++; - } - /* define parameters */ - while ((sym = sym->next) != NULL) { - type = &sym->type; - mode = classify_x86_64_arg(type, NULL, &size, &align, ®_count); - switch (mode) { - case x86_64_mode_sse: - if (sse_param_index + reg_count <= 8) { - /* save arguments passed by register */ - loc -= reg_count * 8; - param_addr = loc; - for (i = 0; i < reg_count; ++i) { - o(0xd60f66); /* movq */ - gen_modrm(sse_param_index, VT_LOCAL, NULL, param_addr + i*8); - ++sse_param_index; - } - } else { - addr = (addr + align - 1) & -align; - param_addr = addr; - addr += size; - } - break; - - case x86_64_mode_memory: - case x86_64_mode_x87: - addr = (addr + align - 1) & -align; - param_addr = addr; - addr += size; - break; - - case x86_64_mode_integer: { - if (reg_param_index + reg_count <= REGN) { - /* save arguments passed by register */ - loc -= reg_count * 8; - param_addr = loc; - for (i = 0; i < reg_count; ++i) { - gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, param_addr + i*8); - ++reg_param_index; - } - } else { - addr = (addr + align - 1) & -align; - param_addr = addr; - addr += size; - } - break; - } - default: break; /* nothing to be done for x86_64_mode_none */ - } - sym_push(sym->v & ~SYM_FIELD, type, - VT_LOCAL | VT_LVAL, param_addr); - } - -#ifdef CONFIG_TCC_BCHECK - /* leave some room for bound checking code */ - if (tcc_state->do_bounds_check) { - func_bound_offset = lbounds_section->data_offset; - func_bound_ind = ind; - oad(0xb8, 0); /* lbound section pointer */ - o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */ - oad(0xb8, 0); /* call to function */ - } -#endif -} - -/* generate function epilog */ -void gfunc_epilog(void) -{ - int v, saved_ind; - -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check - && func_bound_offset != lbounds_section->data_offset) - { - addr_t saved_ind; - addr_t *bounds_ptr; - Sym *sym_data; - - /* add end of table info */ - bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t)); - *bounds_ptr = 0; - - /* generate bound local allocation */ - sym_data = get_sym_ref(&char_pointer_type, lbounds_section, - func_bound_offset, lbounds_section->data_offset); - saved_ind = ind; - ind = func_bound_ind; - greloc(cur_text_section, sym_data, ind + 1, R_386_32); - ind = ind + 5 + 3; - gen_static_call(TOK___bound_local_new); - ind = saved_ind; - - /* generate bound check local freeing */ - o(0x5250); /* save returned value, if any */ - greloc(cur_text_section, sym_data, ind + 1, R_386_32); - oad(0xb8, 0); /* mov xxx, %rax */ - o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */ - gen_static_call(TOK___bound_local_delete); - o(0x585a); /* restore returned value, if any */ - } -#endif - o(0xc9); /* leave */ - if (func_ret_sub == 0) { - o(0xc3); /* ret */ - } else { - o(0xc2); /* ret n */ - g(func_ret_sub); - g(func_ret_sub >> 8); - } - /* align local size to word & save local variables */ - v = (-loc + 15) & -16; - saved_ind = ind; - ind = func_sub_sp_offset - FUNC_PROLOG_SIZE; - o(0xe5894855); /* push %rbp, mov %rsp, %rbp */ - o(0xec8148); /* sub rsp, stacksize */ - gen_le32(v); - ind = saved_ind; -} - -#endif /* not PE */ - -/* generate a jump to a label */ -int gjmp(int t) -{ - return psym(0xe9, t); -} - -/* generate a jump to a fixed address */ -void gjmp_addr(int a) -{ - int r; - r = a - ind - 2; - if (r == (char)r) { - g(0xeb); - g(r); - } else { - oad(0xe9, a - ind - 5); - } -} - -/* generate a test. set 'inv' to invert test. Stack entry is popped */ -int gtst(int inv, int t) -{ - int v = vtop->r & VT_VALMASK; - if (v == VT_CMP) { - /* fast case : can jump directly since flags are set */ - if (vtop->c.i & 0x100) - { - /* This was a float compare. If the parity flag is set - the result was unordered. For anything except != this - means false and we don't jump (anding both conditions). - For != this means true (oring both). - Take care about inverting the test. We need to jump - to our target if the result was unordered and test wasn't NE, - otherwise if unordered we don't want to jump. */ - vtop->c.i &= ~0x100; - if (inv == (vtop->c.i == TOK_NE)) - o(0x067a); /* jp +6 */ - else - { - g(0x0f); - t = psym(0x8a, t); /* jp t */ - } - } - g(0x0f); - t = psym((vtop->c.i - 16) ^ inv, t); - } else if (v == VT_JMP || v == VT_JMPI) { - /* && or || optimization */ - if ((v & 1) == inv) { - /* insert vtop->c jump list in t */ - uint32_t n1, n = vtop->c.i; - if (n) { - while ((n1 = read32le(cur_text_section->data + n))) - n = n1; - write32le(cur_text_section->data + n, t); - t = vtop->c.i; - } - } else { - t = gjmp(t); - gsym(vtop->c.i); - } - } - vtop--; - return t; -} - -/* generate an integer binary operation */ -void gen_opi(int op) -{ - int r, fr, opc, c; - int ll, uu, cc; - - ll = is64_type(vtop[-1].type.t); - uu = (vtop[-1].type.t & VT_UNSIGNED) != 0; - cc = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; - - switch(op) { - case '+': - case TOK_ADDC1: /* add with carry generation */ - opc = 0; - gen_op8: - if (cc && (!ll || (int)vtop->c.i == vtop->c.i)) { - /* constant case */ - vswap(); - r = gv(RC_INT); - vswap(); - c = vtop->c.i; - if (c == (char)c) { - /* XXX: generate inc and dec for smaller code ? */ - orex(ll, r, 0, 0x83); - o(0xc0 | (opc << 3) | REG_VALUE(r)); - g(c); - } else { - orex(ll, r, 0, 0x81); - oad(0xc0 | (opc << 3) | REG_VALUE(r), c); - } - } else { - gv2(RC_INT, RC_INT); - r = vtop[-1].r; - fr = vtop[0].r; - orex(ll, r, fr, (opc << 3) | 0x01); - o(0xc0 + REG_VALUE(r) + REG_VALUE(fr) * 8); - } - vtop--; - if (op >= TOK_ULT && op <= TOK_GT) { - vtop->r = VT_CMP; - vtop->c.i = op; - } - break; - case '-': - case TOK_SUBC1: /* sub with carry generation */ - opc = 5; - goto gen_op8; - case TOK_ADDC2: /* add with carry use */ - opc = 2; - goto gen_op8; - case TOK_SUBC2: /* sub with carry use */ - opc = 3; - goto gen_op8; - case '&': - opc = 4; - goto gen_op8; - case '^': - opc = 6; - goto gen_op8; - case '|': - opc = 1; - goto gen_op8; - case '*': - gv2(RC_INT, RC_INT); - r = vtop[-1].r; - fr = vtop[0].r; - orex(ll, fr, r, 0xaf0f); /* imul fr, r */ - o(0xc0 + REG_VALUE(fr) + REG_VALUE(r) * 8); - vtop--; - break; - case TOK_SHL: - opc = 4; - goto gen_shift; - case TOK_SHR: - opc = 5; - goto gen_shift; - case TOK_SAR: - opc = 7; - gen_shift: - opc = 0xc0 | (opc << 3); - if (cc) { - /* constant case */ - vswap(); - r = gv(RC_INT); - vswap(); - orex(ll, r, 0, 0xc1); /* shl/shr/sar $xxx, r */ - o(opc | REG_VALUE(r)); - g(vtop->c.i & (ll ? 63 : 31)); - } else { - /* we generate the shift in ecx */ - gv2(RC_INT, RC_RCX); - r = vtop[-1].r; - orex(ll, r, 0, 0xd3); /* shl/shr/sar %cl, r */ - o(opc | REG_VALUE(r)); - } - vtop--; - break; - case TOK_UDIV: - case TOK_UMOD: - uu = 1; - goto divmod; - case '/': - case '%': - case TOK_PDIV: - uu = 0; - divmod: - /* first operand must be in eax */ - /* XXX: need better constraint for second operand */ - gv2(RC_RAX, RC_RCX); - r = vtop[-1].r; - fr = vtop[0].r; - vtop--; - save_reg(TREG_RDX); - orex(ll, 0, 0, uu ? 0xd231 : 0x99); /* xor %edx,%edx : cqto */ - orex(ll, fr, 0, 0xf7); /* div fr, %eax */ - o((uu ? 0xf0 : 0xf8) + REG_VALUE(fr)); - if (op == '%' || op == TOK_UMOD) - r = TREG_RDX; - else - r = TREG_RAX; - vtop->r = r; - break; - default: - opc = 7; - goto gen_op8; - } -} - -void gen_opl(int op) -{ - gen_opi(op); -} - -/* generate a floating point operation 'v = t1 op t2' instruction. The - two operands are guaranted to have the same floating point type */ -/* XXX: need to use ST1 too */ -void gen_opf(int op) -{ - int a, ft, fc, swapped, r; - int float_type = - (vtop->type.t & VT_BTYPE) == VT_LDOUBLE ? RC_ST0 : RC_FLOAT; - - /* convert constants to memory references */ - if ((vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { - vswap(); - gv(float_type); - vswap(); - } - if ((vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) - gv(float_type); - - /* must put at least one value in the floating point register */ - if ((vtop[-1].r & VT_LVAL) && - (vtop[0].r & VT_LVAL)) { - vswap(); - gv(float_type); - vswap(); - } - swapped = 0; - /* swap the stack if needed so that t1 is the register and t2 is - the memory reference */ - if (vtop[-1].r & VT_LVAL) { - vswap(); - swapped = 1; - } - if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { - if (op >= TOK_ULT && op <= TOK_GT) { - /* load on stack second operand */ - load(TREG_ST0, vtop); - save_reg(TREG_RAX); /* eax is used by FP comparison code */ - if (op == TOK_GE || op == TOK_GT) - swapped = !swapped; - else if (op == TOK_EQ || op == TOK_NE) - swapped = 0; - if (swapped) - o(0xc9d9); /* fxch %st(1) */ - if (op == TOK_EQ || op == TOK_NE) - o(0xe9da); /* fucompp */ - else - o(0xd9de); /* fcompp */ - o(0xe0df); /* fnstsw %ax */ - if (op == TOK_EQ) { - o(0x45e480); /* and $0x45, %ah */ - o(0x40fC80); /* cmp $0x40, %ah */ - } else if (op == TOK_NE) { - o(0x45e480); /* and $0x45, %ah */ - o(0x40f480); /* xor $0x40, %ah */ - op = TOK_NE; - } else if (op == TOK_GE || op == TOK_LE) { - o(0x05c4f6); /* test $0x05, %ah */ - op = TOK_EQ; - } else { - o(0x45c4f6); /* test $0x45, %ah */ - op = TOK_EQ; - } - vtop--; - vtop->r = VT_CMP; - vtop->c.i = op; - } else { - /* no memory reference possible for long double operations */ - load(TREG_ST0, vtop); - swapped = !swapped; - - switch(op) { - default: - case '+': - a = 0; - break; - case '-': - a = 4; - if (swapped) - a++; - break; - case '*': - a = 1; - break; - case '/': - a = 6; - if (swapped) - a++; - break; - } - ft = vtop->type.t; - fc = vtop->c.i; - o(0xde); /* fxxxp %st, %st(1) */ - o(0xc1 + (a << 3)); - vtop--; - } - } else { - if (op >= TOK_ULT && op <= TOK_GT) { - /* if saved lvalue, then we must reload it */ - r = vtop->r; - fc = vtop->c.i; - if ((r & VT_VALMASK) == VT_LLOCAL) { - SValue v1; - r = get_reg(RC_INT); - v1.type.t = VT_PTR; - v1.r = VT_LOCAL | VT_LVAL; - v1.c.i = fc; - load(r, &v1); - fc = 0; - } - - if (op == TOK_EQ || op == TOK_NE) { - swapped = 0; - } else { - if (op == TOK_LE || op == TOK_LT) - swapped = !swapped; - if (op == TOK_LE || op == TOK_GE) { - op = 0x93; /* setae */ - } else { - op = 0x97; /* seta */ - } - } - - if (swapped) { - gv(RC_FLOAT); - vswap(); - } - assert(!(vtop[-1].r & VT_LVAL)); - - if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) - o(0x66); - if (op == TOK_EQ || op == TOK_NE) - o(0x2e0f); /* ucomisd */ - else - o(0x2f0f); /* comisd */ - - if (vtop->r & VT_LVAL) { - gen_modrm(vtop[-1].r, r, vtop->sym, fc); - } else { - o(0xc0 + REG_VALUE(vtop[0].r) + REG_VALUE(vtop[-1].r)*8); - } - - vtop--; - vtop->r = VT_CMP; - vtop->c.i = op | 0x100; - } else { - assert((vtop->type.t & VT_BTYPE) != VT_LDOUBLE); - switch(op) { - default: - case '+': - a = 0; - break; - case '-': - a = 4; - break; - case '*': - a = 1; - break; - case '/': - a = 6; - break; - } - ft = vtop->type.t; - fc = vtop->c.i; - assert((ft & VT_BTYPE) != VT_LDOUBLE); - - r = vtop->r; - /* if saved lvalue, then we must reload it */ - if ((vtop->r & VT_VALMASK) == VT_LLOCAL) { - SValue v1; - r = get_reg(RC_INT); - v1.type.t = VT_PTR; - v1.r = VT_LOCAL | VT_LVAL; - v1.c.i = fc; - load(r, &v1); - fc = 0; - } - - assert(!(vtop[-1].r & VT_LVAL)); - if (swapped) { - assert(vtop->r & VT_LVAL); - gv(RC_FLOAT); - vswap(); - } - - if ((ft & VT_BTYPE) == VT_DOUBLE) { - o(0xf2); - } else { - o(0xf3); - } - o(0x0f); - o(0x58 + a); - - if (vtop->r & VT_LVAL) { - gen_modrm(vtop[-1].r, r, vtop->sym, fc); - } else { - o(0xc0 + REG_VALUE(vtop[0].r) + REG_VALUE(vtop[-1].r)*8); - } - - vtop--; - } - } -} - -/* convert integers to fp 't' type. Must handle 'int', 'unsigned int' - and 'long long' cases. */ -void gen_cvt_itof(int t) -{ - if ((t & VT_BTYPE) == VT_LDOUBLE) { - save_reg(TREG_ST0); - gv(RC_INT); - if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { - /* signed long long to float/double/long double (unsigned case - is handled generically) */ - o(0x50 + (vtop->r & VT_VALMASK)); /* push r */ - o(0x242cdf); /* fildll (%rsp) */ - o(0x08c48348); /* add $8, %rsp */ - } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == - (VT_INT | VT_UNSIGNED)) { - /* unsigned int to float/double/long double */ - o(0x6a); /* push $0 */ - g(0x00); - o(0x50 + (vtop->r & VT_VALMASK)); /* push r */ - o(0x242cdf); /* fildll (%rsp) */ - o(0x10c48348); /* add $16, %rsp */ - } else { - /* int to float/double/long double */ - o(0x50 + (vtop->r & VT_VALMASK)); /* push r */ - o(0x2404db); /* fildl (%rsp) */ - o(0x08c48348); /* add $8, %rsp */ - } - vtop->r = TREG_ST0; - } else { - int r = get_reg(RC_FLOAT); - gv(RC_INT); - o(0xf2 + ((t & VT_BTYPE) == VT_FLOAT?1:0)); - if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == - (VT_INT | VT_UNSIGNED) || - (vtop->type.t & VT_BTYPE) == VT_LLONG) { - o(0x48); /* REX */ - } - o(0x2a0f); - o(0xc0 + (vtop->r & VT_VALMASK) + REG_VALUE(r)*8); /* cvtsi2sd */ - vtop->r = r; - } -} - -/* convert from one floating point type to another */ -void gen_cvt_ftof(int t) -{ - int ft, bt, tbt; - - ft = vtop->type.t; - bt = ft & VT_BTYPE; - tbt = t & VT_BTYPE; - - if (bt == VT_FLOAT) { - gv(RC_FLOAT); - if (tbt == VT_DOUBLE) { - o(0x140f); /* unpcklps */ - o(0xc0 + REG_VALUE(vtop->r)*9); - o(0x5a0f); /* cvtps2pd */ - o(0xc0 + REG_VALUE(vtop->r)*9); - } else if (tbt == VT_LDOUBLE) { - save_reg(RC_ST0); - /* movss %xmm0,-0x10(%rsp) */ - o(0x110ff3); - o(0x44 + REG_VALUE(vtop->r)*8); - o(0xf024); - o(0xf02444d9); /* flds -0x10(%rsp) */ - vtop->r = TREG_ST0; - } - } else if (bt == VT_DOUBLE) { - gv(RC_FLOAT); - if (tbt == VT_FLOAT) { - o(0x140f66); /* unpcklpd */ - o(0xc0 + REG_VALUE(vtop->r)*9); - o(0x5a0f66); /* cvtpd2ps */ - o(0xc0 + REG_VALUE(vtop->r)*9); - } else if (tbt == VT_LDOUBLE) { - save_reg(RC_ST0); - /* movsd %xmm0,-0x10(%rsp) */ - o(0x110ff2); - o(0x44 + REG_VALUE(vtop->r)*8); - o(0xf024); - o(0xf02444dd); /* fldl -0x10(%rsp) */ - vtop->r = TREG_ST0; - } - } else { - int r; - gv(RC_ST0); - r = get_reg(RC_FLOAT); - if (tbt == VT_DOUBLE) { - o(0xf0245cdd); /* fstpl -0x10(%rsp) */ - /* movsd -0x10(%rsp),%xmm0 */ - o(0x100ff2); - o(0x44 + REG_VALUE(r)*8); - o(0xf024); - vtop->r = r; - } else if (tbt == VT_FLOAT) { - o(0xf0245cd9); /* fstps -0x10(%rsp) */ - /* movss -0x10(%rsp),%xmm0 */ - o(0x100ff3); - o(0x44 + REG_VALUE(r)*8); - o(0xf024); - vtop->r = r; - } - } -} - -/* convert fp to int 't' type */ -void gen_cvt_ftoi(int t) -{ - int ft, bt, size, r; - ft = vtop->type.t; - bt = ft & VT_BTYPE; - if (bt == VT_LDOUBLE) { - gen_cvt_ftof(VT_DOUBLE); - bt = VT_DOUBLE; - } - - gv(RC_FLOAT); - if (t != VT_INT) - size = 8; - else - size = 4; - - r = get_reg(RC_INT); - if (bt == VT_FLOAT) { - o(0xf3); - } else if (bt == VT_DOUBLE) { - o(0xf2); - } else { - assert(0); - } - orex(size == 8, r, 0, 0x2c0f); /* cvttss2si or cvttsd2si */ - o(0xc0 + REG_VALUE(vtop->r) + REG_VALUE(r)*8); - vtop->r = r; -} - -/* computed goto support */ -void ggoto(void) -{ - gcall_or_jmp(1); - vtop--; -} - -/* Save the stack pointer onto the stack and return the location of its address */ -ST_FUNC void gen_vla_sp_save(int addr) { - /* mov %rsp,addr(%rbp)*/ - gen_modrm64(0x89, TREG_RSP, VT_LOCAL, NULL, addr); -} - -/* Restore the SP from a location on the stack */ -ST_FUNC void gen_vla_sp_restore(int addr) { - gen_modrm64(0x8b, TREG_RSP, VT_LOCAL, NULL, addr); -} - -/* Subtract from the stack pointer, and push the resulting value onto the stack */ -ST_FUNC void gen_vla_alloc(CType *type, int align) { -#ifdef TCC_TARGET_PE - /* alloca does more than just adjust %rsp on Windows */ - vpush_global_sym(&func_old_type, TOK_alloca); - vswap(); /* Move alloca ref past allocation size */ - gfunc_call(1); - vset(type, REG_IRET, 0); -#else - int r; - r = gv(RC_INT); /* allocation size */ - /* sub r,%rsp */ - o(0x2b48); - o(0xe0 | REG_VALUE(r)); - /* We align to 16 bytes rather than align */ - /* and ~15, %rsp */ - o(0xf0e48348); - vpop(); -#endif -} - - -/* end of x86-64 code generator */ -/*************************************************************/ -#endif /* ! TARGET_DEFS_ONLY */ -/******************************************************/ diff --git a/include/vcmp.h b/include/vcmp.h index 2aba70cb..7aa5bfa5 100644 --- a/include/vcmp.h +++ b/include/vcmp.h @@ -2,7 +2,7 @@ Project: Vice City Multiplayer 0.4 Server / Plugin Kit File: plugin.h - Copyright 2011 Ago Allikmaa (maxorator) + Copyright 2011-2016 Ago Allikmaa (maxorator) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,966 +19,930 @@ #pragma once -#if !defined _MSC_VER || _MSC_VER >= 1600 #include -#elif defined _MSC_VER -typedef unsigned __int64 uint64_t; -#endif +#include typedef struct { - unsigned int uStructSize; - char szServerName[128]; - unsigned int uMaxPlayers; - unsigned int uPort; - unsigned int uFlags; + uint32_t structSize; + char serverName[128]; + uint32_t maxPlayers; + uint32_t port; + uint32_t flags; } ServerSettings; +#define PLUGIN_API_MAJOR 2 +#define PLUGIN_API_MINOR 0 + typedef struct { - unsigned int uStructSize; - int nPluginId; - char szName[32]; - unsigned int uPluginVer; + uint32_t structSize; + uint32_t pluginId; + char name[32]; + uint32_t pluginVersion; + uint16_t apiMajorVersion; + uint16_t apiMinorVersion; } PluginInfo; -#define SDK_ENTPOOL_VEHICLE 1 -#define SDK_ENTPOOL_OBJECT 2 -#define SDK_ENTPOOL_PICKUP 3 -#define SDK_ENTPOOL_RADIO 4 -#define SDK_ENTPOOL_SPRITE 5 -#define SDK_ENTPOOL_TEXTDRAW 6 -#define SDK_ENTPOOL_BLIP 7 +typedef enum { + vcmpErrorNone = 0, + vcmpErrorNoSuchEntity = 1, + vcmpErrorBufferTooSmall = 2, + vcmpErrorTooLargeInput = 3, + vcmpErrorArgumentOutOfBounds = 4, + vcmpErrorNullArgument = 5, + vcmpErrorPoolExhausted = 6, + vcmpErrorInvalidName = 7, + vcmpErrorRequestDenied = 8, + forceSizeVcmpError = INT32_MAX +} vcmpError; -#define SDK_PSTATE_NONE 0 -#define SDK_PSTATE_NORMAL 1 -#define SDK_PSTATE_AIM 2 -#define SDK_PSTATE_DRIVER 3 -#define SDK_PSTATE_PASSENGER 4 -#define SDK_PSTATE_ENTER_DRIVER 5 -#define SDK_PSTATE_ENTER_PASS 6 -#define SDK_PSTATE_EXIT 7 -#define SDK_PSTATE_UNSPAWNED 8 +typedef enum { + vcmpEntityPoolVehicle = 1, + vcmpEntityPoolObject = 2, + vcmpEntityPoolPickup = 3, + vcmpEntityPoolRadio = 4, + vcmpEntityPoolBlip = 7, + vcmpEntityPoolCheckPoint = 8, + forceSizeVcmpEntityPool = INT32_MAX +} vcmpEntityPool; -#define SDK_PLAYERUPD_NORMAL 0 -#define SDK_PLAYERUPD_AIMING 1 -#define SDK_PLAYERUPD_DRIVER 2 -#define SDK_PLAYERUPD_PASSENGER 3 +typedef enum { + vcmpDisconnectReasonTimeout = 0, + vcmpDisconnectReasonQuit = 1, + vcmpDisconnectReasonKick = 2, + vcmpDisconnectReasonCrash = 3, + vcmpDisconnectReasonAntiCheat = 4, + forceSizeVcmpDisconnectReason = INT32_MAX +} vcmpDisconnectReason; -#define SDK_VSYNCTYPE_NONE 0 -#define SDK_VSYNCTYPE_DRIVER 1 -#define SDK_VSYNCTYPE_DRIVEREX 2 -#define SDK_VSYNCTYPE_PASSENGER 3 -#define SDK_VSYNCTYPE_NEAR 4 +typedef enum { + vcmpBodyPartBody = 0, + vcmpBodyPartTorso = 1, + vcmpBodyPartLeftArm = 2, + vcmpBodyPartRightArm = 3, + vcmpBodyPartLeftLeg = 4, + vcmpBodyPartRightLeg = 5, + vcmpBodyPartHead = 6, + vcmpBodyPartInVehicle = 7, + forceSizeVcmpBodyPart = INT32_MAX +} vcmpBodyPart; -#define SDK_VUPDATE_DRIVERSYNC 0 -#define SDK_VUPDATE_OTHERSYNC 1 -#define SDK_VUPDATE_POSITION 2 -#define SDK_VUPDATE_HEALTH 4 -#define SDK_VUPDATE_COLOUR 5 -#define SDK_VUPDATE_ROTATION 6 +typedef enum { + vcmpPlayerStateNone = 0, + vcmpPlayerStateNormal = 1, + vcmpPlayerStateAim = 2, + vcmpPlayerStateDriver = 3, + vcmpPlayerStatePassenger = 4, + vcmpPlayerStateEnterDriver = 5, + vcmpPlayerStateEnterPassenger = 6, + vcmpPlayerStateExit = 7, + vcmpPlayerStateUnspawned = 8, + forceSizeVcmpPlayerState = INT32_MAX +} vcmpPlayerState; -typedef unsigned int (*SDK_GetServerVersion) (void); -typedef unsigned int (*SDK_GetServerSettings) (ServerSettings* pstSettings); -typedef unsigned int (*SDK_ExportFunctions) (int nPluginId, void** ppFunctionList, unsigned int uSize); -typedef unsigned int (*SDK_GetNumberOfPlugins) (void); -typedef unsigned int (*SDK_GetPluginInfo) (int nPluginId, PluginInfo* pstPluginInfo); -typedef int (*SDK_FindPlugin) (char* pszPluginName); -typedef void** (*SDK_GetPluginExports) (int nPluginId, unsigned int* puSize); -typedef int (*SDK_GetTime) (uint64_t* pullTime); -typedef int (*SDK_printf) (const char* pszFormat, ...); -typedef int (*SDK_SendCustomCommand) (unsigned int uCmdType, const char* pszFormat, ...); -typedef int (*SDK_SendClientMessage) (int nPlayerId, unsigned int uColour, const char* pszFormat, ...); -typedef int (*SDK_SendGameMessage) (int nPlayerId, int nType, const char* pszFormat, ... ); -typedef int (*SDK_SetServerName) (const char* pszText); -typedef int (*SDK_GetServerName) (char* pszBuffer, int nBufferLen); -typedef int (*SDK_SetMaxPlayers) (int nMaxPlayers); -typedef int (*SDK_GetMaxPlayers) (void); -typedef int (*SDK_SetServerPassword) (char* pszBuffer); -typedef int (*SDK_GetServerPassword) (char* pszBuffer, int nBufferLen); -typedef int (*SDK_SetGameModeText) (const char* pszText); -typedef int (*SDK_GetGameModeText) (char* pszBuffer, int nBufferLen); -typedef int (*SDK_ShutdownServer) (void); -typedef int (*SDK_SetWorldBounds) (float fMaxX, float fMinX, float fMaxY, float fMinY); -typedef int (*SDK_GetWorldBounds) (float* pfMaxX, float* pfMinX, float* pfMaxY, float* pfMinY); -typedef int (*SDK_SetWastedSettings) (unsigned int dwDeathTimer, unsigned int dwFadeTimer, float fFadeInSpeed, float fFadeOutSpeed, unsigned int dwFadeColour, unsigned int dwCorpseFadeStart, unsigned int dwCorpseFadeTime); -typedef int (*SDK_GetWastedSettings) (unsigned int* pdwDeathTimer, unsigned int* pdwFadeTimer, float* pfFadeInSpeed, float* pfFadeOutSpeed, unsigned int* pdwFadeColour, unsigned int* pdwCorpseFadeStart, unsigned int* pdwCorpseFadeTime); -typedef int (*SDK_SetTimeRate) (unsigned int uTimeRate); -typedef unsigned int (*SDK_GetTimeRate) (void); -typedef int (*SDK_SetHour) (int nHour); -typedef int (*SDK_GetHour) (void); -typedef int (*SDK_SetMinute) (int nMinute); -typedef int (*SDK_GetMinute) (void); -typedef int (*SDK_SetWeather) (int nWeather); -typedef int (*SDK_GetWeather) (void); -typedef int (*SDK_SetGravity) (float fGravity); -typedef float (*SDK_GetGravity) (void); -typedef int (*SDK_SetGamespeed) (float fGamespeed); -typedef float (*SDK_GetGamespeed) (void); -typedef int (*SDK_SetWaterLevel) (float fWaterLevel); -typedef float (*SDK_GetWaterLevel) (void); -typedef int (*SDK_SetMaxHeight) (float fHeight); -typedef float (*SDK_GetMaxHeight) (void); -typedef int (*SDK_SetKillCmdDelay) (int nDelay); -typedef int (*SDK_GetKillCmdDelay) (void); -typedef int (*SDK_SetVehiclesForcedRespawnHeight) (float fHeight); -typedef float (*SDK_GetVehiclesForcedRespawnHeight) (void); -typedef int (*SDK_ToggleSyncFrameLimiter) (unsigned int bToggle); -typedef unsigned int (*SDK_EnabledSyncFrameLimiter) (void); -typedef int (*SDK_ToggleFrameLimiter) (unsigned int bToggle); -typedef unsigned int (*SDK_EnabledFrameLimiter) (void); -typedef int (*SDK_ToggleTaxiBoostJump) (unsigned int bToggle); -typedef unsigned int (*SDK_EnabledTaxiBoostJump) (void); -typedef int (*SDK_ToggleDriveOnWater) (unsigned int bToggle); -typedef unsigned int (*SDK_EnabledDriveOnWater) (void); -typedef int (*SDK_ToggleFastSwitch) (unsigned int bToggle); -typedef unsigned int (*SDK_EnabledFastSwitch) (void); -typedef int (*SDK_ToggleFriendlyFire) (unsigned int bToggle); -typedef unsigned int (*SDK_EnabledFriendlyFire) (void); -typedef int (*SDK_ToggleDisableDriveby) (unsigned int bToggle); -typedef unsigned int (*SDK_EnabledDisableDriveby) (void); -typedef int (*SDK_TogglePerfectHandling) (unsigned int bToggle); -typedef unsigned int (*SDK_EnabledPerfectHandling) (void); -typedef int (*SDK_ToggleFlyingCars) (unsigned int bToggle); -typedef unsigned int (*SDK_EnabledFlyingCars) (void); -typedef int (*SDK_ToggleJumpSwitch) (unsigned int bToggle); -typedef unsigned int (*SDK_EnabledJumpSwitch) (void); -typedef int (*SDK_ToggleShowMarkers) (unsigned int bToggle); -typedef unsigned int (*SDK_EnabledShowMarkers) (void); -typedef int (*SDK_ToggleOnlyShowTeamMarkers) (unsigned int bToggle); -typedef unsigned int (*SDK_EnabledOnlyShowTeamMarkers) (void); -typedef int (*SDK_ToggleStuntBike) (unsigned int bToggle); -typedef unsigned int (*SDK_EnabledStuntBike) (void); -typedef int (*SDK_ToggleShootInAir) (unsigned int bToggle); -typedef unsigned int (*SDK_EnabledShootInAir) (void); -typedef int (*SDK_ToggleShowNametags) (unsigned int bToggle); -typedef unsigned int (*SDK_EnabledShowNametags) (void); -typedef int (*SDK_ToggleJoinMessages) (unsigned int bToggle); -typedef unsigned int (*SDK_EnabledJoinMessages) (void); -typedef int (*SDK_ToggleDeathMessages) (unsigned int bToggle); -typedef unsigned int (*SDK_EnabledDeathMessages) (void); -typedef int (*SDK_ToggleChatTagsByDefaultEnabled) (unsigned int bToggle); -typedef unsigned int (*SDK_EnabledChatTagsByDefault) (void); -typedef int (*SDK_CreateExplosion) (int nWorldId, int nType, float fPosX, float fPosY, float fPosZ, int nSourcePlayerId, unsigned int bGroundLevel); -typedef int (*SDK_PlaySound) (int nWorldId, int nSoundId, float fPosX, float fPosY, float fPosZ); -typedef int (*SDK_HideMapObject) (int nModelId, int nTenthX, int nTenthY, int nTenthZ); -typedef int (*SDK_ShowMapObject) (int nModelId, int nTenthX, int nTenthY, int nTenthZ); -typedef int (*SDK_ShowAllMapObjects) (void); -typedef int (*SDK_SetWeaponDataValue) (int nWeaponId, int nFieldId, double fValue); -typedef double (*SDK_GetWeaponDataValue) (int nWeaponId, int nFieldId); -typedef int (*SDK_ResetWeaponDataValue) (int nWeaponId, int nFieldId); -typedef unsigned int (*SDK_IsWeaponDataValueModified) (int nWeaponId, int nFieldId); -typedef int (*SDK_ResetWeaponData) (int nWeaponId); -typedef int (*SDK_ResetAllWeaponData) (void); -typedef int (*SDK_GetKeyBindUnusedSlot) (void); -typedef unsigned int (*SDK_GetKeyBindData) (int nBindId, unsigned int* pbOnRelease, int* nKeyOne, int* pnKeyTwo, int* pnKeyThree); -typedef unsigned int (*SDK_RegisterKeyBind) (int nBindId, unsigned int bOnRelease, int nKeyOne, int nKeyTwo, int nKeyThree); -typedef unsigned int (*SDK_RemoveKeyBind) (int nBindId); -typedef void (*SDK_RemoveAllKeyBinds) (void); -typedef int (*SDK_CreateCoordBlip) (int nIndex, int nWorld, float fX, float fY, float fZ, int nScale, unsigned int uColour, int nSprite); -typedef void (*SDK_DestroyCoordBlip) (int nIndex); -typedef unsigned int (*SDK_GetCoordBlipInfo) (int nIndex, int* pnWorld, float* pfX, float* pfY, float* pfZ, int* pnScale, unsigned int* puColour, int* pnSprite); -typedef int (*SDK_CreateSprite) (int nIndex, const char * pszFilename, int fX, int fY, int fRotX, int fRotY, float fRotation, unsigned char byAlpha, unsigned int isRelative); -typedef void (*SDK_DestroySprite) (int nIndex); -typedef void (*SDK_ShowSprite) (int nIndex, int nPlayerId); -typedef void (*SDK_HideSprite) (int nIndex, int nPlayerId); -typedef void (*SDK_MoveSprite) (int nIndex, int nPlayerId, int fX, int fY); -typedef void (*SDK_SetSpriteCenter) (int nIndex, int nPlayerId, int fX, int fY); -typedef void (*SDK_RotateSprite) (int nIndex, int nPlayerId, float fRotation); -typedef void (*SDK_SetSpriteAlpha) (int nIndex, int nPlayerId, unsigned char byAlpha); -typedef void (*SDK_SetSpriteRelativity) (int nIndex, int nPlayerId, unsigned int isRelative); -typedef int (*SDK_CreateTextdraw) (int nIndex, const char * pszText, int lX, int lY, unsigned int dwColour, unsigned int isRelative); -typedef void (*SDK_DestroyTextdraw) (int nIndex); -typedef void (*SDK_ShowTextdraw) (int nIndex, int nPlayerId); -typedef void (*SDK_HideTextdraw) (int nIndex, int nPlayerId); -typedef void (*SDK_MoveTextdraw) (int nIndex, int nPlayerId, int lX, int lY); -typedef void (*SDK_SetTextdrawColour) (int nIndex, int nPlayerId, unsigned int dwColour); -typedef void (*SDK_SetTextdrawRelativity) (int nIndex, int nPlayerId, unsigned int isRelative); -typedef int (*SDK_AddRadioStream) (int nRadioId, const char* pszRadioName, const char* pszRadioURL, unsigned int bIsListed); -typedef int (*SDK_RemoveRadioStream) (int nRadioId); -typedef int (*SDK_SetUseClasses) (unsigned int bToggle); -typedef unsigned int (*SDK_GetUseClasses) (void); -typedef int (*SDK_GetPlayerClass) (int nPlayerId); -typedef int (*SDK_AddPlayerClass) (int nTeamId, unsigned int uColour, int nModelId, float fSpawnX, float fSpawnY, float fSpawnZ, float fAngleZ, int nWep1, int nWep1Ammo, int nWep2, int nWep2Ammo, int nWep3, int nWep3Ammo); -typedef int (*SDK_SetSpawnPlayerPos) (float fPosX, float fPosY, float fPosZ); -typedef int (*SDK_SetSpawnCameraPos) (float fPosX, float fPosY, float fPosZ); -typedef int (*SDK_SetSpawnCameraLookAt) (float fPosX, float fPosY, float fPosZ); -typedef unsigned int (*SDK_IsPlayerAdmin) (int nPlayerId); -typedef int (*SDK_SetPlayerAdmin) (int nPlayerId, unsigned int bToggle); -typedef int (*SDK_GetPlayerIP) (int nPlayerId, char* pszBuffer, int nBufferLen); -typedef int (*SDK_KickPlayer) (int nPlayerId); -typedef int (*SDK_BanPlayer) (int nPlayerId); -typedef int (*SDK_BanIP) (char* pszIPAddress); -typedef int (*SDK_UnbanIP) (char* pszIPAddress); -typedef unsigned int (*SDK_IsIPBanned) (char* pszIPAddress); -typedef int (*SDK_GetPlayerIDFromName) (char* pszName); -typedef unsigned int (*SDK_IsPlayerConnected) (int nPlayerId); -typedef unsigned int (*SDK_IsPlayerSpawned) (int nPlayerId); -typedef unsigned int (*SDK_IsPlayerStreamedForPlayer) (int nCheckPlayer, int nPlayerId); -typedef unsigned int (*SDK_GetPlayerKey) (int nPlayerId); -typedef int (*SDK_SetPlayerWorld) (int nPlayerId, int nWorld); -typedef int (*SDK_GetPlayerWorld) (int nPlayerId); -typedef int (*SDK_SetPlayerSecWorld) (int nPlayerId, int nSecWorld); -typedef int (*SDK_GetPlayerSecWorld) (int nPlayerId); -typedef int (*SDK_GetPlayerUniqueWorld) (int nPlayerId); -typedef unsigned int (*SDK_IsPlayerWorldCompatible) (int nPlayerId, int nWorld); -typedef int (*SDK_GetPlayerState) (int nPlayerId); -typedef int (*SDK_GetPlayerName) (int nPlayerId, char* szBuffer, int nBufferLen); -typedef unsigned int (*SDK_SetPlayerName) (int nPlayerId, const char* pszName); -typedef int (*SDK_SetPlayerTeam) (int nPlayerId, int nTeamId); -typedef int (*SDK_GetPlayerTeam) (int nPlayerId); -typedef int (*SDK_SetPlayerSkin) (int nPlayerId, int nSkinId); -typedef int (*SDK_GetPlayerSkin) (int nPlayerId); -typedef int (*SDK_SetPlayerColour) (int nPlayerId, unsigned int uColour); -typedef unsigned int (*SDK_GetPlayerColour) (int nPlayerId); -typedef int (*SDK_ForcePlayerSpawn) (int nPlayerId); -typedef int (*SDK_ForcePlayerSelect) (int nPlayerId); -typedef int (*SDK_ForceAllSelect) (void); -typedef int (*SDK_GivePlayerMoney) (int nPlayerId, int nAmount); -typedef int (*SDK_SetPlayerMoney) (int nPlayerId, int nAmount); -typedef int (*SDK_GetPlayerMoney) (int nPlayerId); -typedef int (*SDK_SetPlayerScore) (int nPlayerId, int nScore); -typedef int (*SDK_GetPlayerScore) (int nPlayerId); -typedef int (*SDK_GetPlayerPing) (int nPlayerId); -typedef unsigned int (*SDK_IsPlayerTyping) (int nPlayerId); -typedef double (*SDK_GetPlayerFPS) (int nPlayerId); -typedef int (*SDK_GetPlayerUID) (int nPlayerId, char* szBuffer, int nBufferLen); -typedef int (*SDK_GetPlayerWantedLevel) (int nPlayerId); -typedef int (*SDK_SetPlayerHealth) (int nPlayerId, float fHealth); -typedef float (*SDK_GetPlayerHealth) (int nPlayerId); -typedef int (*SDK_SetPlayerArmour) (int nPlayerId, float fArmour); -typedef float (*SDK_GetPlayerArmour) (int nPlayerId); -typedef int (*SDK_SetPlayerImmunityFlags) (int nPlayerId, int nFlags); -typedef int (*SDK_GetPlayerImmunityFlags) (int nPlayerId); -typedef int (*SDK_SetPlayerPos) (int nPlayerId, float fPosX, float fPosY, float fPosZ); -typedef int (*SDK_GetPlayerPos) (int nPlayerId, float* pfPosX, float* pfPosY, float* pfPosZ); -typedef int (*SDK_SetPlayerSpeed) (int nPlayerId, float fSpeedX, float fSpeedY, float fSpeedZ); -typedef int (*SDK_GetPlayerSpeed) (int nPlayerId, float* pfSpeedX, float* pfSpeedY, float* pfSpeedZ); -typedef int (*SDK_AddPlayerSpeed) (int nPlayerId, float fSpeedX, float fSpeedY, float fSpeedZ); -typedef int (*SDK_SetPlayerHeading) (int nPlayerId, float fAngleZ); -typedef float (*SDK_GetPlayerHeading) (int nPlayerId); -typedef int (*SDK_SetPlayerAlpha) (int nPlayerId, int nAlpha, int nFadeTime); -typedef int (*SDK_GetPlayerAlpha) (int nPlayerId); -typedef unsigned int (*SDK_GetPlayerOnFireStatus) (int nPlayerId); -typedef unsigned int (*SDK_GetPlayerCrouchStatus) (int nPlayerId); -typedef int (*SDK_GetPlayerAction) (int nPlayerId); -typedef int (*SDK_GetPlayerGameKeys) (int nPlayerId); -typedef unsigned int (*SDK_GetPlayerAimPos) (int nPlayerId, float* pfX, float* pfY, float* pfZ); -typedef unsigned int (*SDK_GetPlayerAimDir) (int nPlayerId, float* pfX, float* pfY, float* pfZ); -typedef int (*SDK_PutPlayerInVehicle) (int nPlayerId, int nVehicleId, int nSlot, unsigned int bMakeRoom, unsigned int bWarp); -typedef int (*SDK_RemovePlayerFromVehicle) (int nPlayerId); -typedef int (*SDK_GetPlayerInVehicleStatus) (int nPlayerId); -typedef int (*SDK_GetPlayerInVehicleSlot) (int nPlayerId); -typedef int (*SDK_GetPlayerVehicleID) (int nPlayerId); -typedef int (*SDK_TogglePlayerControllable) (int nPlayerId, unsigned int bToggle); -typedef unsigned int (*SDK_EnabledPlayerControllable) (int nPlayerId); -typedef int (*SDK_TogglePlayerDriveby) (int nPlayerId, unsigned int bToggle); -typedef unsigned int (*SDK_EnabledPlayerDriveby) (int nPlayerId); -typedef int (*SDK_TogglePlayerWhiteScanlines) (int nPlayerId, unsigned int bToggle); -typedef unsigned int (*SDK_EnabledPlayerWhiteScanlines) (int nPlayerId); -typedef int (*SDK_TogglePlayerGreenScanlines) (int nPlayerId, unsigned int bToggle); -typedef unsigned int (*SDK_EnabledPlayerGreenScanlines) (int nPlayerId); -typedef int (*SDK_TogglePlayerWidescreen) (int nPlayerId, unsigned int bToggle); -typedef unsigned int (*SDK_EnabledPlayerWidescreen) (int nPlayerId); -typedef int (*SDK_TogglePlayerShowMarkers) (int nPlayerId, unsigned int bToggle); -typedef unsigned int (*SDK_EnabledPlayerShowMarkers) (int nPlayerId); -typedef int (*SDK_TogglePlayerAttackPriv) (int nPlayerId, unsigned int bToggle); -typedef unsigned int (*SDK_EnabledPlayerAttackPriv) (int nPlayerId); -typedef int (*SDK_TogglePlayerHasMarker) (int nPlayerId, unsigned int bToggle); -typedef unsigned int (*SDK_EnabledPlayerHasMarker) (int nPlayerId); -typedef int (*SDK_TogglePlayerChatTagsEnabled) (int nPlayerId, unsigned int bToggle); -typedef unsigned int (*SDK_EnabledPlayerChatTags) (int nPlayerId); -typedef int (*SDK_TogglePlayerDrunkEffects) (int nPlayerId, unsigned int bToggle); -typedef unsigned int (*SDK_EnabledPlayerDrunkEffects) (int nPlayerId); -typedef int (*SDK_GivePlayerWeapon) (int nPlayerId, int nWeaponId, int nAmmo); -typedef int (*SDK_SetPlayerWeapon) (int nPlayerId, int nWeaponId, int nAmmo); -typedef int (*SDK_GetPlayerWeapon) (int nPlayerId); -typedef int (*SDK_GetPlayerWeaponAmmo) (int nPlayerId); -typedef int (*SDK_SetPlayerWeaponSlot) (int nPlayerId, int nSlot); -typedef int (*SDK_GetPlayerWeaponSlot) (int nPlayerId); -typedef int (*SDK_GetPlayerWeaponAtSlot) (int nPlayerId, int nSlot); -typedef int (*SDK_GetPlayerAmmoAtSlot) (int nPlayerId, int nSlot); -typedef int (*SDK_RemovePlayerWeapon) (int nPlayerId, int nWeaponId); -typedef int (*SDK_RemoveAllWeapons) (int nPlayerId); -typedef int (*SDK_SetCameraPosition) (int nPlayerId, float fPosX, float fPosY, float fPosZ, float fLookX, float fLookY, float fLookZ); -typedef int (*SDK_RestoreCamera) (int nPlayerId); -typedef unsigned int (*SDK_IsCameraLocked) (int nPlayerId); -typedef int (*SDK_SetPlayerAnimation) (int nPlayerId, int nGroupId, int nAnimationId); -typedef int (*SDK_SetPlayerWantedLevel) (int nPlayerId, int nLevel); -typedef int (*SDK_GetPlayerStandingOnVehicle) (int nPlayerId); -typedef int (*SDK_GetPlayerStandingOnObject) (int nPlayerId); -typedef unsigned int (*SDK_IsPlayerAway) (int nPlayerId); -typedef int (*SDK_GetPlayerSpectateTarget) (int nPlayerId); -typedef int (*SDK_SetPlayerSpectateTarget) (int nPlayerId, int nTargetId); -typedef unsigned int (*SDK_RedirectPlayerToServer) (int nPlayerId, const char* szIP, unsigned int usPort, const char* szNickname, const char* szServerPass, const char* szUserPass); -typedef int (*SDK_CreateVehicle) (int nModelId, int nWorld, float fPosX, float fPosY, float fPosZ, float fAngleZ, int nColour1, int nColour2); -typedef int (*SDK_DeleteVehicle) (int nVehicleId); -typedef int (*SDK_GetVehicleSyncSource) (int nVehicleId); -typedef int (*SDK_GetVehicleSyncType) (int nVehicleId); -typedef unsigned int (*SDK_IsVehicleStreamedForPlayer) (int nVehicleId, int nPlayerId); -typedef int (*SDK_SetVehicleWorld) (int nVehicleId, int nWorld); -typedef int (*SDK_GetVehicleWorld) (int nVehicleId); -typedef int (*SDK_GetVehicleModel) (int nVehicleId); -typedef int (*SDK_GetVehicleOccupant) (int nVehicleId, int nSlotIndex); -typedef int (*SDK_RespawnVehicle) (int nVehicleId); -typedef int (*SDK_SetVehicleImmunityFlags) (int nVehicleId, int nImmuFlags); -typedef int (*SDK_GetVehicleImmunityFlags) (int nVehicleId); -typedef int (*SDK_KillVehicle) (int nVehicleId); -typedef unsigned int (*SDK_IsVehicleWrecked) (int nVehicleId); -typedef int (*SDK_SetVehiclePos) (int nVehicleId, float fPosX, float fPosY, float fPosZ, unsigned int bRemoveOccupants); -typedef int (*SDK_GetVehiclePos) (int nVehicleId, float* pfPosX, float* pfPosY, float* pfPosZ); -typedef int (*SDK_SetVehicleRot) (int nVehicleId, float fX, float fY, float fZ, float fW); -typedef int (*SDK_SetVehicleRotEuler) (int nVehicleId, float fX, float fY, float fZ); -typedef int (*SDK_GetVehicleRot) (int nVehicleId, float* pfX, float* pfY, float *pfZ, float *pfW); -typedef int (*SDK_GetVehicleRotEuler) (int nVehicleId, float* pfX, float* pfY, float *pfZ); -typedef int (*SDK_SetVehicleSpeed) (int nVehicleId, float fX, float fY, float fZ); -typedef int (*SDK_GetVehicleSpeed) (int nVehicleId, float* pfX, float* pfY, float* pfZ); -typedef int (*SDK_AddVehicleSpeed) (int nVehicleId, float fX, float fY, float fZ); -typedef int (*SDK_SetVehicleRelSpeed) (int nVehicleId, float fX, float fY, float fZ); -typedef int (*SDK_GetVehicleRelSpeed) (int nVehicleId, float* pfX, float* pfY, float* pfZ); -typedef int (*SDK_AddVehicleRelSpeed) (int nVehicleId, float fX, float fY, float fZ); -typedef int (*SDK_SetVehicleTurnSpeed) (int nVehicleId, float fX, float fY, float fZ); -typedef int (*SDK_GetVehicleTurnSpeed) (int nVehicleId, float* pfX, float* pfY, float* pfZ); -typedef int (*SDK_AddVehicleTurnSpeed) (int nVehicleId, float fX, float fY, float fZ); -typedef int (*SDK_SetVehicleRelTurnSpeed) (int nVehicleId, float fX, float fY, float fZ); -typedef int (*SDK_GetVehicleRelTurnSpeed) (int nVehicleId, float* pfX, float* pfY, float* pfZ); -typedef int (*SDK_AddVehicleRelTurnSpeed) (int nVehicleId, float fX, float fY, float fZ); -typedef int (*SDK_SetVehicleSpawnPos) (int nVehicleId, float fPosX, float fPosY, float fPosZ, float fAngleZ); -typedef int (*SDK_GetVehicleSpawnPos) (int nVehicleId, float* pfPosX, float* pfPosY, float* pfPosZ, float* pfAngleZ); -typedef int (*SDK_SetVehicleSpawnRot) (int nVehicleId, float fX, float fY, float fZ, float fW); -typedef int (*SDK_SetVehicleSpawnRotEuler) (int nVehicleId, float fX, float fY, float fZ); -typedef int (*SDK_GetVehicleSpawnRot) (int nVehicleId, float* pfX, float* pfY, float* pfZ, float* pfW); -typedef int (*SDK_GetVehicleSpawnRotEuler) (int nVehicleId, float* pfX, float* pfY, float* pfZ); -typedef int (*SDK_SetVehicleIdleRespawnTimer) (int nVehicleId, unsigned int uTimer); -typedef unsigned int (*SDK_GetVehicleIdleRespawnTimer) (int nVehicleId); -typedef int (*SDK_SetVehicleHealth) (int nVehicleId, float fHealth); -typedef float (*SDK_GetVehicleHealth) (int nVehicleId); -typedef int (*SDK_SetVehicleColour) (int nVehicleId, int nColour1, int nColour2); -typedef int (*SDK_GetVehicleColour) (int nVehicleId, int* pnColour1, int* pnColour2); -typedef int (*SDK_SetVehicleDoorsLocked) (int nVehicleId, unsigned int bToggle); -typedef unsigned int (*SDK_GetVehicleDoorsLocked) (int nVehicleId); -typedef int (*SDK_SetVehiclePartStatus) (int nVehicleId, int nPartId, int nStatus); -typedef int (*SDK_GetVehiclePartStatus) (int nVehicleId, int nPartId); -typedef int (*SDK_SetVehicleTyreStatus) (int nVehicleId, int nTyreId, int nStatus); -typedef int (*SDK_GetVehicleTyreStatus) (int nVehicleId, int nTyreId); -typedef int (*SDK_SetVehicleDamageData) (int nVehicleId, unsigned int uDamageData); -typedef unsigned int (*SDK_GetVehicleDamageData) (int nVehicleId); -typedef int (*SDK_SetVehicleAlarm) (int nVehicleId, unsigned int bToggle); -typedef unsigned int (*SDK_GetVehicleAlarm) (int nVehicleId); -typedef int (*SDK_SetVehicleLights) (int nVehicleId, unsigned int bToggle); -typedef unsigned int (*SDK_GetVehicleLights) (int nVehicleId); -typedef int (*SDK_SetVehicleRadio) (int nVehicleId, int nRadioId); -typedef int (*SDK_GetVehicleRadio) (int nVehicleId); -typedef int (*SDK_SetVehicleRadioLocked) (int nVehicleId, unsigned int bToggle); -typedef unsigned int (*SDK_IsVehicleRadioLocked) (int nVehicleId); -typedef unsigned int (*SDK_GetVehicleGhostState) (int nVehicleId); -typedef int (*SDK_SetVehicleGhostState) (int nVehicleId, unsigned int bToggle); -typedef unsigned int (*SDK_GetVehicleTurretRotation) (int nVehicleId, float* pfH, float* pfV); -typedef int (*SDK_ResetAllVehicleHandlings) (void); -typedef unsigned int (*SDK_ExistsHandlingRule) (int nModelIndex, int nRuleIndex); -typedef int (*SDK_SetHandlingRule) (int nModelIndex, int nRuleIndex, double fValue); -typedef double (*SDK_GetHandlingRule) (int nModelIndex, int nRuleIndex); -typedef int (*SDK_ResetHandlingRule) (int nModelIndex, int nRuleIndex); -typedef int (*SDK_ResetHandling) (int nModelIndex); -typedef unsigned int (*SDK_ExistsInstHandlingRule) (int nVehicleId, int nRuleIndex); -typedef int (*SDK_SetInstHandlingRule) (int nVehicleId, int nRuleIndex, double fValue); -typedef double (*SDK_GetInstHandlingRule) (int nVehicleId, int nRuleIndex); -typedef int (*SDK_ResetInstHandlingRule) (int nVehicleId, int nRuleIndex); -typedef int (*SDK_ResetInstHandling) (int nVehicleId); -typedef int (*SDK_CreatePickup) (int nModel, int nWorld, int nQuantity, float fPosX, float fPosY, float fPosZ, int nAlpha, unsigned int bAutomatic); -typedef int (*SDK_DeletePickup) (int nPickupId); -typedef unsigned int (*SDK_IsPickupStreamedForPlayer) (int nPickupId, int nPlayerId); -typedef int (*SDK_SetPickupWorld) (int nPickupId, int nWorld); -typedef int (*SDK_GetPickupWorld) (int nPickupId); -typedef int (*SDK_PickupGetAlpha) (int nPickupId); -typedef int (*SDK_PickupSetAlpha) (int nPickupId, int nAlpha); -typedef unsigned int (*SDK_PickupIsAutomatic) (int nPickupId); -typedef int (*SDK_PickupSetAutomatic) (int nPickupId, unsigned int bToggle); -typedef int (*SDK_SetPickupAutoTimer) (int nPickupId, int nTimer); -typedef int (*SDK_GetPickupAutoTimer) (int nPickupId); -typedef int (*SDK_PickupRefresh) (int nPickupId); -typedef int (*SDK_PickupGetPos) (int nPickupId, float* pfPosX, float* pfPosY, float* pfPosZ); -typedef int (*SDK_PickupSetPos) (int nPickupId, float fPosX, float fPosY, float fPosZ); -typedef int (*SDK_PickupGetModel) (int nPickupId); -typedef int (*SDK_PickupGetQuantity) (int nPickupId); -typedef int (*SDK_CreateObject) (int nModelId, int nWorld, float fPosX, float fPosY, float fPosZ, int nAlpha); -typedef int (*SDK_DeleteObject) (int nObjectId); -typedef unsigned int (*SDK_IsObjectStreamedForPlayer) (int nObjectId, int nPlayerId); -typedef int (*SDK_GetObjectModel) (int nObjectId); -typedef int (*SDK_SetObjectWorld) (int nObjectId, int nWorld); -typedef int (*SDK_GetObjectWorld) (int nObjectId); -typedef int (*SDK_SetObjectAlpha) (int nObjectId, int nAlpha, int nTime); -typedef int (*SDK_GetObjectAlpha) (int nObjectId); -typedef int (*SDK_MoveObjectTo) (int nObjectId, float fX, float fY, float fZ, int nTime); -typedef int (*SDK_MoveObjectBy) (int nObjectId, float fX, float fY, float fZ, int nTime); -typedef int (*SDK_SetObjectPos) (int nObjectId, float fX, float fY, float fZ); -typedef int (*SDK_GetObjectPos) (int nObjectId, float* pfPosX, float* pfPosY, float* pfPosZ); -typedef int (*SDK_RotObjectTo) (int nObjectId, float fX, float fY, float fZ, float fW, int nTime); -typedef int (*SDK_RotObjectToEuler) (int nObjectId, float fX, float fY, float fZ, int nTime); -typedef int (*SDK_RotObjectBy) (int nObjectId, float fX, float fY, float fZ, float fW, int nTime); -typedef int (*SDK_RotObjectByEuler) (int nObjectId, float fX, float fY, float fZ, int nTime); -typedef int (*SDK_GetObjectRot) (int nObjectId, float* pfX, float* pfY, float *pfZ, float *pfW); -typedef int (*SDK_GetObjectRotEuler) (int nObjectId, float* pfX, float* pfY, float *pfZ); -typedef int (*SDK_SetObjectShotReport) (int nObjectId, unsigned int bToggle); -typedef unsigned int (*SDK_IsObjectShotReport) (int nObjectId); -typedef int (*SDK_SetObjectBumpReport) (int nObjectId, unsigned int bToggle); -typedef unsigned int (*SDK_IsObjectBumpReport) (int nObjectId); -typedef int (*SDK_ToggleWallglitch) (unsigned int bToggle); -typedef unsigned int (*SDK_EnabledWallglitch) (void); -typedef int (*SDK_SetVehicleSiren) (int nVehicleId, unsigned int bToggle); -typedef unsigned int (*SDK_GetVehicleSiren) (int nVehicleId); -typedef int (*SDK_GetPlayerUID2) (int nPlayerId, char* szBuffer, int nBufferLen); -typedef int (*SDK_CreateCheckpoint) (int nPlayerId, int nWorld, float fPosX, float fPosY, float fPosZ, unsigned int nR, unsigned int nG, unsigned int nB, unsigned int nA, float fRadius); -typedef int (*SDK_DeleteCheckpoint) (int nCheckpointId); -typedef unsigned int (*SDK_IsCheckpointStreamedForPlayer) (int nCheckpointId, int nPlayerId); -typedef int (*SDK_SetCheckpointWorld) (int nCheckpointId, int nWorld); -typedef int (*SDK_GetCheckpointWorld) (int nCheckpointId); -typedef int (*SDK_SetCheckpointColor) (int nCheckpointId, unsigned int nR, unsigned int nG, unsigned int nB, unsigned int nA); -typedef unsigned int (*SDK_GetCheckpointColor) (int nCheckpointId, unsigned int* pnR, unsigned int* pnG, unsigned int* pnB, unsigned int* pnA); -typedef int (*SDK_SetCheckpointPos) (int nCheckpointId, float fPosX, float fPosY, float fPosZ); -typedef int (*SDK_GetCheckpointPos) (int nCheckpointId, float* pfPosX, float* pfPosY, float* pfPosZ); -typedef int (*SDK_SetCheckpointRadius) (int nCheckpointId, float fRadius); -typedef float (*SDK_GetCheckpointRadius) (int nCheckpointId); -typedef int (*SDK_GetCheckpointOwner) (int nCheckpointId); -typedef int (*SDK_CreateSphere) (int nPlayerId, int nWorld, float fPosX, float fPosY, float fPosZ, unsigned int nR, unsigned int nG, unsigned int nB, float fRadius); -typedef int (*SDK_DeleteSphere) (int nSphereId); -typedef unsigned int (*SDK_IsSphereStreamedForPlayer) (int nSphereId, int nPlayerId); -typedef int (*SDK_SetSphereWorld) (int nSphereId, int nWorld); -typedef int (*SDK_GetSphereWorld) (int nSphereId); -typedef int (*SDK_SetSphereColor) (int nSphereId, unsigned int nR, unsigned int nG, unsigned int nB); -typedef unsigned int (*SDK_GetSphereColor) (int nSphereId, unsigned int* pnR, unsigned int* pnG, unsigned int* pnB); -typedef int (*SDK_SetSpherePos) (int nSphereId, float fPosX, float fPosY, float fPosZ); -typedef int (*SDK_GetSpherePos) (int nSphereId, float* pfPosX, float* pfPosY, float* pfPosZ); -typedef int (*SDK_SetSphereRadius) (int nSphereId, float fRadius); -typedef float (*SDK_GetSphereRadius) (int nSphereId); -typedef int (*SDK_GetSphereOwner) (int nSphereId); -typedef int (*SDK_OnInitServer) (void); -typedef void (*SDK_OnShutdownServer) (void); -typedef void (*SDK_OnFrame) (float fElapsedTime); -typedef void (*SDK_OnPlayerConnect) (int nPlayerId); -typedef void (*SDK_OnPlayerDisconnect) (int nPlayerId, int nReason); -typedef void (*SDK_OnPlayerBeginTyping) (int nPlayerId); -typedef void (*SDK_OnPlayerEndTyping) (int nPlayerId); -typedef int (*SDK_OnPlayerRequestClass) (int nPlayerId, int nOffset); -typedef int (*SDK_OnPlayerRequestSpawn) (int nPlayerId); -typedef void (*SDK_OnPlayerSpawn) (int nPlayerId); -typedef void (*SDK_OnPlayerDeath) (int nPlayerId, int nKillerId, int nReason, int nBodyPart); -typedef void (*SDK_OnPlayerUpdate) (int nPlayerId, int nUpdateType); -typedef int (*SDK_OnPlayerRequestEnter) (int nPlayerId, int nVehicleId, int nSlotId); -typedef void (*SDK_OnPlayerEnterVehicle) (int nPlayerId, int nVehicleId, int nSlotId); -typedef void (*SDK_OnPlayerExitVehicle) (int nPlayerId, int nVehicleId); -typedef void (*SDK_OnPlayerNameChange) (int nPlayerId, const char* pszOldName, const char* pszNewName); -typedef void (*SDK_OnPlayerStateChange) (int nPlayerId, int nOldState, int nNewState); -typedef void (*SDK_OnPlayerActionChange) (int nPlayerId, int nOldAction, int nNewAction); -typedef void (*SDK_OnPlayerOnFireChange) (int nPlayerId, unsigned int bIsOnFireNow); -typedef void (*SDK_OnPlayerCrouchChange) (int nPlayerId, unsigned int bIsCrouchingNow); -typedef void (*SDK_OnPlayerGameKeysChange) (int nPlayerId, int nOldKeys, int nNewKeys); -typedef int (*SDK_OnPickupClaimPicked) (int nPickupId, int nPlayerId); -typedef void (*SDK_OnPickupPickedUp) (int nPickupId, int nPlayerId); -typedef void (*SDK_OnPickupRespawn) (int nPickupId); -typedef void (*SDK_OnVehicleUpdate) (int nVehicleId, int nUpdateType); -typedef void (*SDK_OnVehicleExplode) (int nVehicleId); -typedef void (*SDK_OnVehicleRespawn) (int nVehicleId); -typedef void (*SDK_OnObjectShot) (int nObjectId, int nPlayerId, int nWeapon); -typedef void (*SDK_OnObjectBump) (int nObjectId, int nPlayerId); -typedef int (*SDK_OnPublicMessage) (int nPlayerId, const char* pszText); -typedef int (*SDK_OnCommandMessage) (int nPlayerId, const char* pszText); -typedef int (*SDK_OnPrivateMessage) (int nPlayerId, int nTargetId, const char* pszText); -typedef int (*SDK_OnInternalCommand) (unsigned int uCmdType, const char* pszText); -typedef int (*SDK_OnLoginAttempt) (char* pszPlayerName, const char* pszUserPassword, const char* pszIpAddress); -typedef void (*SDK_OnEntityPoolChange) (int nEntityType, int nEntityId, unsigned int bDeleted); -typedef void (*SDK_OnKeyBindDown) (int nPlayerId, int nBindId); -typedef void (*SDK_OnKeyBindUp) (int nPlayerId, int nBindId); -typedef void (*SDK_OnPlayerAwayChange) (int nPlayerId, unsigned int bNewStatus); -typedef void (*SDK_OnPlayerSpectate) (int nPlayerId, int nTargetId); -typedef void (*SDK_OnPlayerCrashReport) (int nPlayerId, const char* pszReport); -typedef void (*SDK_OnServerPerformanceReport) (int nNumStats, const char** ppszDescription, unsigned long long* pnMillisecsSpent); -typedef void (*SDK_OnCheckpointEntered) (int nCheckpointId, int nPlayerId); -typedef void (*SDK_OnCheckpointExited) (int nCheckpointId, int nPlayerId); -typedef void (*SDK_OnSphereEntered) (int nSphereId, int nPlayerId); -typedef void (*SDK_OnSphereExited) (int nSphereId, int nPlayerId); +typedef enum { + vcmpPlayerUpdateNormal = 0, + vcmpPlayerUpdateAiming = 1, + vcmpPlayerUpdateDriver = 2, + vcmpPlayerUpdatePassenger = 3, + forceSizeVcmpPlayerUpdate = INT32_MAX +} vcmpPlayerUpdate; + +typedef enum { + vcmpPlayerVehicleOut = 0, + vcmpPlayerVehicleEntering = 1, + vcmpPlayerVehicleExiting = 2, + vcmpPlayerVehicleIn = 3, + forceSizeVcmpPlayerVehicle = INT32_MAX +} vcmpPlayerVehicle; + +typedef enum { + vcmpVehicleSyncNone = 0, + vcmpVehicleSyncDriver = 1, + vcmpVehicleSyncPassenger = 3, + vcmpVehicleSyncNear = 4, + forceSizeVcmpVehicleSync = INT32_MAX +} vcmpVehicleSync; + +typedef enum { + vcmpVehicleUpdateDriverSync = 0, + vcmpVehicleUpdateOtherSync = 1, + vcmpVehicleUpdatePosition = 2, + vcmpVehicleUpdateHealth = 4, + vcmpVehicleUpdateColour = 5, + vcmpVehicleUpdateRotation = 6, + forceSizeVcmpVehicleUpdate = INT32_MAX +} vcmpVehicleUpdate; + +typedef enum { + vcmpServerOptionSyncFrameLimiter = 0, + vcmpServerOptionFrameLimiter = 1, + vcmpServerOptionTaxiBoostJump = 2, + vcmpServerOptionDriveOnWater = 3, + vcmpServerOptionFastSwitch = 4, + vcmpServerOptionFriendlyFire = 5, + vcmpServerOptionDisableDriveBy = 6, + vcmpServerOptionPerfectHandling = 7, + vcmpServerOptionFlyingCars = 8, + vcmpServerOptionJumpSwitch = 9, + vcmpServerOptionShowMarkers = 10, + vcmpServerOptionOnlyShowTeamMarkers = 11, + vcmpServerOptionStuntBike = 12, + vcmpServerOptionShootInAir = 13, + vcmpServerOptionShowNameTags = 14, + vcmpServerOptionJoinMessages = 15, + vcmpServerOptionDeathMessages = 16, + vcmpServerOptionChatTagsEnabled = 17, + vcmpServerOptionUseClasses = 18, + vcmpServerOptionWallGlitch = 19, + vcmpServerOptionDisableBackfaceCulling = 20, + vcmpServerOptionDisableHeliBladeDamage = 21, + forceSizeVcmpServerOption = INT32_MAX +} vcmpServerOption; + +typedef enum { + vcmpPlayerOptionControllable = 0, + vcmpPlayerOptionDriveBy = 1, + vcmpPlayerOptionWhiteScanlines = 2, + vcmpPlayerOptionGreenScanlines = 3, + vcmpPlayerOptionWidescreen = 4, + vcmpPlayerOptionShowMarkers = 5, + vcmpPlayerOptionCanAttack = 6, + vcmpPlayerOptionHasMarker = 7, + vcmpPlayerOptionChatTagsEnabled = 8, + vcmpPlayerOptionDrunkEffects = 9, + forceSizeVcmpPlayerOption = INT32_MAX +} vcmpPlayerOption; + +typedef enum { + vcmpVehicleOptionDoorsLocked = 0, + vcmpVehicleOptionAlarm = 1, + vcmpVehicleOptionLights = 2, + vcmpVehicleOptionRadioLocked = 3, + vcmpVehicleOptionGhost = 4, + vcmpVehicleOptionSiren = 5, + forceSizeVcmpVehicleOption = INT32_MAX +} vcmpVehicleOption; typedef struct { - unsigned int uStructSize; + uint32_t structSize; - //PLUGIN SYSTEM - SDK_GetServerVersion GetServerVersion; - SDK_GetServerSettings GetServerSettings; - SDK_ExportFunctions ExportFunctions; - SDK_GetNumberOfPlugins GetNumberOfPlugins; - SDK_GetPluginInfo GetPluginInfo; - SDK_FindPlugin FindPlugin; - SDK_GetPluginExports GetPluginExports; - SDK_GetTime GetTime; + /** + * Plugin system + */ - //MESSAGES - SDK_printf printf; - SDK_SendCustomCommand SendCustomCommand; - SDK_SendClientMessage SendClientMessage; - SDK_SendGameMessage SendGameMessage; + /* success */ + uint32_t (*GetServerVersion) (void); + /* vcmpErrorNullArgument */ + vcmpError (*GetServerSettings) (ServerSettings* settings); + /* vcmpErrorNoSuchEntity */ + vcmpError (*ExportFunctions) (int32_t pluginId, const void** functionList, size_t size); + /* success */ + uint32_t (*GetNumberOfPlugins) (void); + /* vcmpErrorNoSuchEntity, vcmpErrorNullArgument */ + vcmpError (*GetPluginInfo) (int32_t pluginId, PluginInfo* pluginInfo); + /* -1 == vcmpEntityNone */ + int32_t (*FindPlugin) (const char* pluginName); + /* GetLastError: vcmpErrorNoSuchEntity */ + const void** (*GetPluginExports) (int32_t pluginId, size_t* exportCount); + /* vcmpErrorNullArgument, vcmpErrorTooLargeInput */ + vcmpError (*SendPluginCommand) (uint32_t commandIdentifier, const char* format, ...); + /* success */ + uint64_t (*GetTime) (void); + /* vcmpErrorNullArgument, vcmpErrorTooLargeInput */ + vcmpError (*LogMessage) (const char* format, ...); + /* success */ + vcmpError (*GetLastError) (void); - //SERVER SETTINGS - SDK_SetServerName SetServerName; - SDK_GetServerName GetServerName; - SDK_SetMaxPlayers SetMaxPlayers; - SDK_GetMaxPlayers GetMaxPlayers; - SDK_SetServerPassword SetServerPassword; - SDK_GetServerPassword GetServerPassword; - SDK_SetGameModeText SetGameModeText; - SDK_GetGameModeText GetGameModeText; - SDK_ShutdownServer ShutdownServer; + /** + * Client messages + */ - //WORLD: settings - SDK_SetWorldBounds SetWorldBounds; - SDK_GetWorldBounds GetWorldBounds; - SDK_SetWastedSettings SetWastedSettings; - SDK_GetWastedSettings GetWastedSettings; - SDK_SetTimeRate SetTimeRate; - SDK_GetTimeRate GetTimeRate; - SDK_SetHour SetHour; - SDK_GetHour GetHour; - SDK_SetMinute SetMinute; - SDK_GetMinute GetMinute; - SDK_SetWeather SetWeather; - SDK_GetWeather GetWeather; - SDK_SetGravity SetGravity; - SDK_GetGravity GetGravity; - SDK_SetGamespeed SetGamespeed; - SDK_GetGamespeed GetGamespeed; - SDK_SetWaterLevel SetWaterLevel; - SDK_GetWaterLevel GetWaterLevel; - SDK_SetMaxHeight SetMaxHeight; - SDK_GetMaxHeight GetMaxHeight; - SDK_SetKillCmdDelay SetKillCmdDelay; - SDK_GetKillCmdDelay GetKillCmdDelay; - SDK_SetVehiclesForcedRespawnHeight SetVehiclesForcedRespawnHeight; - SDK_GetVehiclesForcedRespawnHeight GetVehiclesForcedRespawnHeight; + /* vcmpErrorNoSuchEntity, vcmpErrorNullArgument, vcmpErrorTooLargeInput */ + vcmpError (*SendClientScriptData) (int32_t playerId, const void* data, size_t size); + /* vcmpErrorNoSuchEntity, vcmpErrorNullArgument, vcmpErrorTooLargeInput */ + vcmpError (*SendClientMessage) (int32_t playerId, uint32_t colour, const char* format, ...); + /* vcmpErrorNoSuchEntity, vcmpErrorArgumentOutOfBounds, vcmpErrorNullArgument, vcmpErrorTooLargeInput */ + vcmpError (*SendGameMessage) (int32_t playerId, int32_t type, const char* format, ...); - //WORLD: toggles - SDK_ToggleSyncFrameLimiter ToggleSyncFrameLimiter; - SDK_EnabledSyncFrameLimiter EnabledSyncFrameLimiter; - SDK_ToggleFrameLimiter ToggleFrameLimiter; - SDK_EnabledFrameLimiter EnabledFrameLimiter; - SDK_ToggleTaxiBoostJump ToggleTaxiBoostJump; - SDK_EnabledTaxiBoostJump EnabledTaxiBoostJump; - SDK_ToggleDriveOnWater ToggleDriveOnWater; - SDK_EnabledDriveOnWater EnabledDriveOnWater; - SDK_ToggleFastSwitch ToggleFastSwitch; - SDK_EnabledFastSwitch EnabledFastSwitch; - SDK_ToggleFriendlyFire ToggleFriendlyFire; - SDK_EnabledFriendlyFire EnabledFriendlyFire; - SDK_ToggleDisableDriveby ToggleDisableDriveby; - SDK_EnabledDisableDriveby EnabledDisableDriveby; - SDK_TogglePerfectHandling TogglePerfectHandling; - SDK_EnabledPerfectHandling EnabledPerfectHandling; - SDK_ToggleFlyingCars ToggleFlyingCars; - SDK_EnabledFlyingCars EnabledFlyingCars; - SDK_ToggleJumpSwitch ToggleJumpSwitch; - SDK_EnabledJumpSwitch EnabledJumpSwitch; - SDK_ToggleShowMarkers ToggleShowMarkers; - SDK_EnabledShowMarkers EnabledShowMarkers; - SDK_ToggleOnlyShowTeamMarkers ToggleOnlyShowTeamMarkers; - SDK_EnabledOnlyShowTeamMarkers EnabledOnlyShowTeamMarkers; - SDK_ToggleStuntBike ToggleStuntBike; - SDK_EnabledStuntBike EnabledStuntBike; - SDK_ToggleShootInAir ToggleShootInAir; - SDK_EnabledShootInAir EnabledShootInAir; - SDK_ToggleShowNametags ToggleShowNametags; - SDK_EnabledShowNametags EnabledShowNametags; - SDK_ToggleJoinMessages ToggleJoinMessages; - SDK_EnabledJoinMessages EnabledJoinMessages; - SDK_ToggleDeathMessages ToggleDeathMessages; - SDK_EnabledDeathMessages EnabledDeathMessages; - SDK_ToggleChatTagsByDefaultEnabled ToggleChatTagsByDefaultEnabled; - SDK_EnabledChatTagsByDefault EnabledChatTagsByDefault; + /* + * Server settings + */ - //MISC - SDK_CreateExplosion CreateExplosion; - SDK_PlaySound PlaySound; - SDK_HideMapObject HideMapObject; - SDK_ShowMapObject ShowMapObject; - SDK_ShowAllMapObjects ShowAllMapObjects; + /* vcmpErrorNullArgument, vcmpErrorTooLargeInput */ + vcmpError (*SetServerName) (const char* text); + /* vcmpErrorNullArgument, vcmpErrorBufferTooSmall */ + vcmpError (*GetServerName) (char* buffer, size_t size); + /* vcmpErrorArgumentOutOfBounds */ + vcmpError (*SetMaxPlayers) (uint32_t maxPlayers); + /* success */ + uint32_t (*GetMaxPlayers) (void); + /* vcmpErrorNullArgument, vcmpErrorTooLargeInput */ + vcmpError (*SetServerPassword) (const char* password); + /* vcmpErrorNullArgument, vcmpErrorBufferTooSmall */ + vcmpError (*GetServerPassword) (char* buffer, size_t size); + /* vcmpErrorNullArgument, vcmpErrorTooLargeInput */ + vcmpError (*SetGameModeText) (const char* gameMode); + /* vcmpErrorNullArgument, vcmpErrorBufferTooSmall */ + vcmpError (*GetGameModeText) (char* buffer, size_t size); + /* success */ + void (*ShutdownServer) (void); - //WEAPONDATA - SDK_SetWeaponDataValue SetWeaponDataValue; - SDK_GetWeaponDataValue GetWeaponDataValue; - SDK_ResetWeaponDataValue ResetWeaponDataValue; - SDK_IsWeaponDataValueModified IsWeaponDataValueModified; - SDK_ResetWeaponData ResetWeaponData; - SDK_ResetAllWeaponData ResetAllWeaponData; + /* + * Game environment settings + */ - //KEYBINDS - SDK_GetKeyBindUnusedSlot GetKeyBindUnusedSlot; - SDK_GetKeyBindData GetKeyBindData; - SDK_RegisterKeyBind RegisterKeyBind; - SDK_RemoveKeyBind RemoveKeyBind; - SDK_RemoveAllKeyBinds RemoveAllKeyBinds; + /* vcmpErrorArgumentOutOfBounds */ + vcmpError (*SetServerOption) (vcmpServerOption option, uint8_t toggle); + /* GetLastError: vcmpErrorArgumentOutOfBounds */ + uint8_t (*GetServerOption) (vcmpServerOption option); + /* success */ + void (*SetWorldBounds) (float maxX, float minX, float maxY, float minY); + /* success */ + void (*GetWorldBounds) (float* maxXOut, float* minXOut, float* maxYOut, float* minYOut); + /* success */ + void (*SetWastedSettings) (uint32_t deathTimer, uint32_t fadeTimer, float fadeInSpeed, float fadeOutSpeed, uint32_t fadeColour, uint32_t corpseFadeStart, uint32_t corpseFadeTime); + /* success */ + void (*GetWastedSettings) (uint32_t* deathTimerOut, uint32_t* fadeTimerOut, float* fadeInSpeedOut, float* fadeOutSpeedOut, uint32_t* fadeColourOut, uint32_t* corpseFadeStartOut, uint32_t* corpseFadeTimeOut); + /* success */ + void (*SetTimeRate) (int32_t timeRate); + /* success */ + int32_t (*GetTimeRate) (void); + /* success */ + void (*SetHour) (int32_t hour); + /* success */ + int32_t (*GetHour) (void); + /* success */ + void (*SetMinute) (int32_t minute); + /* success */ + int32_t (*GetMinute) (void); + /* success */ + void (*SetWeather) (int32_t weather); + /* success */ + int32_t (*GetWeather) (void); + /* success */ + void (*SetGravity) (float gravity); + /* success */ + float (*GetGravity) (void); + /* success */ + void (*SetGameSpeed) (float gameSpeed); + /* success */ + float (*GetGameSpeed) (void); + /* success */ + void (*SetWaterLevel) (float waterLevel); + /* success */ + float (*GetWaterLevel) (void); + /* success */ + void (*SetMaximumFlightAltitude) (float height); + /* success */ + float (*GetMaximumFlightAltitude) (void); + /* success */ + void (*SetKillCommandDelay) (int32_t delay); + /* success */ + int32_t (*GetKillCommandDelay) (void); + /* success */ + void (*SetVehiclesForcedRespawnHeight) (float height); + /* success */ + float (*GetVehiclesForcedRespawnHeight) (void); - //BLIPS - SDK_CreateCoordBlip CreateCoordBlip; - SDK_DestroyCoordBlip DestroyCoordBlip; - SDK_GetCoordBlipInfo GetCoordBlipInfo; + /* + * Miscellaneous things + */ - //SPRITES - SDK_CreateSprite CreateSprite; - SDK_DestroySprite DestroySprite; - SDK_ShowSprite ShowSprite; - SDK_HideSprite HideSprite; - SDK_MoveSprite MoveSprite; - SDK_SetSpriteCenter SetSpriteCenter; - SDK_RotateSprite RotateSprite; - SDK_SetSpriteAlpha SetSpriteAlpha; - SDK_SetSpriteRelativity SetSpriteRelativity; + /* vcmpErrorArgumentOutOfBounds, vcmpErrorNoSuchEntity */ + vcmpError (*CreateExplosion) (int32_t worldId, int32_t type, float x, float y, float z, int32_t responsiblePlayerId, uint8_t atGroundLevel); + /* vcmpErrorArgumentOutOfBounds */ + vcmpError (*PlaySound) (int32_t worldId, int32_t soundId, float x, float y, float z); + /* success */ + void (*HideMapObject) (int32_t modelId, int16_t tenthX, int16_t tenthY, int16_t tenthZ); + /* success */ + void (*ShowMapObject) (int32_t modelId, int16_t tenthX, int16_t tenthY, int16_t tenthZ); + /* success */ + void (*ShowAllMapObjects) (void); - //TEXTDRAWS - SDK_CreateTextdraw CreateTextdraw; - SDK_DestroyTextdraw DestroyTextdraw; - SDK_ShowTextdraw ShowTextdraw; - SDK_HideTextdraw HideTextdraw; - SDK_MoveTextdraw MoveTextdraw; - SDK_SetTextdrawColour SetTextdrawColour; - SDK_SetTextdrawRelativity SetTextdrawRelativity; + /* + * Weapon settings + */ - //RADIOS - SDK_AddRadioStream AddRadioStream; - SDK_RemoveRadioStream RemoveRadioStream; + /* vcmpErrorArgumentOutOfBounds */ + vcmpError (*SetWeaponDataValue) (int32_t weaponId, int32_t fieldId, double value); + /* GetLastError: vcmpErrorArgumentOutOfBounds */ + double (*GetWeaponDataValue) (int32_t weaponId, int32_t fieldId); + /* vcmpErrorArgumentOutOfBounds */ + vcmpError (*ResetWeaponDataValue) (int32_t weaponId, int32_t fieldId); + /* GetLastError: vcmpErrorArgumentOutOfBounds */ + uint8_t (*IsWeaponDataValueModified) (int32_t weaponId, int32_t fieldId); + /* vcmpErrorArgumentOutOfBounds */ + vcmpError (*ResetWeaponData) (int32_t weaponId); + /* success */ + void (*ResetAllWeaponData) (void); - //CLASSES - SDK_SetUseClasses SetUseClasses; - SDK_GetUseClasses GetUseClasses; - SDK_GetPlayerClass GetPlayerClass; - SDK_AddPlayerClass AddPlayerClass; - SDK_SetSpawnPlayerPos SetSpawnPlayerPos; - SDK_SetSpawnCameraPos SetSpawnCameraPos; - SDK_SetSpawnCameraLookAt SetSpawnCameraLookAt; + /* + * Key binds + */ - //ADMIN - SDK_IsPlayerAdmin IsPlayerAdmin; - SDK_SetPlayerAdmin SetPlayerAdmin; - SDK_GetPlayerIP GetPlayerIP; - SDK_KickPlayer KickPlayer; - SDK_BanPlayer BanPlayer; - SDK_BanIP BanIP; - SDK_UnbanIP UnbanIP; - SDK_IsIPBanned IsIPBanned; + /* -1 == vcmpEntityNone */ + int32_t (*GetKeyBindUnusedSlot) (void); + /* vcmpErrorNoSuchEntity */ + vcmpError (*GetKeyBindData) (int32_t bindId, uint8_t* isCalledOnReleaseOut, int32_t* keyOneOut, int32_t* keyTwoOut, int32_t* keyThreeOut); + /* vcmpErrorArgumentOutOfBounds */ + vcmpError (*RegisterKeyBind) (int32_t bindId, uint8_t isCalledOnRelease, int32_t keyOne, int32_t keyTwo, int32_t keyThree); + /* vcmpErrorNoSuchEntity */ + vcmpError (*RemoveKeyBind) (int32_t bindId); + /* success */ + void (*RemoveAllKeyBinds) (void); - //PLAYERS: basic - SDK_GetPlayerIDFromName GetPlayerIDFromName; - SDK_IsPlayerConnected IsPlayerConnected; - SDK_IsPlayerSpawned IsPlayerSpawned; - SDK_IsPlayerStreamedForPlayer IsPlayerStreamedForPlayer; - SDK_GetPlayerKey GetPlayerKey; - SDK_SetPlayerWorld SetPlayerWorld; - SDK_GetPlayerWorld GetPlayerWorld; - SDK_SetPlayerSecWorld SetPlayerSecWorld; - SDK_GetPlayerSecWorld GetPlayerSecWorld; - SDK_GetPlayerUniqueWorld GetPlayerUniqueWorld; - SDK_IsPlayerWorldCompatible IsPlayerWorldCompatible; - SDK_GetPlayerState GetPlayerState; - SDK_GetPlayerName GetPlayerName; - SDK_SetPlayerName SetPlayerName; - SDK_SetPlayerTeam SetPlayerTeam; - SDK_GetPlayerTeam GetPlayerTeam; - SDK_SetPlayerSkin SetPlayerSkin; - SDK_GetPlayerSkin GetPlayerSkin; - SDK_SetPlayerColour SetPlayerColour; - SDK_GetPlayerColour GetPlayerColour; - SDK_ForcePlayerSpawn ForcePlayerSpawn; - SDK_ForcePlayerSelect ForcePlayerSelect; - SDK_ForceAllSelect ForceAllSelect; + /* + * Coordinate blips + */ - //PLAYERS: score, ping, money, typing - SDK_GivePlayerMoney GivePlayerMoney; - SDK_SetPlayerMoney SetPlayerMoney; - SDK_GetPlayerMoney GetPlayerMoney; - SDK_SetPlayerScore SetPlayerScore; - SDK_GetPlayerScore GetPlayerScore; - SDK_GetPlayerPing GetPlayerPing; - SDK_IsPlayerTyping IsPlayerTyping; - SDK_GetPlayerFPS GetPlayerFPS; - SDK_GetPlayerUID GetPlayerUID; - SDK_GetPlayerWantedLevel GetPlayerWantedLevel; + /* GetLastError: vcmpErrorPoolExhausted */ + int32_t (*CreateCoordBlip) (int32_t index, int32_t world, float x, float y, float z, int32_t scale, uint32_t colour, int32_t sprite); + /* vcmpErrorNoSuchEntity */ + vcmpError (*DestroyCoordBlip) (int32_t index); + /* vcmpErrorNoSuchEntity */ + vcmpError (*GetCoordBlipInfo) (int32_t index, int32_t* worldOut, float* xOut, float* yOUt, float* zOut, int32_t* scaleOut, uint32_t* colourOut, int32_t* spriteOut); - //PLAYERS: health and location - SDK_SetPlayerHealth SetPlayerHealth; - SDK_GetPlayerHealth GetPlayerHealth; - SDK_SetPlayerArmour SetPlayerArmour; - SDK_GetPlayerArmour GetPlayerArmour; - SDK_SetPlayerImmunityFlags SetPlayerImmunityFlags; - SDK_GetPlayerImmunityFlags GetPlayerImmunityFlags; - SDK_SetPlayerPos SetPlayerPos; - SDK_GetPlayerPos GetPlayerPos; - SDK_SetPlayerSpeed SetPlayerSpeed; - SDK_GetPlayerSpeed GetPlayerSpeed; - SDK_AddPlayerSpeed AddPlayerSpeed; - SDK_SetPlayerHeading SetPlayerHeading; - SDK_GetPlayerHeading GetPlayerHeading; - SDK_SetPlayerAlpha SetPlayerAlpha; - SDK_GetPlayerAlpha GetPlayerAlpha; - SDK_GetPlayerOnFireStatus GetPlayerOnFireStatus; - SDK_GetPlayerCrouchStatus GetPlayerCrouchStatus; - SDK_GetPlayerAction GetPlayerAction; - SDK_GetPlayerGameKeys GetPlayerGameKeys; - SDK_GetPlayerAimPos GetPlayerAimPos; - SDK_GetPlayerAimDir GetPlayerAimDir; + /* + * Radios + */ - //PLAYERS: vehicle - SDK_PutPlayerInVehicle PutPlayerInVehicle; - SDK_RemovePlayerFromVehicle RemovePlayerFromVehicle; - SDK_GetPlayerInVehicleStatus GetPlayerInVehicleStatus; - SDK_GetPlayerInVehicleSlot GetPlayerInVehicleSlot; - SDK_GetPlayerVehicleID GetPlayerVehicleID; + /* vcmpErrorArgumentOutOfBounds, vcmpErrorNullArgument */ + vcmpError (*AddRadioStream) (int32_t radioId, const char* radioName, const char* radioUrl, uint8_t isListed); + /* vcmpErrorNoSuchEntity */ + vcmpError (*RemoveRadioStream) (int32_t radioId); - //PLAYERS: toggles - SDK_TogglePlayerControllable TogglePlayerControllable; - SDK_EnabledPlayerControllable EnabledPlayerControllable; - SDK_TogglePlayerDriveby TogglePlayerDriveby; - SDK_EnabledPlayerDriveby EnabledPlayerDriveby; - SDK_TogglePlayerWhiteScanlines TogglePlayerWhiteScanlines; - SDK_EnabledPlayerWhiteScanlines EnabledPlayerWhiteScanlines; - SDK_TogglePlayerGreenScanlines TogglePlayerGreenScanlines; - SDK_EnabledPlayerGreenScanlines EnabledPlayerGreenScanlines; - SDK_TogglePlayerWidescreen TogglePlayerWidescreen; - SDK_EnabledPlayerWidescreen EnabledPlayerWidescreen; - SDK_TogglePlayerShowMarkers TogglePlayerShowMarkers; - SDK_EnabledPlayerShowMarkers EnabledPlayerShowMarkers; - SDK_TogglePlayerAttackPriv TogglePlayerAttackPriv; - SDK_EnabledPlayerAttackPriv EnabledPlayerAttackPriv; - SDK_TogglePlayerHasMarker TogglePlayerHasMarker; - SDK_EnabledPlayerHasMarker EnabledPlayerHasMarker; - SDK_TogglePlayerChatTagsEnabled TogglePlayerChatTagsEnabled; - SDK_EnabledPlayerChatTags EnabledPlayerChatTags; - SDK_TogglePlayerDrunkEffects TogglePlayerDrunkEffects; - SDK_EnabledPlayerDrunkEffects EnabledPlayerDrunkEffects; + /* + * Spawning and classes + */ - //PLAYERS: weapons - SDK_GivePlayerWeapon GivePlayerWeapon; - SDK_SetPlayerWeapon SetPlayerWeapon; - SDK_GetPlayerWeapon GetPlayerWeapon; - SDK_GetPlayerWeaponAmmo GetPlayerWeaponAmmo; - SDK_SetPlayerWeaponSlot SetPlayerWeaponSlot; - SDK_GetPlayerWeaponSlot GetPlayerWeaponSlot; - SDK_GetPlayerWeaponAtSlot GetPlayerWeaponAtSlot; - SDK_GetPlayerAmmoAtSlot GetPlayerAmmoAtSlot; - SDK_RemovePlayerWeapon RemovePlayerWeapon; - SDK_RemoveAllWeapons RemoveAllWeapons; + /* GetLastError: vcmpErrorArgumentOutOfBounds, vcmpErrorPoolExhausted */ + int32_t (*AddPlayerClass) (int32_t teamId, uint32_t colour, int32_t modelIndex, float x, float y, float z, float angle, int32_t weaponOne, int32_t weaponOneAmmo, int32_t weaponTwo, int32_t weaponTwoAmmo, int32_t weaponThree, int32_t weaponThreeAmmo); + /* success */ + void (*SetSpawnPlayerPosition) (float x, float y, float z); + /* success */ + void (*SetSpawnCameraPosition) (float x, float y, float z); + /* success */ + void (*SetSpawnCameraLookAt) (float x, float y, float z); - //PLAYERS: camera - SDK_SetCameraPosition SetCameraPosition; - SDK_RestoreCamera RestoreCamera; - SDK_IsCameraLocked IsCameraLocked; + /* + * Administration + */ + + /* GetLastError: vcmpErrorNoSuchEntity */ + uint8_t (*IsPlayerAdmin) (int32_t playerId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPlayerAdmin) (int32_t playerId, uint8_t toggle); + /* vcmpErrorNoSuchEntity, vcmpErrorNullArgument, vcmpErrorBufferTooSmall */ + vcmpError (*GetPlayerIP) (int32_t playerId, char* buffer, size_t size); + /* vcmpErrorNoSuchEntity, vcmpErrorNullArgument, vcmpErrorBufferTooSmall */ + vcmpError (*GetPlayerUID) (int32_t playerId, char* buffer, size_t size); + /* vcmpErrorNoSuchEntity, vcmpErrorNullArgument, vcmpErrorBufferTooSmall */ + vcmpError (*GetPlayerUID2) (int32_t playerId, char* buffer, size_t size); + /* vcmpErrorNoSuchEntity */ + vcmpError (*KickPlayer) (int32_t playerId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*BanPlayer) (int32_t playerId); + /* success */ + void (*BanIP) (char* ipAddress); + /* success */ + uint8_t (*UnbanIP) (char* ipAddress); + /* success */ + uint8_t (*IsIPBanned) (char* ipAddress); - //PLAYERS: misc - SDK_SetPlayerAnimation SetPlayerAnimation; - SDK_SetPlayerWantedLevel SetPlayerWantedLevel; - SDK_GetPlayerStandingOnVehicle GetPlayerStandingOnVehicle; - SDK_GetPlayerStandingOnObject GetPlayerStandingOnObject; - SDK_IsPlayerAway IsPlayerAway; - SDK_GetPlayerSpectateTarget GetPlayerSpectateTarget; - SDK_SetPlayerSpectateTarget SetPlayerSpectateTarget; - SDK_RedirectPlayerToServer RedirectPlayerToServer; + /* + * Player access and basic info + */ - //VEHICLES - SDK_CreateVehicle CreateVehicle; - SDK_DeleteVehicle DeleteVehicle; - SDK_GetVehicleSyncSource GetVehicleSyncSource; - SDK_GetVehicleSyncType GetVehicleSyncType; - SDK_IsVehicleStreamedForPlayer IsVehicleStreamedForPlayer; - SDK_SetVehicleWorld SetVehicleWorld; - SDK_GetVehicleWorld GetVehicleWorld; - SDK_GetVehicleModel GetVehicleModel; - SDK_GetVehicleOccupant GetVehicleOccupant; - SDK_RespawnVehicle RespawnVehicle; - SDK_SetVehicleImmunityFlags SetVehicleImmunityFlags; - SDK_GetVehicleImmunityFlags GetVehicleImmunityFlags; - SDK_KillVehicle KillVehicle; - SDK_IsVehicleWrecked IsVehicleWrecked; - SDK_SetVehiclePos SetVehiclePos; - SDK_GetVehiclePos GetVehiclePos; - SDK_SetVehicleRot SetVehicleRot; - SDK_SetVehicleRotEuler SetVehicleRotEuler; - SDK_GetVehicleRot GetVehicleRot; - SDK_GetVehicleRotEuler GetVehicleRotEuler; - SDK_SetVehicleSpeed SetVehicleSpeed; - SDK_GetVehicleSpeed GetVehicleSpeed; - SDK_AddVehicleSpeed AddVehicleSpeed; - SDK_SetVehicleRelSpeed SetVehicleRelSpeed; - SDK_GetVehicleRelSpeed GetVehicleRelSpeed; - SDK_AddVehicleRelSpeed AddVehicleRelSpeed; - SDK_SetVehicleTurnSpeed SetVehicleTurnSpeed; - SDK_GetVehicleTurnSpeed GetVehicleTurnSpeed; - SDK_AddVehicleTurnSpeed AddVehicleTurnSpeed; - SDK_SetVehicleRelTurnSpeed SetVehicleRelTurnSpeed; - SDK_GetVehicleRelTurnSpeed GetVehicleRelTurnSpeed; - SDK_AddVehicleRelTurnSpeed AddVehicleRelTurnSpeed; - SDK_SetVehicleSpawnPos SetVehicleSpawnPos; - SDK_GetVehicleSpawnPos GetVehicleSpawnPos; - SDK_SetVehicleSpawnRot SetVehicleSpawnRot; - SDK_SetVehicleSpawnRotEuler SetVehicleSpawnRotEuler; - SDK_GetVehicleSpawnRot GetVehicleSpawnRot; - SDK_GetVehicleSpawnRotEuler GetVehicleSpawnRotEuler; - SDK_SetVehicleIdleRespawnTimer SetVehicleIdleRespawnTimer; - SDK_GetVehicleIdleRespawnTimer GetVehicleIdleRespawnTimer; - SDK_SetVehicleHealth SetVehicleHealth; - SDK_GetVehicleHealth GetVehicleHealth; - SDK_SetVehicleColour SetVehicleColour; - SDK_GetVehicleColour GetVehicleColour; - SDK_SetVehicleDoorsLocked SetVehicleDoorsLocked; - SDK_GetVehicleDoorsLocked GetVehicleDoorsLocked; - SDK_SetVehiclePartStatus SetVehiclePartStatus; - SDK_GetVehiclePartStatus GetVehiclePartStatus; - SDK_SetVehicleTyreStatus SetVehicleTyreStatus; - SDK_GetVehicleTyreStatus GetVehicleTyreStatus; - SDK_SetVehicleDamageData SetVehicleDamageData; - SDK_GetVehicleDamageData GetVehicleDamageData; - SDK_SetVehicleAlarm SetVehicleAlarm; - SDK_GetVehicleAlarm GetVehicleAlarm; - SDK_SetVehicleLights SetVehicleLights; - SDK_GetVehicleLights GetVehicleLights; - SDK_SetVehicleRadio SetVehicleRadio; - SDK_GetVehicleRadio GetVehicleRadio; - SDK_SetVehicleRadioLocked SetVehicleRadioLocked; - SDK_IsVehicleRadioLocked IsVehicleRadioLocked; - SDK_GetVehicleGhostState GetVehicleGhostState; - SDK_SetVehicleGhostState SetVehicleGhostState; - SDK_GetVehicleTurretRotation GetVehicleTurretRotation; + /* -1 == vcmpEntityNone */ + int32_t (*GetPlayerIdFromName) (const char* name); + /* success */ + uint8_t (*IsPlayerConnected) (int32_t playerId); + /* vcmpErrorNoSuchEntity */ + uint8_t (*IsPlayerStreamedForPlayer) (int32_t checkedPlayerId, int32_t playerId); + /* vcmpErrorNoSuchEntity */ + uint32_t (*GetPlayerKey) (int32_t playerId); + /* vcmpErrorNoSuchEntity, vcmpErrorNullArgument, vcmpErrorBufferTooSmall */ + vcmpError (*GetPlayerName) (int32_t playerId, char* buffer, size_t size); + /* vcmpErrorNoSuchEntity, vcmpErrorNullArgument, vcmpErrorInvalidName, vcmpErrorTooLargeInput */ + vcmpError (*SetPlayerName) (int32_t playerId, const char* name); + /* GetLastError: vcmpErrorNoSuchEntity */ + vcmpPlayerState (*GetPlayerState) (int32_t playerId); + /* vcmpErrorNoSuchEntity, vcmpErrorArgumentOutOfBounds */ + vcmpError (*SetPlayerOption) (int32_t playerId, vcmpPlayerOption option, uint8_t toggle); + /* GetLastError: vcmpErrorNoSuchEntity, vcmpErrorArgumentOutOfBounds */ + uint8_t (*GetPlayerOption) (int32_t playerId, vcmpPlayerOption option); - //VEHICLES: handling - SDK_ResetAllVehicleHandlings ResetAllVehicleHandlings; - SDK_ExistsHandlingRule ExistsHandlingRule; - SDK_SetHandlingRule SetHandlingRule; - SDK_GetHandlingRule GetHandlingRule; - SDK_ResetHandlingRule ResetHandlingRule; - SDK_ResetHandling ResetHandling; - SDK_ExistsInstHandlingRule ExistsInstHandlingRule; - SDK_SetInstHandlingRule SetInstHandlingRule; - SDK_GetInstHandlingRule GetInstHandlingRule; - SDK_ResetInstHandlingRule ResetInstHandlingRule; - SDK_ResetInstHandling ResetInstHandling; + /* + * Player world + */ - //PICKUPS - SDK_CreatePickup CreatePickup; - SDK_DeletePickup DeletePickup; - SDK_IsPickupStreamedForPlayer IsPickupStreamedForPlayer; - SDK_SetPickupWorld SetPickupWorld; - SDK_GetPickupWorld GetPickupWorld; - SDK_PickupGetAlpha PickupGetAlpha; - SDK_PickupSetAlpha PickupSetAlpha; - SDK_PickupIsAutomatic PickupIsAutomatic; - SDK_PickupSetAutomatic PickupSetAutomatic; - SDK_SetPickupAutoTimer SetPickupAutoTimer; - SDK_GetPickupAutoTimer GetPickupAutoTimer; - SDK_PickupRefresh PickupRefresh; - SDK_PickupGetPos PickupGetPos; - SDK_PickupSetPos PickupSetPos; - SDK_PickupGetModel PickupGetModel; - SDK_PickupGetQuantity PickupGetQuantity; + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPlayerWorld) (int32_t playerId, int32_t world); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPlayerWorld) (int32_t playerId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPlayerSecondaryWorld) (int32_t playerId, int32_t secondaryWorld); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPlayerSecondaryWorld) (int32_t playerId); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPlayerUniqueWorld) (int32_t playerId); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint8_t (*IsPlayerWorldCompatible) (int32_t playerId, int32_t world); - //OBJECTS - SDK_CreateObject CreateObject; - SDK_DeleteObject DeleteObject; - SDK_IsObjectStreamedForPlayer IsObjectStreamedForPlayer; - SDK_GetObjectModel GetObjectModel; - SDK_SetObjectWorld SetObjectWorld; - SDK_GetObjectWorld GetObjectWorld; - SDK_SetObjectAlpha SetObjectAlpha; - SDK_GetObjectAlpha GetObjectAlpha; - SDK_MoveObjectTo MoveObjectTo; - SDK_MoveObjectBy MoveObjectBy; - SDK_SetObjectPos SetObjectPos; - SDK_GetObjectPos GetObjectPos; - SDK_RotObjectTo RotObjectTo; - SDK_RotObjectToEuler RotObjectToEuler; - SDK_RotObjectBy RotObjectBy; - SDK_RotObjectByEuler RotObjectByEuler; - SDK_GetObjectRot GetObjectRot; - SDK_GetObjectRotEuler GetObjectRotEuler; - SDK_SetObjectShotReport SetObjectShotReport; - SDK_IsObjectShotReport IsObjectShotReport; - SDK_SetObjectBumpReport SetObjectBumpReport; - SDK_IsObjectBumpReport IsObjectBumpReport; + /* + * Player class, team, skin, colour + */ - // TODO: Move these functions to proper sections on major plugin update - SDK_ToggleWallglitch ToggleWallglitch; - SDK_EnabledWallglitch EnabledWallglitch; - SDK_SetVehicleSiren SetVehicleSiren; - SDK_GetVehicleSiren GetVehicleSiren; - SDK_GetPlayerUID2 GetPlayerUID2; + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPlayerClass) (int32_t playerId); + /* vcmpErrorNoSuchEntity, vcmpErrorArgumentOutOfBounds */ + vcmpError (*SetPlayerTeam) (int32_t playerId, int32_t teamId); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPlayerTeam) (int32_t playerId); + /* vcmpErrorNoSuchEntity, vcmpErrorArgumentOutOfBounds */ + vcmpError (*SetPlayerSkin) (int32_t playerId, int32_t skinId); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPlayerSkin) (int32_t playerId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPlayerColour) (int32_t playerId, uint32_t colour); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint32_t (*GetPlayerColour) (int32_t playerId); - SDK_CreateCheckpoint CreateCheckpoint; - SDK_DeleteCheckpoint DeleteCheckpoint; - SDK_IsCheckpointStreamedForPlayer IsCheckpointStreamedForPlayer; - SDK_SetCheckpointWorld SetCheckpointWorld; - SDK_GetCheckpointWorld GetCheckpointWorld; - SDK_SetCheckpointColor SetCheckpointColor; - SDK_GetCheckpointColor GetCheckpointColor; - SDK_SetCheckpointPos SetCheckpointPos; - SDK_GetCheckpointPos GetCheckpointPos; - SDK_SetCheckpointRadius SetCheckpointRadius; - SDK_GetCheckpointRadius GetCheckpointRadius; - SDK_GetCheckpointOwner GetCheckpointOwner; + /* + * Player spawn cycle + */ + + /* vcmpErrorNoSuchEntity */ + uint8_t (*IsPlayerSpawned) (int32_t playerId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*ForcePlayerSpawn) (int32_t playerId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*ForcePlayerSelect) (int32_t playerId); + /* success */ + void (*ForceAllSelect) (void); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint8_t (*IsPlayerTyping) (int32_t playerId); + + /* + * Player money, score, wanted level + */ + + /* vcmpErrorNoSuchEntity */ + vcmpError (*GivePlayerMoney) (int32_t playerId, int32_t amount); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPlayerMoney) (int32_t playerId, int32_t amount); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPlayerMoney) (int32_t playerId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPlayerScore) (int32_t playerId, int32_t score); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPlayerScore) (int32_t playerId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPlayerWantedLevel) (int32_t playerId, int32_t level); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPlayerWantedLevel) (int32_t playerId); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPlayerPing) (int32_t playerId); + /* GetLastError: vcmpErrorNoSuchEntity */ + double (*GetPlayerFPS) (int32_t playerId); + + /* + * Player health and immunity + */ + + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPlayerHealth) (int32_t playerId, float health); + /* GetLastError: vcmpErrorNoSuchEntity */ + float (*GetPlayerHealth) (int32_t playerId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPlayerArmour) (int32_t playerId, float armour); + /* GetLastError: vcmpErrorNoSuchEntity */ + float (*GetPlayerArmour) (int32_t playerId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPlayerImmunityFlags) (int32_t playerId, uint32_t flags); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint32_t (*GetPlayerImmunityFlags) (int32_t playerId); + + /* + * Player position and rotation + */ + + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPlayerPosition) (int32_t playerId, float x, float y, float z); + /* vcmpErrorNoSuchEntity */ + vcmpError (*GetPlayerPosition) (int32_t playerId, float* xOut, float* yOut, float* zOut); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPlayerSpeed) (int32_t playerId, float x, float y, float z); + /* vcmpErrorNoSuchEntity */ + vcmpError (*GetPlayerSpeed) (int32_t playerId, float* xOut, float* yOut, float* zOut); + /* vcmpErrorNoSuchEntity */ + vcmpError (*AddPlayerSpeed) (int32_t playerId, float x, float y, float z); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPlayerHeading) (int32_t playerId, float angle); + /* GetLastError: vcmpErrorNoSuchEntity */ + float (*GetPlayerHeading) (int32_t playerId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPlayerAlpha) (int32_t playerId, int32_t alpha, uint32_t fadeTime); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPlayerAlpha) (int32_t playerId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*GetPlayerAimPosition) (int32_t playerId, float* xOut, float* yOut, float* zOut); + /* vcmpErrorNoSuchEntity */ + vcmpError (*GetPlayerAimDirection) (int32_t playerId, float* xOut, float* yOut, float* zOut); + + /* + * Player actions and keys + */ + + /* GetLastError: vcmpErrorNoSuchEntity */ + uint8_t (*IsPlayerOnFire) (int32_t playerId); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint8_t (*IsPlayerCrouching) (int32_t playerId); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPlayerAction) (int32_t playerId); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint32_t (*GetPlayerGameKeys) (int32_t playerId); + + /* + * Player vehicle + */ + + /* vcmpErrorNoSuchEntity, vcmpErrorArgumentOutOfBounds, vcmpErrorRequestDenied */ + vcmpError (*PutPlayerInVehicle) (int32_t playerId, int32_t vehicleId, int32_t slotIndex, uint8_t makeRoom, uint8_t warp); + /* vcmpErrorNoSuchEntity */ + vcmpError (*RemovePlayerFromVehicle) (int32_t playerId); + /* GetLastError: vcmpErrorNoSuchEntity */ + vcmpPlayerVehicle (*GetPlayerInVehicleStatus) (int32_t playerId); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPlayerInVehicleSlot) (int32_t playerId); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPlayerVehicleId) (int32_t playerId); + + /* + * Player weapons + */ + + /* vcmpErrorNoSuchEntity, vcmpErrorArgumentOutOfBounds */ + vcmpError (*GivePlayerWeapon) (int32_t playerId, int32_t weaponId, int32_t ammo); + /* vcmpErrorNoSuchEntity, vcmpErrorArgumentOutOfBounds */ + vcmpError (*SetPlayerWeapon) (int32_t playerId, int32_t weaponId, int32_t ammo); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPlayerWeapon) (int32_t playerId); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPlayerWeaponAmmo) (int32_t playerId); + /* vcmpErrorNoSuchEntity, vcmpErrorArgumentOutOfBounds */ + vcmpError (*SetPlayerWeaponSlot) (int32_t playerId, int32_t slot); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPlayerWeaponSlot) (int32_t playerId); + /* GetLastError: vcmpErrorNoSuchEntity, vcmpErrorArgumentOutOfBounds */ + int32_t (*GetPlayerWeaponAtSlot) (int32_t playerId, int32_t slot); + /* GetLastError: vcmpErrorNoSuchEntity, vcmpErrorArgumentOutOfBounds */ + int32_t (*GetPlayerAmmoAtSlot) (int32_t playerId, int32_t slot); + /* vcmpErrorNoSuchEntity */ + vcmpError (*RemovePlayerWeapon) (int32_t playerId, int32_t weaponId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*RemoveAllWeapons) (int32_t playerId); + + /* + * Player camera + */ + + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetCameraPosition) (int32_t playerId, float posX, float posY, float posZ, float lookX, float lookY, float lookZ); + /* vcmpErrorNoSuchEntity */ + vcmpError (*RestoreCamera) (int32_t playerId); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint8_t (*IsCameraLocked) (int32_t playerId); + + /* + * Player miscellaneous stuff + */ + + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPlayerAnimation) (int32_t playerId, int32_t groupId, int32_t animationId); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPlayerStandingOnVehicle) (int32_t playerId); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPlayerStandingOnObject) (int32_t playerId); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint8_t (*IsPlayerAway) (int32_t playerId); + /* vcmpErrorNoSuchEntity */ + int32_t (*GetPlayerSpectateTarget) (int32_t playerId); + /* GetLastError: vcmpErrorNoSuchEntity */ + vcmpError (*SetPlayerSpectateTarget) (int32_t playerId, int32_t targetId); + /* vcmpErrorNoSuchEntity, vcmpErrorNullArgument */ + vcmpError (*RedirectPlayerToServer) (int32_t playerId, const char* ip, uint32_t port, const char* nick, const char* serverPassword, const char* userPassword); + + /* + * All entities + */ + + /* GetLastError: vcmpArgumentOutOfBounds */ + uint8_t (*CheckEntityExists) (vcmpEntityPool entityPool, int32_t index); + + /* + * Vehicles + */ + + /* GetLastError: vcmpErrorArgumentOutOfBounds, vcmpErrorPoolExhausted */ + int32_t (*CreateVehicle) (int32_t modelIndex, int32_t world, float x, float y, float z, float angle, int32_t primaryColour, int32_t secondaryColour); + /* vcmpErrorNoSuchEntity */ + vcmpError (*DeleteVehicle) (int32_t vehicleId); + /* vcmpErrorNoSuchEntity, vcmpErrorArgumentOutOfBounds */ + vcmpError (*SetVehicleOption) (int32_t vehicleId, vcmpVehicleOption option, uint8_t toggle); + /* GetLastError: vcmpErrorNoSuchEntity, vcmpErrorArgumentOutOfBounds */ + uint8_t (*GetVehicleOption) (int32_t vehicleId, vcmpVehicleOption option); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetVehicleSyncSource) (int32_t vehicleId); + /* GetLastError: vcmpErrorNoSuchEntity */ + vcmpVehicleSync (*GetVehicleSyncType) (int32_t vehicleId); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint8_t (*IsVehicleStreamedForPlayer) (int32_t vehicleId, int32_t playerId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetVehicleWorld) (int32_t vehicleId, int32_t world); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetVehicleWorld) (int32_t vehicleId); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetVehicleModel) (int32_t vehicleId); + /* GetLastError: vcmpErrorNoSuchEntity, vcmpErrorArgumentOutOfBounds */ + int32_t (*GetVehicleOccupant) (int32_t vehicleId, int32_t slotIndex); + /* vcmpErrorNoSuchEntity */ + vcmpError (*RespawnVehicle) (int32_t vehicleId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetVehicleImmunityFlags) (int32_t vehicleId, uint32_t immunityFlags); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint32_t (*GetVehicleImmunityFlags) (int32_t vehicleId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*ExplodeVehicle) (int32_t vehicleId); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint8_t (*IsVehicleWrecked) (int32_t vehicleId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetVehiclePosition) (int32_t vehicleId, float x, float y, float z, uint8_t removeOccupants); + /* vcmpErrorNoSuchEntity */ + vcmpError (*GetVehiclePosition) (int32_t vehicleId, float* xOut, float* yOut, float* zOut); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetVehicleRotation) (int32_t vehicleId, float x, float y, float z, float w); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetVehicleRotationEuler) (int32_t vehicleId, float x, float y, float z); + /* vcmpErrorNoSuchEntity */ + vcmpError (*GetVehicleRotation) (int32_t vehicleId, float* xOut, float* yOut, float* zOut, float* wOut); + /* vcmpErrorNoSuchEntity */ + vcmpError (*GetVehicleRotationEuler) (int32_t vehicleId, float* xOut, float* yOut, float* zOut); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetVehicleSpeed) (int32_t vehicleId, float x, float y, float z, uint8_t add, uint8_t relative); + /* vcmpErrorNoSuchEntity */ + vcmpError (*GetVehicleSpeed) (int32_t vehicleId, float* xOut, float* yOut, float* zOut, uint8_t relative); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetVehicleTurnSpeed) (int32_t vehicleId, float x, float y, float z, uint8_t add, uint8_t relative); + /* vcmpErrorNoSuchEntity */ + vcmpError (*GetVehicleTurnSpeed) (int32_t vehicleId, float* xOut, float* yOut, float* zOut, uint8_t relative); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetVehicleSpawnPosition) (int32_t vehicleId, float x, float y, float z); + /* vcmpErrorNoSuchEntity */ + vcmpError (*GetVehicleSpawnPosition) (int32_t vehicleId, float* xOut, float* yOut, float* zOut); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetVehicleSpawnRotation) (int32_t vehicleId, float x, float y, float z, float w); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetVehicleSpawnRotationEuler) (int32_t vehicleId, float x, float y, float z); + /* vcmpErrorNoSuchEntity */ + vcmpError (*GetVehicleSpawnRotation) (int32_t vehicleId, float* xOut, float* yOut, float* zOut, float* wOut); + /* vcmpErrorNoSuchEntity */ + vcmpError (*GetVehicleSpawnRotationEuler) (int32_t vehicleId, float* xOut, float* yOut, float* zOut); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetVehicleIdleRespawnTimer) (int32_t vehicleId, uint32_t millis); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint32_t (*GetVehicleIdleRespawnTimer) (int32_t vehicleId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetVehicleHealth) (int32_t vehicleId, float health); + /* GetLastError: vcmpErrorNoSuchEntity */ + float (*GetVehicleHealth) (int32_t vehicleId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetVehicleColour) (int32_t vehicleId, int32_t primaryColour, int32_t secondaryColour); + /* vcmpErrorNoSuchEntity, vcmpErrorNullArgument */ + vcmpError (*GetVehicleColour) (int32_t vehicleId, int32_t* primaryColourOut, int32_t* secondaryColourOut); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetVehiclePartStatus) (int32_t vehicleId, int32_t partId, int32_t status); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetVehiclePartStatus) (int32_t vehicleId, int32_t partId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetVehicleTyreStatus) (int32_t vehicleId, int32_t tyreId, int32_t status); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetVehicleTyreStatus) (int32_t vehicleId, int32_t tyreId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetVehicleDamageData) (int32_t vehicleId, uint32_t damageData); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint32_t (*GetVehicleDamageData) (int32_t vehicleId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetVehicleRadio) (int32_t vehicleId, int32_t radioId); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetVehicleRadio) (int32_t vehicleId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*GetVehicleTurretRotation) (int32_t vehicleId, float* horizontalOut, float* verticalOut); + + /* + * Vehicle handling + */ + + /* success */ + void (*ResetAllVehicleHandlings) (void); + /* vcmpErrorArgumentOutOfBounds */ + uint8_t (*ExistsHandlingRule) (int32_t modelIndex, int32_t ruleIndex); + /* vcmpErrorArgumentOutOfBounds */ + vcmpError (*SetHandlingRule) (int32_t modelIndex, int32_t ruleIndex, double value); + /* GetLastError: vcmpErrorArgumentOutOfBounds */ + double (*GetHandlingRule) (int32_t modelIndex, int32_t ruleIndex); + /* vcmpErrorArgumentOutOfBounds */ + vcmpError (*ResetHandlingRule) (int32_t modelIndex, int32_t ruleIndex); + /* vcmpErrorArgumentOutOfBounds */ + vcmpError (*ResetHandling) (int32_t modelIndex); + /* GetLastError: vcmpErrorNoSuchEntity, vcmpErrorArgumentOutOfBounds */ + uint8_t (*ExistsInstHandlingRule) (int32_t vehicleId, int32_t ruleIndex); + /* vcmpErrorNoSuchEntity, vcmpErrorArgumentOutOfBounds */ + vcmpError (*SetInstHandlingRule) (int32_t vehicleId, int32_t ruleIndex, double value); + /* GetLastError: vcmpErrorNoSuchEntity, vcmpErrorArgumentOutOfBounds */ + double (*GetInstHandlingRule) (int32_t vehicleId, int32_t ruleIndex); + /* vcmpErrorNoSuchEntity, vcmpErrorArgumentOutOfBounds */ + vcmpError (*ResetInstHandlingRule) (int32_t vehicleId, int32_t ruleIndex); + /* vcmpErrorNoSuchEntity */ + vcmpError (*ResetInstHandling) (int32_t vehicleId); + + /* + * Pickups + */ + + /* vcmpErrorPoolExhausted */ + int32_t (*CreatePickup) (int32_t modelIndex, int32_t world, int32_t quantity, float x, float y, float z, int32_t alpha, uint8_t isAutomatic); + /* vcmpErrorNoSuchEntity */ + vcmpError (*DeletePickup) (int32_t pickupId); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint8_t (*IsPickupStreamedForPlayer) (int32_t pickupId, int32_t playerId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPickupWorld) (int32_t pickupId, int32_t world); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPickupWorld) (int32_t pickupId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPickupAlpha) (int32_t pickupId, int32_t alpha); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPickupAlpha) (int32_t pickupId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPickupIsAutomatic) (int32_t pickupId, uint8_t toggle); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint8_t (*IsPickupAutomatic) (int32_t pickupId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPickupAutoTimer) (int32_t pickupId, uint32_t durationMillis); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint32_t (*GetPickupAutoTimer) (int32_t pickupId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*RefreshPickup) (int32_t pickupId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPickupPosition) (int32_t pickupId, float x, float y, float z); + /* vcmpErrorNoSuchEntity */ + vcmpError (*GetPickupPosition) (int32_t pickupId, float* xOut, float* yOut, float* zOut); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPickupModel) (int32_t pickupId); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetPickupQuantity) (int32_t pickupId); + + /* + * Checkpoints + */ + + /* vcmpErrorPoolExhausted, vcmpErrorNoSuchEntity */ + int32_t (*CreateCheckPoint) (int32_t playerId, int32_t world, uint8_t isSphere, float x, float y, float z, int32_t red, int32_t green, int32_t blue, int32_t alpha, float radius); + /* vcmpErrorNoSuchEntity */ + vcmpError (*DeleteCheckPoint) (int32_t checkPointId); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint8_t (*IsCheckPointStreamedForPlayer) (int32_t checkPointId, int32_t playerId); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint8_t (*IsCheckPointSphere) (int32_t checkPointId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetCheckPointWorld) (int32_t checkPointId, int32_t world); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetCheckPointWorld) (int32_t checkPointId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetCheckPointColour) (int32_t checkPointId, int32_t red, int32_t green, int32_t blue, int32_t alpha); + /* vcmpErrorNoSuchEntity */ + vcmpError (*GetCheckPointColour) (int32_t checkPointId, int32_t* redOut, int32_t* greenOut, int32_t* blueOut, int32_t* alphaOut); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetCheckPointPosition) (int32_t checkPointId, float x, float y, float z); + /* vcmpErrorNoSuchEntity */ + vcmpError (*GetCheckPointPosition) (int32_t checkPointId, float* xOut, float* yOut, float* zOut); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetCheckPointRadius) (int32_t checkPointId, float radius); + /* GetLastError: vcmpErrorNoSuchEntity */ + float (*GetCheckPointRadius) (int32_t checkPointId); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetCheckPointOwner) (int32_t checkPointId); + + /* + * Objects + */ + + /* GetLastError: vcmpErrorPoolExhausted */ + int32_t (*CreateObject) (int32_t modelIndex, int32_t world, float x, float y, float z, int32_t alpha); + /* vcmpErrorNoSuchEntity */ + vcmpError (*DeleteObject) (int32_t objectId); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint8_t (*IsObjectStreamedForPlayer) (int32_t objectId, int32_t playerId); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetObjectModel) (int32_t objectId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetObjectWorld) (int32_t objectId, int32_t world); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetObjectWorld) (int32_t objectId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetObjectAlpha) (int32_t objectId, int32_t alpha, uint32_t duration); + /* GetLastError: vcmpErrorNoSuchEntity */ + int32_t (*GetObjectAlpha) (int32_t objectId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*MoveObjectTo) (int32_t objectId, float x, float y, float z, uint32_t duration); + /* vcmpErrorNoSuchEntity */ + vcmpError (*MoveObjectBy) (int32_t objectId, float x, float y, float z, uint32_t duration); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetObjectPosition) (int32_t objectId, float x, float y, float z); + /* vcmpErrorNoSuchEntity */ + vcmpError (*GetObjectPosition) (int32_t objectId, float* xOut, float* yOut, float* zOut); + /* vcmpErrorNoSuchEntity */ + vcmpError (*RotateObjectTo) (int32_t objectId, float x, float y, float z, float w, uint32_t duration); + /* vcmpErrorNoSuchEntity */ + vcmpError (*RotateObjectToEuler) (int32_t objectId, float x, float y, float z, uint32_t duration); + /* vcmpErrorNoSuchEntity */ + vcmpError (*RotateObjectBy) (int32_t objectId, float x, float y, float z, float w, uint32_t duration); + /* vcmpErrorNoSuchEntity */ + vcmpError (*RotateObjectByEuler) (int32_t objectId, float x, float y, float z, uint32_t duration); + /* vcmpErrorNoSuchEntity */ + vcmpError (*GetObjectRotation) (int32_t objectId, float* xOut, float* yOut, float *zOut, float *wOut); + /* vcmpErrorNoSuchEntity */ + vcmpError (*GetObjectRotationEuler) (int32_t objectId, float* xOut, float* yOut, float *zOut); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetObjectShotReportEnabled) (int32_t objectId, uint8_t toggle); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint8_t (*IsObjectShotReportEnabled) (int32_t objectId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetObjectTouchedReportEnabled) (int32_t objectId, uint8_t toggle); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint8_t (*IsObjectTouchedReportEnabled) (int32_t objectId); - SDK_CreateSphere CreateSphere; - SDK_DeleteSphere DeleteSphere; - SDK_IsSphereStreamedForPlayer IsSphereStreamedForPlayer; - SDK_SetSphereWorld SetSphereWorld; - SDK_GetSphereWorld GetSphereWorld; - SDK_SetSphereColor SetSphereColor; - SDK_GetSphereColor GetSphereColor; - SDK_SetSpherePos SetSpherePos; - SDK_GetSpherePos GetSpherePos; - SDK_SetSphereRadius SetSphereRadius; - SDK_GetSphereRadius GetSphereRadius; - SDK_GetSphereOwner GetSphereOwner; } PluginFuncs; typedef struct { - unsigned int uStructSize; + uint32_t structSize; - SDK_OnInitServer OnInitServer; - SDK_OnShutdownServer OnShutdownServer; - SDK_OnFrame OnFrame; - SDK_OnPlayerConnect OnPlayerConnect; - SDK_OnPlayerDisconnect OnPlayerDisconnect; - SDK_OnPlayerBeginTyping OnPlayerBeginTyping; - SDK_OnPlayerEndTyping OnPlayerEndTyping; - SDK_OnPlayerRequestClass OnPlayerRequestClass; - SDK_OnPlayerRequestSpawn OnPlayerRequestSpawn; - SDK_OnPlayerSpawn OnPlayerSpawn; - SDK_OnPlayerDeath OnPlayerDeath; - SDK_OnPlayerUpdate OnPlayerUpdate; - SDK_OnPlayerRequestEnter OnPlayerRequestEnter; - SDK_OnPlayerEnterVehicle OnPlayerEnterVehicle; - SDK_OnPlayerExitVehicle OnPlayerExitVehicle; - SDK_OnPlayerNameChange OnPlayerNameChange; - SDK_OnPlayerStateChange OnPlayerStateChange; - SDK_OnPlayerActionChange OnPlayerActionChange; - SDK_OnPlayerOnFireChange OnPlayerOnFireChange; - SDK_OnPlayerCrouchChange OnPlayerCrouchChange; - SDK_OnPlayerGameKeysChange OnPlayerGameKeysChange; - SDK_OnPickupClaimPicked OnPickupClaimPicked; - SDK_OnPickupPickedUp OnPickupPickedUp; - SDK_OnPickupRespawn OnPickupRespawn; - SDK_OnVehicleUpdate OnVehicleUpdate; - SDK_OnVehicleExplode OnVehicleExplode; - SDK_OnVehicleRespawn OnVehicleRespawn; - SDK_OnObjectShot OnObjectShot; - SDK_OnObjectBump OnObjectBump; - SDK_OnPublicMessage OnPublicMessage; - SDK_OnCommandMessage OnCommandMessage; - SDK_OnPrivateMessage OnPrivateMessage; - SDK_OnInternalCommand OnInternalCommand; - SDK_OnLoginAttempt OnLoginAttempt; - SDK_OnEntityPoolChange OnEntityPoolChange; - SDK_OnKeyBindDown OnKeyBindDown; - SDK_OnKeyBindUp OnKeyBindUp; - SDK_OnPlayerAwayChange OnPlayerAwayChange; - SDK_OnPlayerSpectate OnPlayerSpectate; - SDK_OnPlayerCrashReport OnPlayerCrashReport; - SDK_OnServerPerformanceReport OnServerPerformanceReport; + uint8_t (*OnServerInitialise) (void); + void (*OnServerShutdown) (void); + void (*OnServerFrame) (float elapsedTime); - // TODO: Move these functions to proper sections on major plugin update - SDK_OnCheckpointEntered OnCheckpointEntered; - SDK_OnCheckpointExited OnCheckpointExited; - SDK_OnSphereEntered OnSphereEntered; - SDK_OnSphereExited OnSphereExited; + uint8_t (*OnPluginCommand) (uint32_t commandIdentifier, const char* message); + uint8_t (*OnIncomingConnection) (char* playerName, size_t nameBufferSize, const char* userPassword, const char* ipAddress); + void (*OnClientScriptData) (int32_t playerId, const uint8_t* data, size_t size); + + void (*OnPlayerConnect) (int32_t playerId); + void (*OnPlayerDisconnect) (int32_t playerId, vcmpDisconnectReason reason); + + uint8_t (*OnPlayerRequestClass) (int32_t playerId, int32_t offset); + uint8_t (*OnPlayerRequestSpawn) (int32_t playerId); + void (*OnPlayerSpawn) (int32_t playerId); + void (*OnPlayerDeath) (int32_t playerId, int32_t killerId, int32_t reason, vcmpBodyPart bodyPart); + void (*OnPlayerUpdate) (int32_t playerId, vcmpPlayerUpdate updateType); + + uint8_t (*OnPlayerRequestEnterVehicle) (int32_t playerId, int32_t vehicleId, int32_t slotIndex); + void (*OnPlayerEnterVehicle) (int32_t playerId, int32_t vehicleId, int32_t slotIndex); + void (*OnPlayerExitVehicle) (int32_t playerId, int32_t vehicleId); + + void (*OnPlayerNameChange) (int32_t playerId, const char* oldName, const char* newName); + void (*OnPlayerStateChange) (int32_t playerId, vcmpPlayerState oldState, vcmpPlayerState newState); + void (*OnPlayerActionChange) (int32_t playerId, int32_t oldAction, int32_t newAction); + void (*OnPlayerOnFireChange) (int32_t playerId, uint8_t isOnFire); + void (*OnPlayerCrouchChange) (int32_t playerId, uint8_t isCrouching); + void (*OnPlayerGameKeysChange) (int32_t playerId, uint32_t oldKeys, uint32_t newKeys); + void (*OnPlayerBeginTyping) (int32_t playerId); + void (*OnPlayerEndTyping) (int32_t playerId); + void (*OnPlayerAwayChange) (int32_t playerId, uint8_t isAway); + + uint8_t (*OnPlayerMessage) (int32_t playerId, const char* message); + uint8_t (*OnPlayerCommand) (int32_t playerId, const char* message); + uint8_t (*OnPlayerPrivateMessage) (int32_t playerId, int32_t targetPlayerId, const char* message); + + void (*OnPlayerKeyBindDown) (int32_t playerId, int32_t bindId); + void (*OnPlayerKeyBindUp) (int32_t playerId, int32_t bindId); + void (*OnPlayerSpectate) (int32_t playerId, int32_t targetPlayerId); + void (*OnPlayerCrashReport) (int32_t playerId, const char* report); + + void (*OnVehicleUpdate) (int32_t vehicleId, vcmpVehicleUpdate updateType); + void (*OnVehicleExplode) (int32_t vehicleId); + void (*OnVehicleRespawn) (int32_t vehicleId); + + void (*OnObjectShot) (int32_t objectId, int32_t playerId, int32_t weaponId); + void (*OnObjectTouched) (int32_t objectId, int32_t playerId); + + uint8_t (*OnPickupPickAttempt) (int32_t pickupId, int32_t playerId); + void (*OnPickupPicked) (int32_t pickupId, int32_t playerId); + void (*OnPickupRespawn) (int32_t pickupId); + + void (*OnCheckpointEntered) (int32_t checkPointId, int32_t playerId); + void (*OnCheckpointExited) (int32_t checkPointId, int32_t playerId); + + void (*OnEntityPoolChange) (vcmpEntityPool entityType, int32_t entityId, uint8_t isDeleted); + void (*OnServerPerformanceReport) (size_t entryCount, const char** descriptions, uint64_t* times); } PluginCallbacks; diff --git a/modules/ini/Module.cpp b/modules/ini/Module.cpp index b9a52610..2e701a7c 100644 --- a/modules/ini/Module.cpp +++ b/modules/ini/Module.cpp @@ -122,12 +122,12 @@ bool CheckAPIVer(CCStr ver) /* -------------------------------------------------------------------------------------------- * React to command sent by other plugins. */ -static int OnInternalCommand(unsigned int type, const char * text) +static uint8_t OnPluginCommand(uint32_t command_identifier, CCStr message) { - switch(type) + switch(command_identifier) { case SQMOD_INITIALIZE_CMD: - if (CheckAPIVer(text)) + if (CheckAPIVer(message)) { OnSquirrelInitialize(); } @@ -146,12 +146,12 @@ static int OnInternalCommand(unsigned int type, const char * text) /* -------------------------------------------------------------------------------------------- * The server was initialized and this plugin was loaded successfully. */ -static int OnInitServer() +static uint8_t OnServerInitialise() { return 1; } -static void OnShutdownServer(void) +static void OnServerShutdown(void) { // The server may still send callbacks UnbindCallbacks(); @@ -160,17 +160,17 @@ static void OnShutdownServer(void) // ------------------------------------------------------------------------------------------------ void BindCallbacks() { - _Clbk->OnInitServer = OnInitServer; - _Clbk->OnInternalCommand = OnInternalCommand; - _Clbk->OnShutdownServer = OnShutdownServer; + _Clbk->OnServerInitialise = OnServerInitialise; + _Clbk->OnServerShutdown = OnServerShutdown; + _Clbk->OnPluginCommand = OnPluginCommand; } // ------------------------------------------------------------------------------------------------ void UnbindCallbacks() { - _Clbk->OnInitServer = nullptr; - _Clbk->OnInternalCommand = nullptr; - _Clbk->OnShutdownServer = nullptr; + _Clbk->OnServerInitialise = nullptr; + _Clbk->OnServerShutdown = nullptr; + _Clbk->OnPluginCommand = nullptr; } // -------------------------------------------------------------------------------------------- @@ -297,17 +297,17 @@ void OutputMessageImpl(const char * msg, va_list args) CONSOLE_SCREEN_BUFFER_INFO csb_before; GetConsoleScreenBufferInfo( hstdout, &csb_before); SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN); - printf("[SQMOD] "); + std::printf("[SQMOD] "); SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); - vprintf(msg, args); - puts(""); + std::vprintf(msg, args); + std::puts(""); SetConsoleTextAttribute(hstdout, csb_before.wAttributes); #else - printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27); - vprintf(msg, args); - puts(""); + std::printf("%c[0;32m[SQMOD]%c[0m", 27, 27); + std::vprintf(msg, args); + std::puts(""); #endif } @@ -320,17 +320,17 @@ void OutputErrorImpl(const char * msg, va_list args) CONSOLE_SCREEN_BUFFER_INFO csb_before; GetConsoleScreenBufferInfo( hstdout, &csb_before); SetConsoleTextAttribute(hstdout, FOREGROUND_RED | FOREGROUND_INTENSITY); - printf("[SQMOD] "); + std::printf("[SQMOD] "); SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); - vprintf(msg, args); - puts(""); + std::vprintf(msg, args); + std::puts(""); SetConsoleTextAttribute(hstdout, csb_before.wAttributes); #else - printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27); - vprintf(msg, args); - puts(""); + std::printf("%c[0;91m[SQMOD]%c[0m", 27, 27); + std::vprintf(msg, args); + std::puts(""); #endif } @@ -398,7 +398,7 @@ SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs* functions, PluginCallb return SQMOD_FAILURE; } // Should never reach this point but just in case - else if (host_plugin_id > (info->nPluginId)) + else if (static_cast< Uint32 >(host_plugin_id) > info->pluginId) { OutputError("%s loaded after the host plugin", SQINI_NAME); // Don't load! @@ -408,9 +408,12 @@ SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs* functions, PluginCallb _Func = functions; _Clbk = callbacks; _Info = info; - // Assign plugin information - _Info->uPluginVer = SQINI_VERSION; - std::strcpy(_Info->szName, SQINI_HOST_NAME); + // Assign plugin version + _Info->pluginVersion = SQINI_VERSION; + _Info->apiMajorVersion = PLUGIN_API_MAJOR; + _Info->apiMinorVersion = PLUGIN_API_MINOR; + // Assign the plugin name + std::snprintf(_Info->name, sizeof(_Info->name), "%s", SQINI_HOST_NAME); // Bind callbacks BindCallbacks(); // Notify that the plugin was successfully loaded diff --git a/modules/irc/Module.cpp b/modules/irc/Module.cpp index 9aa98272..46eb75da 100644 --- a/modules/irc/Module.cpp +++ b/modules/irc/Module.cpp @@ -102,15 +102,6 @@ void OnSquirrelTerminate() DefaultVM::Set(nullptr); } -/* -------------------------------------------------------------------------------------------- - * Update the plugin on each frame. -*/ -static void OnFrame(float /*delta*/) -{ - // Update the sessions and pool for events - Session::Process(); -} - /* -------------------------------------------------------------------------------------------- * Validate the module API to make sure we don't run into issues. */ @@ -133,12 +124,12 @@ bool CheckAPIVer(CCStr ver) /* -------------------------------------------------------------------------------------------- * React to command sent by other plugins. */ -static int OnInternalCommand(unsigned int type, const char * text) +static uint8_t OnPluginCommand(uint32_t command_identifier, CCStr message) { - switch(type) + switch(command_identifier) { case SQMOD_INITIALIZE_CMD: - if (CheckAPIVer(text)) + if (CheckAPIVer(message)) { OnSquirrelInitialize(); } @@ -157,33 +148,42 @@ static int OnInternalCommand(unsigned int type, const char * text) /* -------------------------------------------------------------------------------------------- * The server was initialized and this plugin was loaded successfully. */ -static int OnInitServer() +static uint8_t OnServerInitialise() { return 1; } -static void OnShutdownServer(void) +static void OnServerShutdown(void) { // The server may still send callbacks UnbindCallbacks(); } +/* -------------------------------------------------------------------------------------------- + * Update the plugin on each frame. +*/ +static void OnServerFrame(float /*delta*/) +{ + // Update the sessions and pool for events + Session::Process(); +} + // ------------------------------------------------------------------------------------------------ void BindCallbacks() { - _Clbk->OnInitServer = OnInitServer; - _Clbk->OnFrame = OnFrame; - _Clbk->OnInternalCommand = OnInternalCommand; - _Clbk->OnShutdownServer = OnShutdownServer; + _Clbk->OnServerInitialise = OnServerInitialise; + _Clbk->OnServerShutdown = OnServerShutdown; + _Clbk->OnServerFrame = OnServerFrame; + _Clbk->OnPluginCommand = OnPluginCommand; } // ------------------------------------------------------------------------------------------------ void UnbindCallbacks() { - _Clbk->OnInitServer = nullptr; - _Clbk->OnFrame = nullptr; - _Clbk->OnInternalCommand = nullptr; - _Clbk->OnShutdownServer = nullptr; + _Clbk->OnServerInitialise = nullptr; + _Clbk->OnServerShutdown = nullptr; + _Clbk->OnServerFrame = nullptr; + _Clbk->OnPluginCommand = nullptr; } // -------------------------------------------------------------------------------------------- @@ -496,17 +496,17 @@ void OutputMessageImpl(const char * msg, va_list args) CONSOLE_SCREEN_BUFFER_INFO csb_before; GetConsoleScreenBufferInfo( hstdout, &csb_before); SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN); - printf("[SQMOD] "); + std::printf("[SQMOD] "); SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); - vprintf(msg, args); - puts(""); + std::vprintf(msg, args); + std::puts(""); SetConsoleTextAttribute(hstdout, csb_before.wAttributes); #else - printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27); - vprintf(msg, args); - puts(""); + std::printf("%c[0;32m[SQMOD]%c[0m", 27, 27); + std::vprintf(msg, args); + std::puts(""); #endif } @@ -519,17 +519,17 @@ void OutputErrorImpl(const char * msg, va_list args) CONSOLE_SCREEN_BUFFER_INFO csb_before; GetConsoleScreenBufferInfo( hstdout, &csb_before); SetConsoleTextAttribute(hstdout, FOREGROUND_RED | FOREGROUND_INTENSITY); - printf("[SQMOD] "); + std::printf("[SQMOD] "); SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); - vprintf(msg, args); - puts(""); + std::vprintf(msg, args); + std::puts(""); SetConsoleTextAttribute(hstdout, csb_before.wAttributes); #else - printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27); - vprintf(msg, args); - puts(""); + std::printf("%c[0;91m[SQMOD]%c[0m", 27, 27); + std::vprintf(msg, args); + std::puts(""); #endif } @@ -597,7 +597,7 @@ SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs* functions, PluginCallb return SQMOD_FAILURE; } // Should never reach this point but just in case - else if (host_plugin_id > (info->nPluginId)) + else if (static_cast< Uint32 >(host_plugin_id) > info->pluginId) { OutputError("%s loaded after the host plugin", SQIRC_NAME); // Don't load! @@ -616,9 +616,12 @@ SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs* functions, PluginCallb _Func = functions; _Clbk = callbacks; _Info = info; - // Assign plugin information - _Info->uPluginVer = SQIRC_VERSION; - std::strcpy(_Info->szName, SQIRC_HOST_NAME); + // Assign plugin version + _Info->pluginVersion = SQIRC_VERSION; + _Info->apiMajorVersion = PLUGIN_API_MAJOR; + _Info->apiMinorVersion = PLUGIN_API_MINOR; + // Assign the plugin name + std::snprintf(_Info->name, sizeof(_Info->name), "%s", SQIRC_HOST_NAME); // Bind callbacks BindCallbacks(); // Notify that the plugin was successfully loaded diff --git a/modules/mmdb/Module.cpp b/modules/mmdb/Module.cpp index 6f6dbfdb..7442cf0e 100644 --- a/modules/mmdb/Module.cpp +++ b/modules/mmdb/Module.cpp @@ -18,14 +18,14 @@ namespace SqMod { // -------------------------------------------------------------------------------------------- -PluginFuncs* _Func = NULL; -PluginCallbacks* _Clbk = NULL; -PluginInfo* _Info = NULL; +PluginFuncs* _Func = nullptr; +PluginCallbacks* _Clbk = nullptr; +PluginInfo* _Info = nullptr; // -------------------------------------------------------------------------------------------- -HSQAPI _SqAPI = NULL; -HSQEXPORTS _SqMod = NULL; -HSQUIRRELVM _SqVM = NULL; +HSQAPI _SqAPI = nullptr; +HSQEXPORTS _SqMod = nullptr; +HSQUIRRELVM _SqVM = nullptr; /* ------------------------------------------------------------------------------------------------ * Bind speciffic functions to certain server events. @@ -89,7 +89,7 @@ void OnSquirrelTerminate() { OutputMessage("Terminating: %s", SQMMDB_NAME); // Release the current database (if any) - DefaultVM::Set(NULL); + DefaultVM::Set(nullptr); // Release script resources... } @@ -99,7 +99,7 @@ void OnSquirrelTerminate() bool CheckAPIVer(CCStr ver) { // Obtain the numeric representation of the API version - long vernum = strtol(ver, NULL, 10); + long vernum = strtol(ver, nullptr, 10); // Check against version mismatch if (vernum == SQMOD_API_VER) return true; @@ -113,12 +113,12 @@ bool CheckAPIVer(CCStr ver) /* -------------------------------------------------------------------------------------------- * React to command sent by other plugins. */ -static int OnInternalCommand(unsigned int type, const char * text) +static uint8_t OnPluginCommand(uint32_t command_identifier, CCStr message) { - switch(type) + switch(command_identifier) { case SQMOD_INITIALIZE_CMD: - if (CheckAPIVer(text)) + if (CheckAPIVer(message)) OnSquirrelInitialize(); break; case SQMOD_LOAD_CMD: @@ -135,12 +135,12 @@ static int OnInternalCommand(unsigned int type, const char * text) /* -------------------------------------------------------------------------------------------- * The server was initialized and this plugin was loaded successfully. */ -static int OnInitServer() +static uint8_t OnServerInitialise() { return 1; } -static void OnShutdownServer(void) +static void OnServerShutdown(void) { // The server may still send callbacks UnbindCallbacks(); @@ -149,17 +149,17 @@ static void OnShutdownServer(void) // ------------------------------------------------------------------------------------------------ void BindCallbacks() { - _Clbk->OnInitServer = OnInitServer; - _Clbk->OnInternalCommand = OnInternalCommand; - _Clbk->OnShutdownServer = OnShutdownServer; + _Clbk->OnServerInitialise = OnServerInitialise; + _Clbk->OnServerShutdown = OnServerShutdown; + _Clbk->OnPluginCommand = OnPluginCommand; } // ------------------------------------------------------------------------------------------------ void UnbindCallbacks() { - _Clbk->OnInitServer = NULL; - _Clbk->OnInternalCommand = NULL; - _Clbk->OnShutdownServer = NULL; + _Clbk->OnServerInitialise = nullptr; + _Clbk->OnServerShutdown = nullptr; + _Clbk->OnPluginCommand = nullptr; } // -------------------------------------------------------------------------------------------- @@ -177,17 +177,17 @@ void OutputMessageImpl(const char * msg, va_list args) CONSOLE_SCREEN_BUFFER_INFO csb_before; GetConsoleScreenBufferInfo( hstdout, &csb_before); SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN); - printf("[SQMOD] "); + std::printf("[SQMOD] "); SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); - vprintf(msg, args); - puts(""); + std::vprintf(msg, args); + std::puts(""); SetConsoleTextAttribute(hstdout, csb_before.wAttributes); #else - printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27); - vprintf(msg, args); - puts(""); + std::printf("%c[0;32m[SQMOD]%c[0m", 27, 27); + std::vprintf(msg, args); + std::puts(""); #endif } @@ -200,17 +200,17 @@ void OutputErrorImpl(const char * msg, va_list args) CONSOLE_SCREEN_BUFFER_INFO csb_before; GetConsoleScreenBufferInfo( hstdout, &csb_before); SetConsoleTextAttribute(hstdout, FOREGROUND_RED | FOREGROUND_INTENSITY); - printf("[SQMOD] "); + std::printf("[SQMOD] "); SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); - vprintf(msg, args); - puts(""); + std::vprintf(msg, args); + std::puts(""); SetConsoleTextAttribute(hstdout, csb_before.wAttributes); #else - printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27); - vprintf(msg, args); - puts(""); + std::printf("%c[0;91m[SQMOD]%c[0m", 27, 27); + std::vprintf(msg, args); + std::puts(""); #endif } @@ -288,9 +288,12 @@ SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs* functions, PluginCallb _Func = functions; _Clbk = callbacks; _Info = info; - // Assign plugin information - _Info->uPluginVer = SQMMDB_VERSION; - strcpy(_Info->szName, SQMMDB_HOST_NAME); + // Assign plugin version + _Info->pluginVersion = SQMMDB_VERSION; + _Info->apiMajorVersion = PLUGIN_API_MAJOR; + _Info->apiMinorVersion = PLUGIN_API_MINOR; + // Assign the plugin name + std::snprintf(_Info->name, sizeof(_Info->name), "%s", SQMMDB_HOST_NAME); // Bind callbacks BindCallbacks(); // Notify that the plugin was successfully loaded diff --git a/modules/sample/Module.cpp b/modules/sample/Module.cpp index 9014a6d5..524ef62e 100644 --- a/modules/sample/Module.cpp +++ b/modules/sample/Module.cpp @@ -122,12 +122,12 @@ bool CheckAPIVer(CCStr ver) /* -------------------------------------------------------------------------------------------- * React to command sent by other plugins. */ -static int OnInternalCommand(unsigned int type, const char * text) +static uint8_t OnPluginCommand(uint32_t command_identifier, CCStr message) { - switch(type) + switch(command_identifier) { case SQMOD_INITIALIZE_CMD: - if (CheckAPIVer(text)) + if (CheckAPIVer(message)) { OnSquirrelInitialize(); } @@ -146,12 +146,12 @@ static int OnInternalCommand(unsigned int type, const char * text) /* -------------------------------------------------------------------------------------------- * The server was initialized and this plugin was loaded successfully. */ -static int OnInitServer() +static uint8_t OnServerInitialise() { return 1; } -static void OnShutdownServer(void) +static void OnServerShutdown(void) { // The server may still send callbacks UnbindCallbacks(); @@ -160,17 +160,17 @@ static void OnShutdownServer(void) // ------------------------------------------------------------------------------------------------ void BindCallbacks() { - _Clbk->OnInitServer = OnInitServer; - _Clbk->OnInternalCommand = OnInternalCommand; - _Clbk->OnShutdownServer = OnShutdownServer; + _Clbk->OnServerInitialise = OnServerInitialise; + _Clbk->OnServerShutdown = OnServerShutdown; + _Clbk->OnPluginCommand = OnPluginCommand; } // ------------------------------------------------------------------------------------------------ void UnbindCallbacks() { - _Clbk->OnInitServer = nullptr; - _Clbk->OnInternalCommand = nullptr; - _Clbk->OnShutdownServer = nullptr; + _Clbk->OnServerInitialise = nullptr; + _Clbk->OnServerShutdown = nullptr; + _Clbk->OnPluginCommand = nullptr; } // -------------------------------------------------------------------------------------------- @@ -204,7 +204,7 @@ void OutputMessageImpl(const char * msg, va_list args) SetConsoleTextAttribute(hstdout, csb_before.wAttributes); #else - std::printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27); + std::printf("%c[0;32m[SQMOD]%c[0m", 27, 27); std::vprintf(msg, args); std::puts(""); #endif @@ -227,7 +227,7 @@ void OutputErrorImpl(const char * msg, va_list args) SetConsoleTextAttribute(hstdout, csb_before.wAttributes); #else - std::printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27); + std::printf("%c[0;91m[SQMOD]%c[0m", 27, 27); std::vprintf(msg, args); std::puts(""); #endif @@ -297,7 +297,7 @@ SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs* functions, PluginCallb return SQMOD_FAILURE; } // Should never reach this point but just in case - else if (host_plugin_id > (info->nPluginId)) + else if (static_cast< Uint32 >(host_plugin_id) > info->pluginId) { OutputError("%s loaded after the host plugin", SQSAMPLE_NAME); // Don't load! @@ -307,9 +307,12 @@ SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs* functions, PluginCallb _Func = functions; _Clbk = callbacks; _Info = info; - // Assign plugin information - _Info->uPluginVer = SQSAMPLE_VERSION; - std::strcpy(_Info->szName, SQSAMPLE_HOST_NAME); + // Assign plugin version + _Info->pluginVersion = SQSAMPLE_VERSION; + _Info->apiMajorVersion = PLUGIN_API_MAJOR; + _Info->apiMinorVersion = PLUGIN_API_MINOR; + // Assign the plugin name + std::snprintf(_Info->name, sizeof(_Info->name), "%s", SQSAMPLE_HOST_NAME); // Bind callbacks BindCallbacks(); // Notify that the plugin was successfully loaded diff --git a/modules/sqlite/Module.cpp b/modules/sqlite/Module.cpp index 07b61bd0..b85bc7a0 100644 --- a/modules/sqlite/Module.cpp +++ b/modules/sqlite/Module.cpp @@ -123,12 +123,12 @@ bool CheckAPIVer(CCStr ver) /* -------------------------------------------------------------------------------------------- * React to command sent by other plugins. */ -static int OnInternalCommand(unsigned int type, const char * text) +static uint8_t OnPluginCommand(uint32_t command_identifier, CCStr message) { - switch(type) + switch(command_identifier) { case SQMOD_INITIALIZE_CMD: - if (CheckAPIVer(text)) + if (CheckAPIVer(message)) { OnSquirrelInitialize(); } @@ -147,12 +147,12 @@ static int OnInternalCommand(unsigned int type, const char * text) /* -------------------------------------------------------------------------------------------- * The server was initialized and this plugin was loaded successfully. */ -static int OnInitServer() +static uint8_t OnServerInitialise() { return 1; } -static void OnShutdownServer(void) +static void OnServerShutdown(void) { // The server may still send callbacks UnbindCallbacks(); @@ -161,17 +161,17 @@ static void OnShutdownServer(void) // ------------------------------------------------------------------------------------------------ void BindCallbacks() { - _Clbk->OnInitServer = OnInitServer; - _Clbk->OnInternalCommand = OnInternalCommand; - _Clbk->OnShutdownServer = OnShutdownServer; + _Clbk->OnServerInitialise = OnServerInitialise; + _Clbk->OnServerShutdown = OnServerShutdown; + _Clbk->OnPluginCommand = OnPluginCommand; } // ------------------------------------------------------------------------------------------------ void UnbindCallbacks() { - _Clbk->OnInitServer = nullptr; - _Clbk->OnInternalCommand = nullptr; - _Clbk->OnShutdownServer = nullptr; + _Clbk->OnServerInitialise = nullptr; + _Clbk->OnServerShutdown = nullptr; + _Clbk->OnPluginCommand = nullptr; } // -------------------------------------------------------------------------------------------- @@ -712,17 +712,17 @@ void OutputMessageImpl(const char * msg, va_list args) CONSOLE_SCREEN_BUFFER_INFO csb_before; GetConsoleScreenBufferInfo( hstdout, &csb_before); SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN); - printf("[SQMOD] "); + std::printf("[SQMOD] "); SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); - vprintf(msg, args); - puts(""); + std::vprintf(msg, args); + std::puts(""); SetConsoleTextAttribute(hstdout, csb_before.wAttributes); #else - printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27); - vprintf(msg, args); - puts(""); + std::printf("%c[0;32m[SQMOD]%c[0m", 27, 27); + std::vprintf(msg, args); + std::puts(""); #endif } @@ -735,17 +735,17 @@ void OutputErrorImpl(const char * msg, va_list args) CONSOLE_SCREEN_BUFFER_INFO csb_before; GetConsoleScreenBufferInfo( hstdout, &csb_before); SetConsoleTextAttribute(hstdout, FOREGROUND_RED | FOREGROUND_INTENSITY); - printf("[SQMOD] "); + std::printf("[SQMOD] "); SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); - vprintf(msg, args); - puts(""); + std::vprintf(msg, args); + std::puts(""); SetConsoleTextAttribute(hstdout, csb_before.wAttributes); #else - printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27); - vprintf(msg, args); - puts(""); + std::printf("%c[0;91m[SQMOD]%c[0m", 27, 27); + std::vprintf(msg, args); + std::puts(""); #endif } @@ -813,7 +813,7 @@ SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs* functions, PluginCallb return SQMOD_FAILURE; } // Should never reach this point but just in case - else if (host_plugin_id > (info->nPluginId)) + else if (static_cast< Uint32 >(host_plugin_id) > info->pluginId) { OutputError("%s loaded after the host plugin", SQSQLITE_NAME); // Don't load! @@ -823,9 +823,12 @@ SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs* functions, PluginCallb _Func = functions; _Clbk = callbacks; _Info = info; - // Assign plugin information - _Info->uPluginVer = SQSQLITE_VERSION; - std::strcpy(_Info->szName, SQSQLITE_HOST_NAME); + // Assign plugin version + _Info->pluginVersion = SQSQLITE_VERSION; + _Info->apiMajorVersion = PLUGIN_API_MAJOR; + _Info->apiMinorVersion = PLUGIN_API_MINOR; + // Assign the plugin name + std::snprintf(_Info->name, sizeof(_Info->name), "%s", SQSQLITE_HOST_NAME); // Bind callbacks BindCallbacks(); // Notify that the plugin was successfully loaded diff --git a/modules/tcc/API.cpp b/modules/tcc/API.cpp deleted file mode 100644 index 0f2b37a6..00000000 --- a/modules/tcc/API.cpp +++ /dev/null @@ -1,607 +0,0 @@ -// ------------------------------------------------------------------------------------------------ -#include "Common.hpp" -#include "Module.hpp" - -// ------------------------------------------------------------------------------------------------ -#include -#include - -// ------------------------------------------------------------------------------------------------ -namespace SqMod { - -// ------------------------------------------------------------------------------------------------ -#define TCC_FUNC(p) reinterpret_cast< const void * >(p) - -// ------------------------------------------------------------------------------------------------ -static HSQUIRRELVM GetSqVM() -{ - return _SqVM; -} - -// ------------------------------------------------------------------------------------------------ -void RegisterAPI(StateHnd & s) -{ - // Make sure the state is valid and not relocated - if (!s || s->mRelocated) - { - return; - } - // Specify whether this is a 64bit build -#ifdef _SQ64 - s.DefineSymbol("__SQ64", "1"); -#endif // _SQ64 - // ctype.h - s.AddSymbol("isalnum", TCC_FUNC(isalnum)); - s.AddSymbol("isalpha", TCC_FUNC(isalpha)); - s.AddSymbol("isblank", TCC_FUNC(isblank)); - s.AddSymbol("iscntrl", TCC_FUNC(iscntrl)); - s.AddSymbol("isdigit", TCC_FUNC(isdigit)); - s.AddSymbol("isgraph", TCC_FUNC(isgraph)); - s.AddSymbol("islower", TCC_FUNC(islower)); - s.AddSymbol("isprint", TCC_FUNC(isprint)); - s.AddSymbol("ispunct", TCC_FUNC(ispunct)); - s.AddSymbol("isspace", TCC_FUNC(isspace)); - s.AddSymbol("isupper", TCC_FUNC(isupper)); - s.AddSymbol("isxdigit", TCC_FUNC(isxdigit)); - // stdio.h - s.AddSymbol("printf", TCC_FUNC(printf)); - // Helpers - s.AddSymbol("get_sqvm", TCC_FUNC(GetSqVM)); - // VC:MP - s.AddSymbol("vcGetServerVersion", TCC_FUNC(_Func->GetServerVersion)); - s.AddSymbol("vcGetServerSettings", TCC_FUNC(_Func->GetServerSettings)); - s.AddSymbol("vcExportFunctions", TCC_FUNC(_Func->ExportFunctions)); - s.AddSymbol("vcGetNumberOfPlugins", TCC_FUNC(_Func->GetNumberOfPlugins)); - s.AddSymbol("vcGetPluginInfo", TCC_FUNC(_Func->GetPluginInfo)); - s.AddSymbol("vcFindPlugin", TCC_FUNC(_Func->FindPlugin)); - s.AddSymbol("vcGetPluginExports", TCC_FUNC(_Func->GetPluginExports)); - s.AddSymbol("vcGetTime", TCC_FUNC(_Func->GetTime)); - s.AddSymbol("vcprintf", TCC_FUNC(_Func->printf)); - s.AddSymbol("vcSendCustomCommand", TCC_FUNC(_Func->SendCustomCommand)); - s.AddSymbol("vcSendClientMessage", TCC_FUNC(_Func->SendClientMessage)); - s.AddSymbol("vcSendGameMessage", TCC_FUNC(_Func->SendGameMessage)); - s.AddSymbol("vcSetServerName", TCC_FUNC(_Func->SetServerName)); - s.AddSymbol("vcGetServerName", TCC_FUNC(_Func->GetServerName)); - s.AddSymbol("vcSetMaxPlayers", TCC_FUNC(_Func->SetMaxPlayers)); - s.AddSymbol("vcGetMaxPlayers", TCC_FUNC(_Func->GetMaxPlayers)); - s.AddSymbol("vcSetServerPassword", TCC_FUNC(_Func->SetServerPassword)); - s.AddSymbol("vcGetServerPassword", TCC_FUNC(_Func->GetServerPassword)); - s.AddSymbol("vcSetGameModeText", TCC_FUNC(_Func->SetGameModeText)); - s.AddSymbol("vcGetGameModeText", TCC_FUNC(_Func->GetGameModeText)); - s.AddSymbol("vcShutdownServer", TCC_FUNC(_Func->ShutdownServer)); - s.AddSymbol("vcSetWorldBounds", TCC_FUNC(_Func->SetWorldBounds)); - s.AddSymbol("vcGetWorldBounds", TCC_FUNC(_Func->GetWorldBounds)); - s.AddSymbol("vcSetWastedSettings", TCC_FUNC(_Func->SetWastedSettings)); - s.AddSymbol("vcGetWastedSettings", TCC_FUNC(_Func->GetWastedSettings)); - s.AddSymbol("vcSetTimeRate", TCC_FUNC(_Func->SetTimeRate)); - s.AddSymbol("vcGetTimeRate", TCC_FUNC(_Func->GetTimeRate)); - s.AddSymbol("vcSetHour", TCC_FUNC(_Func->SetHour)); - s.AddSymbol("vcGetHour", TCC_FUNC(_Func->GetHour)); - s.AddSymbol("vcSetMinute", TCC_FUNC(_Func->SetMinute)); - s.AddSymbol("vcGetMinute", TCC_FUNC(_Func->GetMinute)); - s.AddSymbol("vcSetWeather", TCC_FUNC(_Func->SetWeather)); - s.AddSymbol("vcGetWeather", TCC_FUNC(_Func->GetWeather)); - s.AddSymbol("vcSetGravity", TCC_FUNC(_Func->SetGravity)); - s.AddSymbol("vcGetGravity", TCC_FUNC(_Func->GetGravity)); - s.AddSymbol("vcSetGamespeed", TCC_FUNC(_Func->SetGamespeed)); - s.AddSymbol("vcGetGamespeed", TCC_FUNC(_Func->GetGamespeed)); - s.AddSymbol("vcSetWaterLevel", TCC_FUNC(_Func->SetWaterLevel)); - s.AddSymbol("vcGetWaterLevel", TCC_FUNC(_Func->GetWaterLevel)); - s.AddSymbol("vcSetMaxHeight", TCC_FUNC(_Func->SetMaxHeight)); - s.AddSymbol("vcGetMaxHeight", TCC_FUNC(_Func->GetMaxHeight)); - s.AddSymbol("vcSetKillCmdDelay", TCC_FUNC(_Func->SetKillCmdDelay)); - s.AddSymbol("vcGetKillCmdDelay", TCC_FUNC(_Func->GetKillCmdDelay)); - s.AddSymbol("vcSetVehiclesForcedRespawnHeight", TCC_FUNC(_Func->SetVehiclesForcedRespawnHeight)); - s.AddSymbol("vcGetVehiclesForcedRespawnHeight", TCC_FUNC(_Func->GetVehiclesForcedRespawnHeight)); - s.AddSymbol("vcToggleSyncFrameLimiter", TCC_FUNC(_Func->ToggleSyncFrameLimiter)); - s.AddSymbol("vcEnabledSyncFrameLimiter", TCC_FUNC(_Func->EnabledSyncFrameLimiter)); - s.AddSymbol("vcToggleFrameLimiter", TCC_FUNC(_Func->ToggleFrameLimiter)); - s.AddSymbol("vcEnabledFrameLimiter", TCC_FUNC(_Func->EnabledFrameLimiter)); - s.AddSymbol("vcToggleTaxiBoostJump", TCC_FUNC(_Func->ToggleTaxiBoostJump)); - s.AddSymbol("vcEnabledTaxiBoostJump", TCC_FUNC(_Func->EnabledTaxiBoostJump)); - s.AddSymbol("vcToggleDriveOnWater", TCC_FUNC(_Func->ToggleDriveOnWater)); - s.AddSymbol("vcEnabledDriveOnWater", TCC_FUNC(_Func->EnabledDriveOnWater)); - s.AddSymbol("vcToggleFastSwitch", TCC_FUNC(_Func->ToggleFastSwitch)); - s.AddSymbol("vcEnabledFastSwitch", TCC_FUNC(_Func->EnabledFastSwitch)); - s.AddSymbol("vcToggleFriendlyFire", TCC_FUNC(_Func->ToggleFriendlyFire)); - s.AddSymbol("vcEnabledFriendlyFire", TCC_FUNC(_Func->EnabledFriendlyFire)); - s.AddSymbol("vcToggleDisableDriveby", TCC_FUNC(_Func->ToggleDisableDriveby)); - s.AddSymbol("vcEnabledDisableDriveby", TCC_FUNC(_Func->EnabledDisableDriveby)); - s.AddSymbol("vcTogglePerfectHandling", TCC_FUNC(_Func->TogglePerfectHandling)); - s.AddSymbol("vcEnabledPerfectHandling", TCC_FUNC(_Func->EnabledPerfectHandling)); - s.AddSymbol("vcToggleFlyingCars", TCC_FUNC(_Func->ToggleFlyingCars)); - s.AddSymbol("vcEnabledFlyingCars", TCC_FUNC(_Func->EnabledFlyingCars)); - s.AddSymbol("vcToggleJumpSwitch", TCC_FUNC(_Func->ToggleJumpSwitch)); - s.AddSymbol("vcEnabledJumpSwitch", TCC_FUNC(_Func->EnabledJumpSwitch)); - s.AddSymbol("vcToggleShowMarkers", TCC_FUNC(_Func->ToggleShowMarkers)); - s.AddSymbol("vcEnabledShowMarkers", TCC_FUNC(_Func->EnabledShowMarkers)); - s.AddSymbol("vcToggleOnlyShowTeamMarkers", TCC_FUNC(_Func->ToggleOnlyShowTeamMarkers)); - s.AddSymbol("vcEnabledOnlyShowTeamMarkers", TCC_FUNC(_Func->EnabledOnlyShowTeamMarkers)); - s.AddSymbol("vcToggleStuntBike", TCC_FUNC(_Func->ToggleStuntBike)); - s.AddSymbol("vcEnabledStuntBike", TCC_FUNC(_Func->EnabledStuntBike)); - s.AddSymbol("vcToggleShootInAir", TCC_FUNC(_Func->ToggleShootInAir)); - s.AddSymbol("vcEnabledShootInAir", TCC_FUNC(_Func->EnabledShootInAir)); - s.AddSymbol("vcToggleShowNametags", TCC_FUNC(_Func->ToggleShowNametags)); - s.AddSymbol("vcEnabledShowNametags", TCC_FUNC(_Func->EnabledShowNametags)); - s.AddSymbol("vcToggleJoinMessages", TCC_FUNC(_Func->ToggleJoinMessages)); - s.AddSymbol("vcEnabledJoinMessages", TCC_FUNC(_Func->EnabledJoinMessages)); - s.AddSymbol("vcToggleDeathMessages", TCC_FUNC(_Func->ToggleDeathMessages)); - s.AddSymbol("vcEnabledDeathMessages", TCC_FUNC(_Func->EnabledDeathMessages)); - s.AddSymbol("vcToggleChatTagsByDefaultEnabled", TCC_FUNC(_Func->ToggleChatTagsByDefaultEnabled)); - s.AddSymbol("vcEnabledChatTagsByDefault", TCC_FUNC(_Func->EnabledChatTagsByDefault)); - s.AddSymbol("vcCreateExplosion", TCC_FUNC(_Func->CreateExplosion)); - s.AddSymbol("vcPlaySound", TCC_FUNC(_Func->PlaySound)); - s.AddSymbol("vcHideMapObject", TCC_FUNC(_Func->HideMapObject)); - s.AddSymbol("vcShowMapObject", TCC_FUNC(_Func->ShowMapObject)); - s.AddSymbol("vcShowAllMapObjects", TCC_FUNC(_Func->ShowAllMapObjects)); - s.AddSymbol("vcSetWeaponDataValue", TCC_FUNC(_Func->SetWeaponDataValue)); - s.AddSymbol("vcGetWeaponDataValue", TCC_FUNC(_Func->GetWeaponDataValue)); - s.AddSymbol("vcResetWeaponDataValue", TCC_FUNC(_Func->ResetWeaponDataValue)); - s.AddSymbol("vcIsWeaponDataValueModified", TCC_FUNC(_Func->IsWeaponDataValueModified)); - s.AddSymbol("vcResetWeaponData", TCC_FUNC(_Func->ResetWeaponData)); - s.AddSymbol("vcResetAllWeaponData", TCC_FUNC(_Func->ResetAllWeaponData)); - s.AddSymbol("vcGetKeyBindUnusedSlot", TCC_FUNC(_Func->GetKeyBindUnusedSlot)); - s.AddSymbol("vcGetKeyBindData", TCC_FUNC(_Func->GetKeyBindData)); - s.AddSymbol("vcRegisterKeyBind", TCC_FUNC(_Func->RegisterKeyBind)); - s.AddSymbol("vcRemoveKeyBind", TCC_FUNC(_Func->RemoveKeyBind)); - s.AddSymbol("vcRemoveAllKeyBinds", TCC_FUNC(_Func->RemoveAllKeyBinds)); - s.AddSymbol("vcCreateCoordBlip", TCC_FUNC(_Func->CreateCoordBlip)); - s.AddSymbol("vcDestroyCoordBlip", TCC_FUNC(_Func->DestroyCoordBlip)); - s.AddSymbol("vcGetCoordBlipInfo", TCC_FUNC(_Func->GetCoordBlipInfo)); - s.AddSymbol("vcCreateSprite", TCC_FUNC(_Func->CreateSprite)); - s.AddSymbol("vcDestroySprite", TCC_FUNC(_Func->DestroySprite)); - s.AddSymbol("vcShowSprite", TCC_FUNC(_Func->ShowSprite)); - s.AddSymbol("vcHideSprite", TCC_FUNC(_Func->HideSprite)); - s.AddSymbol("vcMoveSprite", TCC_FUNC(_Func->MoveSprite)); - s.AddSymbol("vcSetSpriteCenter", TCC_FUNC(_Func->SetSpriteCenter)); - s.AddSymbol("vcRotateSprite", TCC_FUNC(_Func->RotateSprite)); - s.AddSymbol("vcSetSpriteAlpha", TCC_FUNC(_Func->SetSpriteAlpha)); - s.AddSymbol("vcSetSpriteRelativity", TCC_FUNC(_Func->SetSpriteRelativity)); - s.AddSymbol("vcCreateTextdraw", TCC_FUNC(_Func->CreateTextdraw)); - s.AddSymbol("vcDestroyTextdraw", TCC_FUNC(_Func->DestroyTextdraw)); - s.AddSymbol("vcShowTextdraw", TCC_FUNC(_Func->ShowTextdraw)); - s.AddSymbol("vcHideTextdraw", TCC_FUNC(_Func->HideTextdraw)); - s.AddSymbol("vcMoveTextdraw", TCC_FUNC(_Func->MoveTextdraw)); - s.AddSymbol("vcSetTextdrawColour", TCC_FUNC(_Func->SetTextdrawColour)); - s.AddSymbol("vcSetTextdrawRelativity", TCC_FUNC(_Func->SetTextdrawRelativity)); - s.AddSymbol("vcAddRadioStream", TCC_FUNC(_Func->AddRadioStream)); - s.AddSymbol("vcRemoveRadioStream", TCC_FUNC(_Func->RemoveRadioStream)); - s.AddSymbol("vcSetUseClasses", TCC_FUNC(_Func->SetUseClasses)); - s.AddSymbol("vcGetUseClasses", TCC_FUNC(_Func->GetUseClasses)); - s.AddSymbol("vcGetPlayerClass", TCC_FUNC(_Func->GetPlayerClass)); - s.AddSymbol("vcAddPlayerClass", TCC_FUNC(_Func->AddPlayerClass)); - s.AddSymbol("vcSetSpawnPlayerPos", TCC_FUNC(_Func->SetSpawnPlayerPos)); - s.AddSymbol("vcSetSpawnCameraPos", TCC_FUNC(_Func->SetSpawnCameraPos)); - s.AddSymbol("vcSetSpawnCameraLookAt", TCC_FUNC(_Func->SetSpawnCameraLookAt)); - s.AddSymbol("vcIsPlayerAdmin", TCC_FUNC(_Func->IsPlayerAdmin)); - s.AddSymbol("vcSetPlayerAdmin", TCC_FUNC(_Func->SetPlayerAdmin)); - s.AddSymbol("vcGetPlayerIP", TCC_FUNC(_Func->GetPlayerIP)); - s.AddSymbol("vcKickPlayer", TCC_FUNC(_Func->KickPlayer)); - s.AddSymbol("vcBanPlayer", TCC_FUNC(_Func->BanPlayer)); - s.AddSymbol("vcBanIP", TCC_FUNC(_Func->BanIP)); - s.AddSymbol("vcUnbanIP", TCC_FUNC(_Func->UnbanIP)); - s.AddSymbol("vcIsIPBanned", TCC_FUNC(_Func->IsIPBanned)); - s.AddSymbol("vcGetPlayerIDFromName", TCC_FUNC(_Func->GetPlayerIDFromName)); - s.AddSymbol("vcIsPlayerConnected", TCC_FUNC(_Func->IsPlayerConnected)); - s.AddSymbol("vcIsPlayerSpawned", TCC_FUNC(_Func->IsPlayerSpawned)); - s.AddSymbol("vcIsPlayerStreamedForPlayer", TCC_FUNC(_Func->IsPlayerStreamedForPlayer)); - s.AddSymbol("vcGetPlayerKey", TCC_FUNC(_Func->GetPlayerKey)); - s.AddSymbol("vcSetPlayerWorld", TCC_FUNC(_Func->SetPlayerWorld)); - s.AddSymbol("vcGetPlayerWorld", TCC_FUNC(_Func->GetPlayerWorld)); - s.AddSymbol("vcSetPlayerSecWorld", TCC_FUNC(_Func->SetPlayerSecWorld)); - s.AddSymbol("vcGetPlayerSecWorld", TCC_FUNC(_Func->GetPlayerSecWorld)); - s.AddSymbol("vcGetPlayerUniqueWorld", TCC_FUNC(_Func->GetPlayerUniqueWorld)); - s.AddSymbol("vcIsPlayerWorldCompatible", TCC_FUNC(_Func->IsPlayerWorldCompatible)); - s.AddSymbol("vcGetPlayerState", TCC_FUNC(_Func->GetPlayerState)); - s.AddSymbol("vcGetPlayerName", TCC_FUNC(_Func->GetPlayerName)); - s.AddSymbol("vcSetPlayerName", TCC_FUNC(_Func->SetPlayerName)); - s.AddSymbol("vcSetPlayerTeam", TCC_FUNC(_Func->SetPlayerTeam)); - s.AddSymbol("vcGetPlayerTeam", TCC_FUNC(_Func->GetPlayerTeam)); - s.AddSymbol("vcSetPlayerSkin", TCC_FUNC(_Func->SetPlayerSkin)); - s.AddSymbol("vcGetPlayerSkin", TCC_FUNC(_Func->GetPlayerSkin)); - s.AddSymbol("vcSetPlayerColour", TCC_FUNC(_Func->SetPlayerColour)); - s.AddSymbol("vcGetPlayerColour", TCC_FUNC(_Func->GetPlayerColour)); - s.AddSymbol("vcForcePlayerSpawn", TCC_FUNC(_Func->ForcePlayerSpawn)); - s.AddSymbol("vcForcePlayerSelect", TCC_FUNC(_Func->ForcePlayerSelect)); - s.AddSymbol("vcForceAllSelect", TCC_FUNC(_Func->ForceAllSelect)); - s.AddSymbol("vcGivePlayerMoney", TCC_FUNC(_Func->GivePlayerMoney)); - s.AddSymbol("vcSetPlayerMoney", TCC_FUNC(_Func->SetPlayerMoney)); - s.AddSymbol("vcGetPlayerMoney", TCC_FUNC(_Func->GetPlayerMoney)); - s.AddSymbol("vcSetPlayerScore", TCC_FUNC(_Func->SetPlayerScore)); - s.AddSymbol("vcGetPlayerScore", TCC_FUNC(_Func->GetPlayerScore)); - s.AddSymbol("vcGetPlayerPing", TCC_FUNC(_Func->GetPlayerPing)); - s.AddSymbol("vcIsPlayerTyping", TCC_FUNC(_Func->IsPlayerTyping)); - s.AddSymbol("vcGetPlayerFPS", TCC_FUNC(_Func->GetPlayerFPS)); - s.AddSymbol("vcGetPlayerUID", TCC_FUNC(_Func->GetPlayerUID)); - s.AddSymbol("vcGetPlayerWantedLevel", TCC_FUNC(_Func->GetPlayerWantedLevel)); - s.AddSymbol("vcSetPlayerHealth", TCC_FUNC(_Func->SetPlayerHealth)); - s.AddSymbol("vcGetPlayerHealth", TCC_FUNC(_Func->GetPlayerHealth)); - s.AddSymbol("vcSetPlayerArmour", TCC_FUNC(_Func->SetPlayerArmour)); - s.AddSymbol("vcGetPlayerArmour", TCC_FUNC(_Func->GetPlayerArmour)); - s.AddSymbol("vcSetPlayerImmunityFlags", TCC_FUNC(_Func->SetPlayerImmunityFlags)); - s.AddSymbol("vcGetPlayerImmunityFlags", TCC_FUNC(_Func->GetPlayerImmunityFlags)); - s.AddSymbol("vcSetPlayerPos", TCC_FUNC(_Func->SetPlayerPos)); - s.AddSymbol("vcGetPlayerPos", TCC_FUNC(_Func->GetPlayerPos)); - s.AddSymbol("vcSetPlayerSpeed", TCC_FUNC(_Func->SetPlayerSpeed)); - s.AddSymbol("vcGetPlayerSpeed", TCC_FUNC(_Func->GetPlayerSpeed)); - s.AddSymbol("vcAddPlayerSpeed", TCC_FUNC(_Func->AddPlayerSpeed)); - s.AddSymbol("vcSetPlayerHeading", TCC_FUNC(_Func->SetPlayerHeading)); - s.AddSymbol("vcGetPlayerHeading", TCC_FUNC(_Func->GetPlayerHeading)); - s.AddSymbol("vcSetPlayerAlpha", TCC_FUNC(_Func->SetPlayerAlpha)); - s.AddSymbol("vcGetPlayerAlpha", TCC_FUNC(_Func->GetPlayerAlpha)); - s.AddSymbol("vcGetPlayerOnFireStatus", TCC_FUNC(_Func->GetPlayerOnFireStatus)); - s.AddSymbol("vcGetPlayerCrouchStatus", TCC_FUNC(_Func->GetPlayerCrouchStatus)); - s.AddSymbol("vcGetPlayerAction", TCC_FUNC(_Func->GetPlayerAction)); - s.AddSymbol("vcGetPlayerGameKeys", TCC_FUNC(_Func->GetPlayerGameKeys)); - s.AddSymbol("vcGetPlayerAimPos", TCC_FUNC(_Func->GetPlayerAimPos)); - s.AddSymbol("vcGetPlayerAimDir", TCC_FUNC(_Func->GetPlayerAimDir)); - s.AddSymbol("vcPutPlayerInVehicle", TCC_FUNC(_Func->PutPlayerInVehicle)); - s.AddSymbol("vcRemovePlayerFromVehicle", TCC_FUNC(_Func->RemovePlayerFromVehicle)); - s.AddSymbol("vcGetPlayerInVehicleStatus", TCC_FUNC(_Func->GetPlayerInVehicleStatus)); - s.AddSymbol("vcGetPlayerInVehicleSlot", TCC_FUNC(_Func->GetPlayerInVehicleSlot)); - s.AddSymbol("vcGetPlayerVehicleID", TCC_FUNC(_Func->GetPlayerVehicleID)); - s.AddSymbol("vcTogglePlayerControllable", TCC_FUNC(_Func->TogglePlayerControllable)); - s.AddSymbol("vcEnabledPlayerControllable", TCC_FUNC(_Func->EnabledPlayerControllable)); - s.AddSymbol("vcTogglePlayerDriveby", TCC_FUNC(_Func->TogglePlayerDriveby)); - s.AddSymbol("vcEnabledPlayerDriveby", TCC_FUNC(_Func->EnabledPlayerDriveby)); - s.AddSymbol("vcTogglePlayerWhiteScanlines", TCC_FUNC(_Func->TogglePlayerWhiteScanlines)); - s.AddSymbol("vcEnabledPlayerWhiteScanlines", TCC_FUNC(_Func->EnabledPlayerWhiteScanlines)); - s.AddSymbol("vcTogglePlayerGreenScanlines", TCC_FUNC(_Func->TogglePlayerGreenScanlines)); - s.AddSymbol("vcEnabledPlayerGreenScanlines", TCC_FUNC(_Func->EnabledPlayerGreenScanlines)); - s.AddSymbol("vcTogglePlayerWidescreen", TCC_FUNC(_Func->TogglePlayerWidescreen)); - s.AddSymbol("vcEnabledPlayerWidescreen", TCC_FUNC(_Func->EnabledPlayerWidescreen)); - s.AddSymbol("vcTogglePlayerShowMarkers", TCC_FUNC(_Func->TogglePlayerShowMarkers)); - s.AddSymbol("vcEnabledPlayerShowMarkers", TCC_FUNC(_Func->EnabledPlayerShowMarkers)); - s.AddSymbol("vcTogglePlayerAttackPriv", TCC_FUNC(_Func->TogglePlayerAttackPriv)); - s.AddSymbol("vcEnabledPlayerAttackPriv", TCC_FUNC(_Func->EnabledPlayerAttackPriv)); - s.AddSymbol("vcTogglePlayerHasMarker", TCC_FUNC(_Func->TogglePlayerHasMarker)); - s.AddSymbol("vcEnabledPlayerHasMarker", TCC_FUNC(_Func->EnabledPlayerHasMarker)); - s.AddSymbol("vcTogglePlayerChatTagsEnabled", TCC_FUNC(_Func->TogglePlayerChatTagsEnabled)); - s.AddSymbol("vcEnabledPlayerChatTags", TCC_FUNC(_Func->EnabledPlayerChatTags)); - s.AddSymbol("vcTogglePlayerDrunkEffects", TCC_FUNC(_Func->TogglePlayerDrunkEffects)); - s.AddSymbol("vcEnabledPlayerDrunkEffects", TCC_FUNC(_Func->EnabledPlayerDrunkEffects)); - s.AddSymbol("vcGivePlayerWeapon", TCC_FUNC(_Func->GivePlayerWeapon)); - s.AddSymbol("vcSetPlayerWeapon", TCC_FUNC(_Func->SetPlayerWeapon)); - s.AddSymbol("vcGetPlayerWeapon", TCC_FUNC(_Func->GetPlayerWeapon)); - s.AddSymbol("vcGetPlayerWeaponAmmo", TCC_FUNC(_Func->GetPlayerWeaponAmmo)); - s.AddSymbol("vcSetPlayerWeaponSlot", TCC_FUNC(_Func->SetPlayerWeaponSlot)); - s.AddSymbol("vcGetPlayerWeaponSlot", TCC_FUNC(_Func->GetPlayerWeaponSlot)); - s.AddSymbol("vcGetPlayerWeaponAtSlot", TCC_FUNC(_Func->GetPlayerWeaponAtSlot)); - s.AddSymbol("vcGetPlayerAmmoAtSlot", TCC_FUNC(_Func->GetPlayerAmmoAtSlot)); - s.AddSymbol("vcRemovePlayerWeapon", TCC_FUNC(_Func->RemovePlayerWeapon)); - s.AddSymbol("vcRemoveAllWeapons", TCC_FUNC(_Func->RemoveAllWeapons)); - s.AddSymbol("vcSetCameraPosition", TCC_FUNC(_Func->SetCameraPosition)); - s.AddSymbol("vcRestoreCamera", TCC_FUNC(_Func->RestoreCamera)); - s.AddSymbol("vcIsCameraLocked", TCC_FUNC(_Func->IsCameraLocked)); - s.AddSymbol("vcSetPlayerAnimation", TCC_FUNC(_Func->SetPlayerAnimation)); - s.AddSymbol("vcSetPlayerWantedLevel", TCC_FUNC(_Func->SetPlayerWantedLevel)); - s.AddSymbol("vcGetPlayerStandingOnVehicle", TCC_FUNC(_Func->GetPlayerStandingOnVehicle)); - s.AddSymbol("vcGetPlayerStandingOnObject", TCC_FUNC(_Func->GetPlayerStandingOnObject)); - s.AddSymbol("vcIsPlayerAway", TCC_FUNC(_Func->IsPlayerAway)); - s.AddSymbol("vcGetPlayerSpectateTarget", TCC_FUNC(_Func->GetPlayerSpectateTarget)); - s.AddSymbol("vcSetPlayerSpectateTarget", TCC_FUNC(_Func->SetPlayerSpectateTarget)); - s.AddSymbol("vcRedirectPlayerToServer", TCC_FUNC(_Func->RedirectPlayerToServer)); - s.AddSymbol("vcCreateVehicle", TCC_FUNC(_Func->CreateVehicle)); - s.AddSymbol("vcDeleteVehicle", TCC_FUNC(_Func->DeleteVehicle)); - s.AddSymbol("vcGetVehicleSyncSource", TCC_FUNC(_Func->GetVehicleSyncSource)); - s.AddSymbol("vcGetVehicleSyncType", TCC_FUNC(_Func->GetVehicleSyncType)); - s.AddSymbol("vcIsVehicleStreamedForPlayer", TCC_FUNC(_Func->IsVehicleStreamedForPlayer)); - s.AddSymbol("vcSetVehicleWorld", TCC_FUNC(_Func->SetVehicleWorld)); - s.AddSymbol("vcGetVehicleWorld", TCC_FUNC(_Func->GetVehicleWorld)); - s.AddSymbol("vcGetVehicleModel", TCC_FUNC(_Func->GetVehicleModel)); - s.AddSymbol("vcGetVehicleOccupant", TCC_FUNC(_Func->GetVehicleOccupant)); - s.AddSymbol("vcRespawnVehicle", TCC_FUNC(_Func->RespawnVehicle)); - s.AddSymbol("vcSetVehicleImmunityFlags", TCC_FUNC(_Func->SetVehicleImmunityFlags)); - s.AddSymbol("vcGetVehicleImmunityFlags", TCC_FUNC(_Func->GetVehicleImmunityFlags)); - s.AddSymbol("vcKillVehicle", TCC_FUNC(_Func->KillVehicle)); - s.AddSymbol("vcIsVehicleWrecked", TCC_FUNC(_Func->IsVehicleWrecked)); - s.AddSymbol("vcSetVehiclePos", TCC_FUNC(_Func->SetVehiclePos)); - s.AddSymbol("vcGetVehiclePos", TCC_FUNC(_Func->GetVehiclePos)); - s.AddSymbol("vcSetVehicleRot", TCC_FUNC(_Func->SetVehicleRot)); - s.AddSymbol("vcSetVehicleRotEuler", TCC_FUNC(_Func->SetVehicleRotEuler)); - s.AddSymbol("vcGetVehicleRot", TCC_FUNC(_Func->GetVehicleRot)); - s.AddSymbol("vcGetVehicleRotEuler", TCC_FUNC(_Func->GetVehicleRotEuler)); - s.AddSymbol("vcSetVehicleSpeed", TCC_FUNC(_Func->SetVehicleSpeed)); - s.AddSymbol("vcGetVehicleSpeed", TCC_FUNC(_Func->GetVehicleSpeed)); - s.AddSymbol("vcAddVehicleSpeed", TCC_FUNC(_Func->AddVehicleSpeed)); - s.AddSymbol("vcSetVehicleRelSpeed", TCC_FUNC(_Func->SetVehicleRelSpeed)); - s.AddSymbol("vcGetVehicleRelSpeed", TCC_FUNC(_Func->GetVehicleRelSpeed)); - s.AddSymbol("vcAddVehicleRelSpeed", TCC_FUNC(_Func->AddVehicleRelSpeed)); - s.AddSymbol("vcSetVehicleTurnSpeed", TCC_FUNC(_Func->SetVehicleTurnSpeed)); - s.AddSymbol("vcGetVehicleTurnSpeed", TCC_FUNC(_Func->GetVehicleTurnSpeed)); - s.AddSymbol("vcAddVehicleTurnSpeed", TCC_FUNC(_Func->AddVehicleTurnSpeed)); - s.AddSymbol("vcSetVehicleRelTurnSpeed", TCC_FUNC(_Func->SetVehicleRelTurnSpeed)); - s.AddSymbol("vcGetVehicleRelTurnSpeed", TCC_FUNC(_Func->GetVehicleRelTurnSpeed)); - s.AddSymbol("vcAddVehicleRelTurnSpeed", TCC_FUNC(_Func->AddVehicleRelTurnSpeed)); - s.AddSymbol("vcSetVehicleSpawnPos", TCC_FUNC(_Func->SetVehicleSpawnPos)); - s.AddSymbol("vcGetVehicleSpawnPos", TCC_FUNC(_Func->GetVehicleSpawnPos)); - s.AddSymbol("vcSetVehicleSpawnRot", TCC_FUNC(_Func->SetVehicleSpawnRot)); - s.AddSymbol("vcSetVehicleSpawnRotEuler", TCC_FUNC(_Func->SetVehicleSpawnRotEuler)); - s.AddSymbol("vcGetVehicleSpawnRot", TCC_FUNC(_Func->GetVehicleSpawnRot)); - s.AddSymbol("vcGetVehicleSpawnRotEuler", TCC_FUNC(_Func->GetVehicleSpawnRotEuler)); - s.AddSymbol("vcSetVehicleIdleRespawnTimer", TCC_FUNC(_Func->SetVehicleIdleRespawnTimer)); - s.AddSymbol("vcGetVehicleIdleRespawnTimer", TCC_FUNC(_Func->GetVehicleIdleRespawnTimer)); - s.AddSymbol("vcSetVehicleHealth", TCC_FUNC(_Func->SetVehicleHealth)); - s.AddSymbol("vcGetVehicleHealth", TCC_FUNC(_Func->GetVehicleHealth)); - s.AddSymbol("vcSetVehicleColour", TCC_FUNC(_Func->SetVehicleColour)); - s.AddSymbol("vcGetVehicleColour", TCC_FUNC(_Func->GetVehicleColour)); - s.AddSymbol("vcSetVehicleDoorsLocked", TCC_FUNC(_Func->SetVehicleDoorsLocked)); - s.AddSymbol("vcGetVehicleDoorsLocked", TCC_FUNC(_Func->GetVehicleDoorsLocked)); - s.AddSymbol("vcSetVehiclePartStatus", TCC_FUNC(_Func->SetVehiclePartStatus)); - s.AddSymbol("vcGetVehiclePartStatus", TCC_FUNC(_Func->GetVehiclePartStatus)); - s.AddSymbol("vcSetVehicleTyreStatus", TCC_FUNC(_Func->SetVehicleTyreStatus)); - s.AddSymbol("vcGetVehicleTyreStatus", TCC_FUNC(_Func->GetVehicleTyreStatus)); - s.AddSymbol("vcSetVehicleDamageData", TCC_FUNC(_Func->SetVehicleDamageData)); - s.AddSymbol("vcGetVehicleDamageData", TCC_FUNC(_Func->GetVehicleDamageData)); - s.AddSymbol("vcSetVehicleAlarm", TCC_FUNC(_Func->SetVehicleAlarm)); - s.AddSymbol("vcGetVehicleAlarm", TCC_FUNC(_Func->GetVehicleAlarm)); - s.AddSymbol("vcSetVehicleLights", TCC_FUNC(_Func->SetVehicleLights)); - s.AddSymbol("vcGetVehicleLights", TCC_FUNC(_Func->GetVehicleLights)); - s.AddSymbol("vcSetVehicleRadio", TCC_FUNC(_Func->SetVehicleRadio)); - s.AddSymbol("vcGetVehicleRadio", TCC_FUNC(_Func->GetVehicleRadio)); - s.AddSymbol("vcSetVehicleRadioLocked", TCC_FUNC(_Func->SetVehicleRadioLocked)); - s.AddSymbol("vcIsVehicleRadioLocked", TCC_FUNC(_Func->IsVehicleRadioLocked)); - s.AddSymbol("vcGetVehicleGhostState", TCC_FUNC(_Func->GetVehicleGhostState)); - s.AddSymbol("vcSetVehicleGhostState", TCC_FUNC(_Func->SetVehicleGhostState)); - s.AddSymbol("vcGetVehicleTurretRotation", TCC_FUNC(_Func->GetVehicleTurretRotation)); - s.AddSymbol("vcResetAllVehicleHandlings", TCC_FUNC(_Func->ResetAllVehicleHandlings)); - s.AddSymbol("vcExistsHandlingRule", TCC_FUNC(_Func->ExistsHandlingRule)); - s.AddSymbol("vcSetHandlingRule", TCC_FUNC(_Func->SetHandlingRule)); - s.AddSymbol("vcGetHandlingRule", TCC_FUNC(_Func->GetHandlingRule)); - s.AddSymbol("vcResetHandlingRule", TCC_FUNC(_Func->ResetHandlingRule)); - s.AddSymbol("vcResetHandling", TCC_FUNC(_Func->ResetHandling)); - s.AddSymbol("vcExistsInstHandlingRule", TCC_FUNC(_Func->ExistsInstHandlingRule)); - s.AddSymbol("vcSetInstHandlingRule", TCC_FUNC(_Func->SetInstHandlingRule)); - s.AddSymbol("vcGetInstHandlingRule", TCC_FUNC(_Func->GetInstHandlingRule)); - s.AddSymbol("vcResetInstHandlingRule", TCC_FUNC(_Func->ResetInstHandlingRule)); - s.AddSymbol("vcResetInstHandling", TCC_FUNC(_Func->ResetInstHandling)); - s.AddSymbol("vcCreatePickup", TCC_FUNC(_Func->CreatePickup)); - s.AddSymbol("vcDeletePickup", TCC_FUNC(_Func->DeletePickup)); - s.AddSymbol("vcIsPickupStreamedForPlayer", TCC_FUNC(_Func->IsPickupStreamedForPlayer)); - s.AddSymbol("vcSetPickupWorld", TCC_FUNC(_Func->SetPickupWorld)); - s.AddSymbol("vcGetPickupWorld", TCC_FUNC(_Func->GetPickupWorld)); - s.AddSymbol("vcPickupGetAlpha", TCC_FUNC(_Func->PickupGetAlpha)); - s.AddSymbol("vcPickupSetAlpha", TCC_FUNC(_Func->PickupSetAlpha)); - s.AddSymbol("vcPickupIsAutomatic", TCC_FUNC(_Func->PickupIsAutomatic)); - s.AddSymbol("vcPickupSetAutomatic", TCC_FUNC(_Func->PickupSetAutomatic)); - s.AddSymbol("vcSetPickupAutoTimer", TCC_FUNC(_Func->SetPickupAutoTimer)); - s.AddSymbol("vcGetPickupAutoTimer", TCC_FUNC(_Func->GetPickupAutoTimer)); - s.AddSymbol("vcPickupRefresh", TCC_FUNC(_Func->PickupRefresh)); - s.AddSymbol("vcPickupGetPos", TCC_FUNC(_Func->PickupGetPos)); - s.AddSymbol("vcPickupSetPos", TCC_FUNC(_Func->PickupSetPos)); - s.AddSymbol("vcPickupGetModel", TCC_FUNC(_Func->PickupGetModel)); - s.AddSymbol("vcPickupGetQuantity", TCC_FUNC(_Func->PickupGetQuantity)); - s.AddSymbol("vcCreateObject", TCC_FUNC(_Func->CreateObject)); - s.AddSymbol("vcDeleteObject", TCC_FUNC(_Func->DeleteObject)); - s.AddSymbol("vcIsObjectStreamedForPlayer", TCC_FUNC(_Func->IsObjectStreamedForPlayer)); - s.AddSymbol("vcGetObjectModel", TCC_FUNC(_Func->GetObjectModel)); - s.AddSymbol("vcSetObjectWorld", TCC_FUNC(_Func->SetObjectWorld)); - s.AddSymbol("vcGetObjectWorld", TCC_FUNC(_Func->GetObjectWorld)); - s.AddSymbol("vcSetObjectAlpha", TCC_FUNC(_Func->SetObjectAlpha)); - s.AddSymbol("vcGetObjectAlpha", TCC_FUNC(_Func->GetObjectAlpha)); - s.AddSymbol("vcMoveObjectTo", TCC_FUNC(_Func->MoveObjectTo)); - s.AddSymbol("vcMoveObjectBy", TCC_FUNC(_Func->MoveObjectBy)); - s.AddSymbol("vcSetObjectPos", TCC_FUNC(_Func->SetObjectPos)); - s.AddSymbol("vcGetObjectPos", TCC_FUNC(_Func->GetObjectPos)); - s.AddSymbol("vcRotObjectTo", TCC_FUNC(_Func->RotObjectTo)); - s.AddSymbol("vcRotObjectToEuler", TCC_FUNC(_Func->RotObjectToEuler)); - s.AddSymbol("vcRotObjectBy", TCC_FUNC(_Func->RotObjectBy)); - s.AddSymbol("vcRotObjectByEuler", TCC_FUNC(_Func->RotObjectByEuler)); - s.AddSymbol("vcGetObjectRot", TCC_FUNC(_Func->GetObjectRot)); - s.AddSymbol("vcGetObjectRotEuler", TCC_FUNC(_Func->GetObjectRotEuler)); - s.AddSymbol("vcSetObjectShotReport", TCC_FUNC(_Func->SetObjectShotReport)); - s.AddSymbol("vcIsObjectShotReport", TCC_FUNC(_Func->IsObjectShotReport)); - s.AddSymbol("vcSetObjectBumpReport", TCC_FUNC(_Func->SetObjectBumpReport)); - s.AddSymbol("vcIsObjectBumpReport", TCC_FUNC(_Func->IsObjectBumpReport)); - s.AddSymbol("vcToggleWallglitch", TCC_FUNC(_Func->ToggleWallglitch)); - s.AddSymbol("vcEnabledWallglitch", TCC_FUNC(_Func->EnabledWallglitch)); - s.AddSymbol("vcSetVehicleSiren", TCC_FUNC(_Func->SetVehicleSiren)); - s.AddSymbol("vcGetVehicleSiren", TCC_FUNC(_Func->GetVehicleSiren)); - s.AddSymbol("vcGetPlayerUID2", TCC_FUNC(_Func->GetPlayerUID2)); - s.AddSymbol("vcCreateCheckpoint", TCC_FUNC(_Func->CreateCheckpoint)); - s.AddSymbol("vcDeleteCheckpoint", TCC_FUNC(_Func->DeleteCheckpoint)); - s.AddSymbol("vcIsCheckpointStreamedForPlayer", TCC_FUNC(_Func->IsCheckpointStreamedForPlayer)); - s.AddSymbol("vcSetCheckpointWorld", TCC_FUNC(_Func->SetCheckpointWorld)); - s.AddSymbol("vcGetCheckpointWorld", TCC_FUNC(_Func->GetCheckpointWorld)); - s.AddSymbol("vcSetCheckpointColor", TCC_FUNC(_Func->SetCheckpointColor)); - s.AddSymbol("vcGetCheckpointColor", TCC_FUNC(_Func->GetCheckpointColor)); - s.AddSymbol("vcSetCheckpointPos", TCC_FUNC(_Func->SetCheckpointPos)); - s.AddSymbol("vcGetCheckpointPos", TCC_FUNC(_Func->GetCheckpointPos)); - s.AddSymbol("vcSetCheckpointRadius", TCC_FUNC(_Func->SetCheckpointRadius)); - s.AddSymbol("vcGetCheckpointRadius", TCC_FUNC(_Func->GetCheckpointRadius)); - s.AddSymbol("vcGetCheckpointOwner", TCC_FUNC(_Func->GetCheckpointOwner)); - s.AddSymbol("vcCreateSphere", TCC_FUNC(_Func->CreateSphere)); - s.AddSymbol("vcDeleteSphere", TCC_FUNC(_Func->DeleteSphere)); - s.AddSymbol("vcIsSphereStreamedForPlayer", TCC_FUNC(_Func->IsSphereStreamedForPlayer)); - s.AddSymbol("vcSetSphereWorld", TCC_FUNC(_Func->SetSphereWorld)); - s.AddSymbol("vcGetSphereWorld", TCC_FUNC(_Func->GetSphereWorld)); - s.AddSymbol("vcSetSphereColor", TCC_FUNC(_Func->SetSphereColor)); - s.AddSymbol("vcGetSphereColor", TCC_FUNC(_Func->GetSphereColor)); - s.AddSymbol("vcSetSpherePos", TCC_FUNC(_Func->SetSpherePos)); - s.AddSymbol("vcGetSpherePos", TCC_FUNC(_Func->GetSpherePos)); - s.AddSymbol("vcSetSphereRadius", TCC_FUNC(_Func->SetSphereRadius)); - s.AddSymbol("vcGetSphereRadius", TCC_FUNC(_Func->GetSphereRadius)); - s.AddSymbol("vcGetSphereOwner", TCC_FUNC(_Func->GetSphereOwner)); - // Squirrel Library - s.AddSymbol("sq_open", TCC_FUNC(_SqAPI->open)); - s.AddSymbol("sq_newthread", TCC_FUNC(_SqAPI->newthread)); - s.AddSymbol("sq_seterrorhandler", TCC_FUNC(_SqAPI->seterrorhandler)); - s.AddSymbol("sq_close", TCC_FUNC(_SqAPI->close)); - s.AddSymbol("sq_setforeignptr", TCC_FUNC(_SqAPI->setforeignptr)); - s.AddSymbol("sq_getforeignptr", TCC_FUNC(_SqAPI->getforeignptr)); - s.AddSymbol("sq_setsharedforeignptr", TCC_FUNC(_SqAPI->setsharedforeignptr)); - s.AddSymbol("sq_getsharedforeignptr", TCC_FUNC(_SqAPI->getsharedforeignptr)); - s.AddSymbol("sq_setvmreleasehook", TCC_FUNC(_SqAPI->setvmreleasehook)); - s.AddSymbol("sq_getvmreleasehook", TCC_FUNC(_SqAPI->getvmreleasehook)); - s.AddSymbol("sq_setsharedreleasehook", TCC_FUNC(_SqAPI->setsharedreleasehook)); - s.AddSymbol("sq_getsharedreleasehook", TCC_FUNC(_SqAPI->getsharedreleasehook)); - s.AddSymbol("sq_setprintfunc", TCC_FUNC(_SqAPI->setprintfunc)); - s.AddSymbol("sq_getprintfunc", TCC_FUNC(_SqAPI->getprintfunc)); - s.AddSymbol("sq_geterrorfunc", TCC_FUNC(_SqAPI->geterrorfunc)); - s.AddSymbol("sq_suspendvm", TCC_FUNC(_SqAPI->suspendvm)); - s.AddSymbol("sq_wakeupvm", TCC_FUNC(_SqAPI->wakeupvm)); - s.AddSymbol("sq_getvmstate", TCC_FUNC(_SqAPI->getvmstate)); - s.AddSymbol("sq_getversion", TCC_FUNC(_SqAPI->getversion)); - s.AddSymbol("sq_compile", TCC_FUNC(_SqAPI->compile)); - s.AddSymbol("sq_compilebuffer", TCC_FUNC(_SqAPI->compilebuffer)); - s.AddSymbol("sq_enabledebuginfo", TCC_FUNC(_SqAPI->enabledebuginfo)); - s.AddSymbol("sq_notifyallexceptions", TCC_FUNC(_SqAPI->notifyallexceptions)); - s.AddSymbol("sq_setcompilererrorhandler", TCC_FUNC(_SqAPI->setcompilererrorhandler)); - s.AddSymbol("sq_push", TCC_FUNC(_SqAPI->push)); - s.AddSymbol("sq_pop", TCC_FUNC(_SqAPI->pop)); - s.AddSymbol("sq_poptop", TCC_FUNC(_SqAPI->poptop)); - s.AddSymbol("sq_remove", TCC_FUNC(_SqAPI->remove)); - s.AddSymbol("sq_gettop", TCC_FUNC(_SqAPI->gettop)); - s.AddSymbol("sq_settop", TCC_FUNC(_SqAPI->settop)); - s.AddSymbol("sq_reservestack", TCC_FUNC(_SqAPI->reservestack)); - s.AddSymbol("sq_cmp", TCC_FUNC(_SqAPI->cmp)); - s.AddSymbol("sq_move", TCC_FUNC(_SqAPI->move)); - s.AddSymbol("sq_newuserdata", TCC_FUNC(_SqAPI->newuserdata)); - s.AddSymbol("sq_newtable", TCC_FUNC(_SqAPI->newtable)); - s.AddSymbol("sq_newtableex", TCC_FUNC(_SqAPI->newtableex)); - s.AddSymbol("sq_newarray", TCC_FUNC(_SqAPI->newarray)); - s.AddSymbol("sq_newclosure", TCC_FUNC(_SqAPI->newclosure)); - s.AddSymbol("sq_setparamscheck", TCC_FUNC(_SqAPI->setparamscheck)); - s.AddSymbol("sq_bindenv", TCC_FUNC(_SqAPI->bindenv)); - s.AddSymbol("sq_setclosureroot", TCC_FUNC(_SqAPI->setclosureroot)); - s.AddSymbol("sq_getclosureroot", TCC_FUNC(_SqAPI->getclosureroot)); - s.AddSymbol("sq_pushstring", TCC_FUNC(_SqAPI->pushstring)); - s.AddSymbol("sq_pushfloat", TCC_FUNC(_SqAPI->pushfloat)); - s.AddSymbol("sq_pushinteger", TCC_FUNC(_SqAPI->pushinteger)); - s.AddSymbol("sq_pushbool", TCC_FUNC(_SqAPI->pushbool)); - s.AddSymbol("sq_pushuserpointer", TCC_FUNC(_SqAPI->pushuserpointer)); - s.AddSymbol("sq_pushnull", TCC_FUNC(_SqAPI->pushnull)); - s.AddSymbol("sq_pushthread", TCC_FUNC(_SqAPI->pushthread)); - s.AddSymbol("sq_gettype", TCC_FUNC(_SqAPI->gettype)); - s.AddSymbol("sq_typeof", TCC_FUNC(_SqAPI->typeof_)); - s.AddSymbol("sq_getsize", TCC_FUNC(_SqAPI->getsize)); - s.AddSymbol("sq_gethash", TCC_FUNC(_SqAPI->gethash)); - s.AddSymbol("sq_getbase", TCC_FUNC(_SqAPI->getbase)); - s.AddSymbol("sq_instanceof", TCC_FUNC(_SqAPI->instanceof)); - s.AddSymbol("sq_tostring", TCC_FUNC(_SqAPI->tostring)); - s.AddSymbol("sq_tobool", TCC_FUNC(_SqAPI->tobool)); - s.AddSymbol("sq_getstring", TCC_FUNC(_SqAPI->getstring)); - s.AddSymbol("sq_getinteger", TCC_FUNC(_SqAPI->getinteger)); - s.AddSymbol("sq_getfloat", TCC_FUNC(_SqAPI->getfloat)); - s.AddSymbol("sq_getbool", TCC_FUNC(_SqAPI->getbool)); - s.AddSymbol("sq_getthread", TCC_FUNC(_SqAPI->getthread)); - s.AddSymbol("sq_getuserpointer", TCC_FUNC(_SqAPI->getuserpointer)); - s.AddSymbol("sq_getuserdata", TCC_FUNC(_SqAPI->getuserdata)); - s.AddSymbol("sq_settypetag", TCC_FUNC(_SqAPI->settypetag)); - s.AddSymbol("sq_gettypetag", TCC_FUNC(_SqAPI->gettypetag)); - s.AddSymbol("sq_setreleasehook", TCC_FUNC(_SqAPI->setreleasehook)); - s.AddSymbol("sq_getreleasehook", TCC_FUNC(_SqAPI->getreleasehook)); - s.AddSymbol("sq_getscratchpad", TCC_FUNC(_SqAPI->getscratchpad)); - s.AddSymbol("sq_getfunctioninfo", TCC_FUNC(_SqAPI->getfunctioninfo)); - s.AddSymbol("sq_getclosureinfo", TCC_FUNC(_SqAPI->getclosureinfo)); - s.AddSymbol("sq_getclosurename", TCC_FUNC(_SqAPI->getclosurename)); - s.AddSymbol("sq_setnativeclosurename", TCC_FUNC(_SqAPI->setnativeclosurename)); - s.AddSymbol("sq_setinstanceup", TCC_FUNC(_SqAPI->setinstanceup)); - s.AddSymbol("sq_getinstanceup", TCC_FUNC(_SqAPI->getinstanceup)); - s.AddSymbol("sq_setclassudsize", TCC_FUNC(_SqAPI->setclassudsize)); - s.AddSymbol("sq_newclass", TCC_FUNC(_SqAPI->newclass)); - s.AddSymbol("sq_createinstance", TCC_FUNC(_SqAPI->createinstance)); - s.AddSymbol("sq_setattributes", TCC_FUNC(_SqAPI->setattributes)); - s.AddSymbol("sq_getattributes", TCC_FUNC(_SqAPI->getattributes)); - s.AddSymbol("sq_getclass", TCC_FUNC(_SqAPI->getclass)); - s.AddSymbol("sq_weakref", TCC_FUNC(_SqAPI->weakref)); - s.AddSymbol("sq_getdefaultdelegate", TCC_FUNC(_SqAPI->getdefaultdelegate)); - s.AddSymbol("sq_getmemberhandle", TCC_FUNC(_SqAPI->getmemberhandle)); - s.AddSymbol("sq_getbyhandle", TCC_FUNC(_SqAPI->getbyhandle)); - s.AddSymbol("sq_setbyhandle", TCC_FUNC(_SqAPI->setbyhandle)); - s.AddSymbol("sq_pushroottable", TCC_FUNC(_SqAPI->pushroottable)); - s.AddSymbol("sq_pushregistrytable", TCC_FUNC(_SqAPI->pushregistrytable)); - s.AddSymbol("sq_pushconsttable", TCC_FUNC(_SqAPI->pushconsttable)); - s.AddSymbol("sq_setroottable", TCC_FUNC(_SqAPI->setroottable)); - s.AddSymbol("sq_setconsttable", TCC_FUNC(_SqAPI->setconsttable)); - s.AddSymbol("sq_newslot", TCC_FUNC(_SqAPI->newslot)); - s.AddSymbol("sq_deleteslot", TCC_FUNC(_SqAPI->deleteslot)); - s.AddSymbol("sq_set", TCC_FUNC(_SqAPI->set)); - s.AddSymbol("sq_get", TCC_FUNC(_SqAPI->get)); - s.AddSymbol("sq_rawget", TCC_FUNC(_SqAPI->rawget)); - s.AddSymbol("sq_rawset", TCC_FUNC(_SqAPI->rawset)); - s.AddSymbol("sq_rawdeleteslot", TCC_FUNC(_SqAPI->rawdeleteslot)); - s.AddSymbol("sq_newmember", TCC_FUNC(_SqAPI->newmember)); - s.AddSymbol("sq_rawnewmember", TCC_FUNC(_SqAPI->rawnewmember)); - s.AddSymbol("sq_arrayappend", TCC_FUNC(_SqAPI->arrayappend)); - s.AddSymbol("sq_arraypop", TCC_FUNC(_SqAPI->arraypop)); - s.AddSymbol("sq_arrayresize", TCC_FUNC(_SqAPI->arrayresize)); - s.AddSymbol("sq_arrayreverse", TCC_FUNC(_SqAPI->arrayreverse)); - s.AddSymbol("sq_arrayremove", TCC_FUNC(_SqAPI->arrayremove)); - s.AddSymbol("sq_arrayinsert", TCC_FUNC(_SqAPI->arrayinsert)); - s.AddSymbol("sq_setdelegate", TCC_FUNC(_SqAPI->setdelegate)); - s.AddSymbol("sq_getdelegate", TCC_FUNC(_SqAPI->getdelegate)); - s.AddSymbol("sq_clone", TCC_FUNC(_SqAPI->clone)); - s.AddSymbol("sq_setfreevariable", TCC_FUNC(_SqAPI->setfreevariable)); - s.AddSymbol("sq_next", TCC_FUNC(_SqAPI->next)); - s.AddSymbol("sq_getweakrefval", TCC_FUNC(_SqAPI->getweakrefval)); - s.AddSymbol("sq_clear", TCC_FUNC(_SqAPI->clear)); - s.AddSymbol("sq_call", TCC_FUNC(_SqAPI->call)); - s.AddSymbol("sq_resume", TCC_FUNC(_SqAPI->resume)); - s.AddSymbol("sq_getlocal", TCC_FUNC(_SqAPI->getlocal)); - s.AddSymbol("sq_getcallee", TCC_FUNC(_SqAPI->getcallee)); - s.AddSymbol("sq_getfreevariable", TCC_FUNC(_SqAPI->getfreevariable)); - s.AddSymbol("sq_throwerror", TCC_FUNC(_SqAPI->throwerror)); - s.AddSymbol("sq_throwobject", TCC_FUNC(_SqAPI->throwobject)); - s.AddSymbol("sq_reseterror", TCC_FUNC(_SqAPI->reseterror)); - s.AddSymbol("sq_getlasterror", TCC_FUNC(_SqAPI->getlasterror)); - s.AddSymbol("sq_getstackobj", TCC_FUNC(_SqAPI->getstackobj)); - s.AddSymbol("sq_pushobject", TCC_FUNC(_SqAPI->pushobject)); - s.AddSymbol("sq_addref", TCC_FUNC(_SqAPI->addref)); - s.AddSymbol("sq_release", TCC_FUNC(_SqAPI->release)); - s.AddSymbol("sq_getrefcount", TCC_FUNC(_SqAPI->getrefcount)); - s.AddSymbol("sq_resetobject", TCC_FUNC(_SqAPI->resetobject)); - s.AddSymbol("sq_objtostring", TCC_FUNC(_SqAPI->objtostring)); - s.AddSymbol("sq_objtobool", TCC_FUNC(_SqAPI->objtobool)); - s.AddSymbol("sq_objtointeger", TCC_FUNC(_SqAPI->objtointeger)); - s.AddSymbol("sq_objtofloat", TCC_FUNC(_SqAPI->objtofloat)); - s.AddSymbol("sq_objtouserpointer", TCC_FUNC(_SqAPI->objtouserpointer)); - s.AddSymbol("sq_getobjtypetag", TCC_FUNC(_SqAPI->getobjtypetag)); - s.AddSymbol("sq_getvmrefcount", TCC_FUNC(_SqAPI->getvmrefcount)); - s.AddSymbol("sq_collectgarbage", TCC_FUNC(_SqAPI->collectgarbage)); - s.AddSymbol("sq_resurrectunreachable", TCC_FUNC(_SqAPI->resurrectunreachable)); - s.AddSymbol("sq_writeclosure", TCC_FUNC(_SqAPI->writeclosure)); - s.AddSymbol("sq_readclosure", TCC_FUNC(_SqAPI->readclosure)); - s.AddSymbol("sq_malloc", TCC_FUNC(_SqAPI->malloc)); - s.AddSymbol("sq_realloc", TCC_FUNC(_SqAPI->realloc)); - s.AddSymbol("sq_free", TCC_FUNC(_SqAPI->free)); - s.AddSymbol("sq_stackinfos", TCC_FUNC(_SqAPI->stackinfos)); - s.AddSymbol("sq_setdebughook", TCC_FUNC(_SqAPI->setdebughook)); - s.AddSymbol("sq_setnativedebughook", TCC_FUNC(_SqAPI->setnativedebughook)); - s.AddSymbol("sqstd_loadfile", TCC_FUNC(_SqAPI->loadfile)); - s.AddSymbol("sqstd_dofile", TCC_FUNC(_SqAPI->dofile)); - s.AddSymbol("sqstd_writeclosuretofile", TCC_FUNC(_SqAPI->writeclosuretofile)); - s.AddSymbol("sqstd_createblob", TCC_FUNC(_SqAPI->createblob)); - s.AddSymbol("sqstd_getblob", TCC_FUNC(_SqAPI->getblob)); - s.AddSymbol("sqstd_getblobsize", TCC_FUNC(_SqAPI->getblobsize)); - s.AddSymbol("sqstd_format", TCC_FUNC(_SqAPI->format)); - // Host Module - s.AddSymbol("SqMod_GetSquirrelVM", TCC_FUNC(_SqMod->GetSquirrelVM)); - s.AddSymbol("SqMod_LogDbg", TCC_FUNC(_SqMod->LogDbg)); - s.AddSymbol("SqMod_LogUsr", TCC_FUNC(_SqMod->LogUsr)); - s.AddSymbol("SqMod_LogScs", TCC_FUNC(_SqMod->LogScs)); - s.AddSymbol("SqMod_LogInf", TCC_FUNC(_SqMod->LogInf)); - s.AddSymbol("SqMod_LogWrn", TCC_FUNC(_SqMod->LogWrn)); - s.AddSymbol("SqMod_LogErr", TCC_FUNC(_SqMod->LogErr)); - s.AddSymbol("SqMod_LogFtl", TCC_FUNC(_SqMod->LogFtl)); - s.AddSymbol("SqMod_LogSDbg", TCC_FUNC(_SqMod->LogSDbg)); - s.AddSymbol("SqMod_LogSUsr", TCC_FUNC(_SqMod->LogSUsr)); - s.AddSymbol("SqMod_LogSScs", TCC_FUNC(_SqMod->LogSScs)); - s.AddSymbol("SqMod_LogSInf", TCC_FUNC(_SqMod->LogSInf)); - s.AddSymbol("SqMod_LogSWrn", TCC_FUNC(_SqMod->LogSWrn)); - s.AddSymbol("SqMod_LogSErr", TCC_FUNC(_SqMod->LogSErr)); - s.AddSymbol("SqMod_LogSFtl", TCC_FUNC(_SqMod->LogSFtl)); - s.AddSymbol("SqMod_LoadScript", TCC_FUNC(_SqMod->LoadScript)); - s.AddSymbol("SqMod_GetSLongValue", TCC_FUNC(_SqMod->GetSLongValue)); - s.AddSymbol("SqMod_PushSLongObject", TCC_FUNC(_SqMod->PushSLongObject)); - s.AddSymbol("SqMod_GetULongValue", TCC_FUNC(_SqMod->GetULongValue)); - s.AddSymbol("SqMod_PushULongObject", TCC_FUNC(_SqMod->PushULongObject)); - s.AddSymbol("SqMod_GetCurrentSysTime", TCC_FUNC(_SqMod->GetCurrentSysTime)); - s.AddSymbol("SqMod_GetEpochTimeMicro", TCC_FUNC(_SqMod->GetEpochTimeMicro)); - s.AddSymbol("SqMod_GetEpochTimeMilli", TCC_FUNC(_SqMod->GetEpochTimeMilli)); - s.AddSymbol("SqMod_GetTimestamp", TCC_FUNC(_SqMod->GetTimestamp)); - s.AddSymbol("SqMod_PushTimestamp", TCC_FUNC(_SqMod->PushTimestamp)); - -} - -} // Namespace:: SqMod diff --git a/modules/tcc/Common.cpp b/modules/tcc/Common.cpp deleted file mode 100644 index 5d77f720..00000000 --- a/modules/tcc/Common.cpp +++ /dev/null @@ -1,1483 +0,0 @@ -// ------------------------------------------------------------------------------------------------ -#include "Common.hpp" -#include "Module.hpp" - -// ------------------------------------------------------------------------------------------------ -#include -#include - -// ------------------------------------------------------------------------------------------------ -#include - -// ------------------------------------------------------------------------------------------------ -#include - -// ------------------------------------------------------------------------------------------------ -namespace SqMod { - -// ------------------------------------------------------------------------------------------------ -static SQChar g_Buffer[4096]; // Common buffer to reduce memory allocations. - -// ------------------------------------------------------------------------------------------------ -StateHnd::Handles StateHnd::s_Handles; - -// ------------------------------------------------------------------------------------------------ -SStr GetTempBuff() -{ - return g_Buffer; -} - -// ------------------------------------------------------------------------------------------------ -Uint32 GetTempBuffSize() -{ - return sizeof(g_Buffer); -} - -// ------------------------------------------------------------------------------------------------ -void SqThrowF(CSStr str, ...) -{ - // Initialize the argument list - va_list args; - va_start (args, str); - // Write the requested contents - if (std::vsnprintf(g_Buffer, sizeof(g_Buffer), str, args) < 0) - { - std::strcpy(g_Buffer, "Unknown error has occurred"); - } - // Release the argument list - va_end(args); - // Throw the exception with the resulted message - throw Sqrat::Exception(g_Buffer); -} - -// ------------------------------------------------------------------------------------------------ -CSStr FmtStr(CSStr str, ...) -{ - // Initialize the argument list - va_list args; - va_start (args, str); - // Write the requested contents - if (std::vsnprintf(g_Buffer, sizeof(g_Buffer), str, args) < 0) - { - g_Buffer[0] = 0; // Make sure the string is terminated - } - // Release the argument list - va_end(args); - // Return the data from the buffer - return g_Buffer; -} - -// ------------------------------------------------------------------------------------------------ -StackGuard::StackGuard() - : m_VM(_SqVM), m_Top(sq_gettop(m_VM)) -{ - /* ... */ -} - -// ------------------------------------------------------------------------------------------------ -StackGuard::StackGuard(HSQUIRRELVM vm) - : m_VM(vm), m_Top(sq_gettop(vm)) -{ - /* ... */ -} - -// ------------------------------------------------------------------------------------------------ -StackGuard::~StackGuard() -{ - sq_pop(m_VM, sq_gettop(m_VM) - m_Top); -} - -// -------------------------------------------------------------------------------------------- -StackStrF::StackStrF(HSQUIRRELVM vm, SQInteger idx, bool fmt) - : mPtr(nullptr) - , mLen(-1) - , mRes(SQ_OK) - , mObj() - , mVM(vm) -{ - const Int32 top = sq_gettop(vm); - // Reset the converted value object - sq_resetobject(&mObj); - // Was the string or value specified? - if (top <= (idx - 1)) - { - mRes = sq_throwerror(vm, "Missing string or value"); - } - // Do we have enough values to call the format function and are we allowed to? - else if (top > idx && fmt) - { - // Pointer to the generated string - SStr str = nullptr; - // Attempt to generate the specified string format - mRes = sqstd_format(vm, idx, &mLen, &str); - // Did the format succeeded but ended up with a null string pointer? - if (SQ_SUCCEEDED(mRes) && !str) - { - mRes = sq_throwerror(vm, "Unable to generate the string"); - } - else - { - mPtr = const_cast< CSStr >(str); - } - } - // Is the value on the stack an actual string? - else if (sq_gettype(vm, idx) == OT_STRING) - { - // Obtain a reference to the string object - mRes = sq_getstackobj(vm, idx, &mObj); - // Could we retrieve the object from the stack? - if (SQ_SUCCEEDED(mRes)) - { - // Keep a strong reference to the object - sq_addref(vm, &mObj); - // Attempt to retrieve the string value from the stack - mRes = sq_getstring(vm, idx, &mPtr); - } - // Did the retrieval succeeded but ended up with a null string pointer? - if (SQ_SUCCEEDED(mRes) && !mPtr) - { - mRes = sq_throwerror(vm, "Unable to retrieve the string"); - } - } - // We have to try and convert it to string - else - { - // Attempt to convert the value from the stack to a string - mRes = sq_tostring(vm, idx); - // Could we convert the specified value to string? - if (SQ_SUCCEEDED(mRes)) - { - // Obtain a reference to the resulted object - mRes = sq_getstackobj(vm, -1, &mObj); - // Could we retrieve the object from the stack? - if (SQ_SUCCEEDED(mRes)) - { - // Keep a strong reference to the object - sq_addref(vm, &mObj); - // Attempt to obtain the string pointer - mRes = sq_getstring(vm, -1, &mPtr); - } - } - // Pop a value from the stack regardless of the result - sq_pop(vm, 1); - // Did the retrieval succeeded but ended up with a null string pointer? - if (SQ_SUCCEEDED(mRes) && !mPtr) - { - mRes = sq_throwerror(vm, "Unable to retrieve the value"); - } - } -} - -// ------------------------------------------------------------------------------------------------ -StackStrF::~StackStrF() -{ - if (mVM && !sq_isnull(mObj)) - { - sq_release(mVM, &mObj); - } -} - -// ------------------------------------------------------------------------------------------------ -void StateHnd::ErrorHandler(void * opaque, const char * msg) -{ - // Cast the opaque pointer when created to the associated handle instance - Handle * hnd = reinterpret_cast< Handle * >(opaque); - // Is there a valid handle instance associated? - if (!hnd) - { - // Just drop the message to the regular error output - OutputError(msg); - } - // Is there a custom error handler assigned by the script? - else if (hnd->mErrorHandler.IsNull()) - { - // Are we allowed to handle the error in absence of this handler? - if (!(hnd->mNoErrors)) - { - // Just drop the message to the regular error output - OutputError(msg); - } - } - else - { - // Attempt to forward the error to the script callback - try - { - hnd->mErrorHandler.Execute(msg); - } - catch (const Sqrat::Exception & e) - { - OutputError("Error handler failed: %s", e.Message().c_str()); - } - catch (...) - { - OutputError("Error handler failed for unknown reasons"); - } - } -} - -// ------------------------------------------------------------------------------------------------ -StateHnd::Handle::Handle(Counter counter, CSStr name) - : mPtr(tcc_new()) - , mRef(counter) - , mOnInitServer(nullptr) - , mOnShutdownServer(nullptr) - , mOnFrame(nullptr) - , mOnPlayerConnect(nullptr) - , mOnPlayerDisconnect(nullptr) - , mOnPlayerBeginTyping(nullptr) - , mOnPlayerEndTyping(nullptr) - , mOnPlayerRequestClass(nullptr) - , mOnPlayerRequestSpawn(nullptr) - , mOnPlayerSpawn(nullptr) - , mOnPlayerDeath(nullptr) - , mOnPlayerUpdate(nullptr) - , mOnPlayerRequestEnter(nullptr) - , mOnPlayerEnterVehicle(nullptr) - , mOnPlayerExitVehicle(nullptr) - , mOnPlayerNameChange(nullptr) - , mOnPlayerStateChange(nullptr) - , mOnPlayerActionChange(nullptr) - , mOnPlayerOnFireChange(nullptr) - , mOnPlayerCrouchChange(nullptr) - , mOnPlayerGameKeysChange(nullptr) - , mOnPickupClaimPicked(nullptr) - , mOnPickupPickedUp(nullptr) - , mOnPickupRespawn(nullptr) - , mOnVehicleUpdate(nullptr) - , mOnVehicleExplode(nullptr) - , mOnVehicleRespawn(nullptr) - , mOnObjectShot(nullptr) - , mOnObjectBump(nullptr) - , mOnPublicMessage(nullptr) - , mOnCommandMessage(nullptr) - , mOnPrivateMessage(nullptr) - , mOnInternalCommand(nullptr) - , mOnLoginAttempt(nullptr) - , mOnEntityPoolChange(nullptr) - , mOnKeyBindDown(nullptr) - , mOnKeyBindUp(nullptr) - , mOnPlayerAwayChange(nullptr) - , mOnPlayerSpectate(nullptr) - , mOnPlayerCrashReport(nullptr) - , mOnServerPerformanceReport(nullptr) - , mOnCheckpointEntered(nullptr) - , mOnCheckpointExited(nullptr) - , mOnSphereEntered(nullptr) - , mOnSphereExited(nullptr) - , mRelocated(false) - , mNoErrors(false) - , mErrorHandler() - , mName(name ? name : _SC("")) -{ - // See if the state could be created - if (!mPtr) - { - STHROWF("Unable to create compiler state"); - } - else - { - // Make the state output data to memory - tcc_set_output_type(mPtr, TCC_OUTPUT_MEMORY); - // Assign our error function - tcc_set_error_func(mPtr, this, &StateHnd::ErrorHandler); - // Receive events - Remember(this); - } -} - -// ------------------------------------------------------------------------------------------------ -StateHnd::Handle::~Handle() -{ - // Stop receiving events - Forget(this); - // Do we have any state to destroy? - if (mPtr != nullptr) - { - // Release the state resources - tcc_delete(mPtr); - } - // Release the error callback - mErrorHandler.ReleaseGently(); -} - -// ------------------------------------------------------------------------------------------------ -void StateHnd::Validate() const -{ - if (!m_Hnd || !(m_Hnd->mPtr)) - { - STHROWF("Invalid TCC state reference"); - } -} - -// ------------------------------------------------------------------------------------------------ -void StateHnd::PushSymbol(CSStr name, const void * value) -{ - // Validate the managed handle - Validate(); - // Perform the requested operation - tcc_add_symbol(m_Hnd->mPtr, name, value); -} - -// ------------------------------------------------------------------------------------------------ -void * StateHnd::PullSymbol(CSStr name) const -{ - // Validate the managed handle - Validate(); - // Return the requested information - return tcc_get_symbol(m_Hnd->mPtr, name); -} - -// ------------------------------------------------------------------------------------------------ -void StateHnd::SetOptions(CSStr opt) const -{ - // Validate the managed handle - Validate(); - // Perform the requested operation - tcc_set_options(m_Hnd->mPtr, opt); -} - -// ------------------------------------------------------------------------------------------------ -void StateHnd::DefineSymbol(CSStr sym, CSStr value) const -{ - // Validate the managed handle - Validate(); - // Perform the requested operation - tcc_define_symbol(m_Hnd->mPtr, sym, value); -} - -// ------------------------------------------------------------------------------------------------ -void StateHnd::UndefineSymbol(CSStr sym) const -{ - // Validate the managed handle - Validate(); - // Perform the requested operation - tcc_undefine_symbol(m_Hnd->mPtr, sym); -} - -// ------------------------------------------------------------------------------------------------ -void StateHnd::AddIncludePath(CSStr path) const -{ - // Validate the managed handle - Validate(); - // Perform the requested operation - tcc_add_include_path(m_Hnd->mPtr, path); -} - -// ------------------------------------------------------------------------------------------------ -void StateHnd::AddSysIncludePath(CSStr path) const -{ - // Validate the managed handle - Validate(); - // Perform the requested operation - tcc_add_sysinclude_path(m_Hnd->mPtr, path); -} - -// ------------------------------------------------------------------------------------------------ -void StateHnd::SetLibPath(CSStr path) const -{ - // Validate the managed handle - Validate(); - // Perform the requested operation - tcc_set_lib_path(m_Hnd->mPtr, path); -} - -// ------------------------------------------------------------------------------------------------ -void StateHnd::AddLibraryPath(CSStr path) const -{ - // Validate the managed handle - Validate(); - // Perform the requested operation - tcc_add_library_path(m_Hnd->mPtr, path); -} - -// ------------------------------------------------------------------------------------------------ -void StateHnd::AddLibrary(CSStr name) const -{ - // Validate the managed handle - Validate(); - // Perform the requested operation - if (tcc_add_library(m_Hnd->mPtr, name) < 0) - { - STHROWF("Unable to add library: '%s'", name); - } -} - -// ------------------------------------------------------------------------------------------------ -void StateHnd::CompileString(CSStr str) const -{ - // Validate the managed handle - Validate(); - // Perform the requested operation - if (tcc_compile_string(m_Hnd->mPtr, str) < 0) - { - STHROWF("Unable to compile string"); - } -} - -// ------------------------------------------------------------------------------------------------ -void StateHnd::AddFile(CSStr filename, Int32 type) const -{ - // Validate the managed handle - Validate(); - // Perform the requested operation - if (tcc_add_file(m_Hnd->mPtr, filename, type) < 0) - { - STHROWF("Unable to add file: '%s'", filename); - } -} - -// ------------------------------------------------------------------------------------------------ -void StateHnd::Relocate() const -{ - // Validate the managed handle - Validate(); - // Make sure the state was not already relocated - if (m_Hnd->mRelocated) - { - STHROWF("Compiler state was already relocated"); - } - // Attempt to relocate the state - else if (tcc_relocate(m_Hnd->mPtr, TCC_RELOCATE_AUTO) < 0) - { - STHROWF("Unable to relocate compiler state"); - } - // Specify that the compiler was relocated - m_Hnd->mRelocated = true; - // Retrieve the event callbacks - m_Hnd->mOnInitServer = GetSymbol< SDK_OnInitServer >("onInitServer"); - m_Hnd->mOnShutdownServer = GetSymbol< SDK_OnShutdownServer >("onShutdownServer"); - m_Hnd->mOnFrame = GetSymbol< SDK_OnFrame >("onFrame"); - m_Hnd->mOnPlayerConnect = GetSymbol< SDK_OnPlayerConnect >("onPlayerConnect"); - m_Hnd->mOnPlayerDisconnect = GetSymbol< SDK_OnPlayerDisconnect >("onPlayerDisconnect"); - m_Hnd->mOnPlayerBeginTyping = GetSymbol< SDK_OnPlayerBeginTyping >("onPlayerBeginTyping"); - m_Hnd->mOnPlayerEndTyping = GetSymbol< SDK_OnPlayerEndTyping >("onPlayerEndTyping"); - m_Hnd->mOnPlayerRequestClass = GetSymbol< SDK_OnPlayerRequestClass >("onPlayerRequestClass"); - m_Hnd->mOnPlayerRequestSpawn = GetSymbol< SDK_OnPlayerRequestSpawn >("onPlayerRequestSpawn"); - m_Hnd->mOnPlayerSpawn = GetSymbol< SDK_OnPlayerSpawn >("onPlayerSpawn"); - m_Hnd->mOnPlayerDeath = GetSymbol< SDK_OnPlayerDeath >("onPlayerDeath"); - m_Hnd->mOnPlayerUpdate = GetSymbol< SDK_OnPlayerUpdate >("onPlayerUpdate"); - m_Hnd->mOnPlayerRequestEnter = GetSymbol< SDK_OnPlayerRequestEnter >("onPlayerRequestEnter"); - m_Hnd->mOnPlayerEnterVehicle = GetSymbol< SDK_OnPlayerEnterVehicle >("onPlayerEnterVehicle"); - m_Hnd->mOnPlayerExitVehicle = GetSymbol< SDK_OnPlayerExitVehicle >("onPlayerExitVehicle"); - m_Hnd->mOnPlayerNameChange = GetSymbol< SDK_OnPlayerNameChange >("onPlayerNameChange"); - m_Hnd->mOnPlayerStateChange = GetSymbol< SDK_OnPlayerStateChange >("onPlayerStateChange"); - m_Hnd->mOnPlayerActionChange = GetSymbol< SDK_OnPlayerActionChange >("onPlayerActionChange"); - m_Hnd->mOnPlayerOnFireChange = GetSymbol< SDK_OnPlayerOnFireChange >("onPlayerOnFireChange"); - m_Hnd->mOnPlayerCrouchChange = GetSymbol< SDK_OnPlayerCrouchChange >("onPlayerCrouchChange"); - m_Hnd->mOnPlayerGameKeysChange = GetSymbol< SDK_OnPlayerGameKeysChange >("onPlayerGameKeysChange"); - m_Hnd->mOnPickupClaimPicked = GetSymbol< SDK_OnPickupClaimPicked >("onPickupClaimPicked"); - m_Hnd->mOnPickupPickedUp = GetSymbol< SDK_OnPickupPickedUp >("onPickupPickedUp"); - m_Hnd->mOnPickupRespawn = GetSymbol< SDK_OnPickupRespawn >("onPickupRespawn"); - m_Hnd->mOnVehicleUpdate = GetSymbol< SDK_OnVehicleUpdate >("onVehicleUpdate"); - m_Hnd->mOnVehicleExplode = GetSymbol< SDK_OnVehicleExplode >("onVehicleExplode"); - m_Hnd->mOnVehicleRespawn = GetSymbol< SDK_OnVehicleRespawn >("onVehicleRespawn"); - m_Hnd->mOnObjectShot = GetSymbol< SDK_OnObjectShot >("onObjectShot"); - m_Hnd->mOnObjectBump = GetSymbol< SDK_OnObjectBump >("onObjectBump"); - m_Hnd->mOnPublicMessage = GetSymbol< SDK_OnPublicMessage >("onPublicMessage"); - m_Hnd->mOnCommandMessage = GetSymbol< SDK_OnCommandMessage >("onCommandMessage"); - m_Hnd->mOnPrivateMessage = GetSymbol< SDK_OnPrivateMessage >("onPrivateMessage"); - m_Hnd->mOnInternalCommand = GetSymbol< SDK_OnInternalCommand >("onInternalCommand"); - m_Hnd->mOnLoginAttempt = GetSymbol< SDK_OnLoginAttempt >("onLoginAttempt"); - m_Hnd->mOnEntityPoolChange = GetSymbol< SDK_OnEntityPoolChange >("onEntityPoolChange"); - m_Hnd->mOnKeyBindDown = GetSymbol< SDK_OnKeyBindDown >("onKeyBindDown"); - m_Hnd->mOnKeyBindUp = GetSymbol< SDK_OnKeyBindUp >("onKeyBindUp"); - m_Hnd->mOnPlayerAwayChange = GetSymbol< SDK_OnPlayerAwayChange >("onPlayerAwayChange"); - m_Hnd->mOnPlayerSpectate = GetSymbol< SDK_OnPlayerSpectate >("onPlayerSpectate"); - m_Hnd->mOnPlayerCrashReport = GetSymbol< SDK_OnPlayerCrashReport >("onPlayerCrashReport"); - m_Hnd->mOnServerPerformanceReport = GetSymbol< SDK_OnServerPerformanceReport >("onServerPerformanceReport"); - m_Hnd->mOnCheckpointEntered = GetSymbol< SDK_OnCheckpointEntered >("onCheckpointEntered"); - m_Hnd->mOnCheckpointExited = GetSymbol< SDK_OnCheckpointExited >("onCheckpointExited"); - m_Hnd->mOnSphereEntered = GetSymbol< SDK_OnSphereEntered >("onSphereEntered"); - m_Hnd->mOnSphereExited = GetSymbol< SDK_OnSphereExited >("onSphereExited"); -} - -// ------------------------------------------------------------------------------------------------ -bool StateHnd::IsListed(Handle * hnd) -{ - return (std::find(s_Handles.cbegin(), s_Handles.cend(), hnd) != s_Handles.cend()); -} - -// ------------------------------------------------------------------------------------------------ -void StateHnd::Remember(Handle * hnd) -{ - // Make sure this handle doesn't exist already - if (!IsListed(hnd)) - { - s_Handles.push_back(hnd); - } -} - -// ------------------------------------------------------------------------------------------------ -void StateHnd::Forget(Handle * hnd) -{ - // Attempt to find this handle in the list - Handles::const_iterator itr = std::find(s_Handles.cbegin(), s_Handles.cend(), hnd); - // Does this handle exist in the list? - if (itr != s_Handles.cend()) - { - s_Handles.erase(itr); - } -} - -// ------------------------------------------------------------------------------------------------ -void StateHnd::ToHead(Handle * hnd) -{ - // Attempt to find this handle in the list - Handles::const_iterator itr = std::find(s_Handles.cbegin(), s_Handles.cend(), hnd); - // Does this handle exist in the list? - if (itr != s_Handles.cend()) - { - // Erase it from the current position - s_Handles.erase(itr); - } - // Insert it at the beginning of the list - s_Handles.insert(s_Handles.cbegin(), hnd); -} - -// ------------------------------------------------------------------------------------------------ -int StateHnd::OnInitServer(void) -{ - // Allow to startup by default - int res = 1; - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnInitServer) - { - // Forward the event and save the result - res = hnd->mOnInitServer(); - } - // Are we allowed to continue? - if (!res) - { - break; - } - } - // Return the result - return res; -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnShutdownServer(void) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnShutdownServer) - { - // Forward the event - hnd->mOnShutdownServer(); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnFrame(float delta) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnFrame) - { - // Forward the event - hnd->mOnFrame(delta); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnPlayerConnect(int player) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPlayerConnect) - { - // Forward the event - hnd->mOnPlayerConnect(player); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnPlayerDisconnect(int player, int reason) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPlayerDisconnect) - { - // Forward the event - hnd->mOnPlayerDisconnect(player, reason); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnPlayerBeginTyping(int player) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPlayerBeginTyping) - { - // Forward the event - hnd->mOnPlayerBeginTyping(player); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnPlayerEndTyping(int player) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPlayerEndTyping) - { - // Forward the event - hnd->mOnPlayerEndTyping(player); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -int StateHnd::OnPlayerRequestClass(int player, int offset) -{ - // Allow to startup by default - int res = 1; - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPlayerRequestClass) - { - // Forward the event and save the result - res = hnd->mOnPlayerRequestClass(player, offset); - } - // Are we allowed to continue? - if (!res) - { - break; - } - } - // Return the result - return res; -} - - -// ------------------------------------------------------------------------------------------------ -int StateHnd::OnPlayerRequestSpawn(int player) -{ - // Allow to startup by default - int res = 1; - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPlayerRequestSpawn) - { - // Forward the event and save the result - res = hnd->mOnPlayerRequestSpawn(player); - } - // Are we allowed to continue? - if (!res) - { - break; - } - } - // Return the result - return res; -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnPlayerSpawn(int player) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPlayerSpawn) - { - // Forward the event - hnd->mOnPlayerSpawn(player); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnPlayerDeath(int player, int killer, int reason, int body_part) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPlayerDeath) - { - // Forward the event - hnd->mOnPlayerDeath(player, killer, reason, body_part); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnPlayerUpdate(int player, int type) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPlayerUpdate) - { - // Forward the event - hnd->mOnPlayerUpdate(player, type); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -int StateHnd::OnPlayerRequestEnter(int player, int vehicle, int slot) -{ - // Allow to startup by default - int res = 1; - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPlayerRequestEnter) - { - // Forward the event and save the result - res = hnd->mOnPlayerRequestEnter(player, vehicle, slot); - } - // Are we allowed to continue? - if (!res) - { - break; - } - } - // Return the result - return res; -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnPlayerEnterVehicle(int player, int vehicle, int slot) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPlayerEnterVehicle) - { - // Forward the event - hnd->mOnPlayerEnterVehicle(player, vehicle, slot); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnPlayerExitVehicle(int player, int vehicle) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPlayerExitVehicle) - { - // Forward the event - hnd->mOnPlayerExitVehicle(player, vehicle); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnPlayerNameChange(int player, const char * previous, const char * current) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPlayerNameChange) - { - // Forward the event - hnd->mOnPlayerNameChange(player, previous, current); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnPlayerStateChange(int player, int previous, int current) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPlayerStateChange) - { - // Forward the event - hnd->mOnPlayerStateChange(player, previous, current); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnPlayerActionChange(int player, int previous, int current) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPlayerActionChange) - { - // Forward the event - hnd->mOnPlayerActionChange(player, previous, current); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnPlayerOnFireChange(int player, unsigned int state) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPlayerOnFireChange) - { - // Forward the event - hnd->mOnPlayerOnFireChange(player, state); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnPlayerCrouchChange(int player, unsigned int state) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPlayerCrouchChange) - { - // Forward the event - hnd->mOnPlayerCrouchChange(player, state); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnPlayerGameKeysChange(int player, int previous, int current) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPlayerGameKeysChange) - { - // Forward the event - hnd->mOnPlayerGameKeysChange(player, previous, current); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -int StateHnd::OnPickupClaimPicked(int pickup, int player) -{ - // Allow to startup by default - int res = 1; - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPickupClaimPicked) - { - // Forward the event and save the result - res = hnd->mOnPickupClaimPicked(pickup, player); - } - // Are we allowed to continue? - if (!res) - { - break; - } - } - // Return the result - return res; -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnPickupPickedUp(int pickup, int player) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPickupPickedUp) - { - // Forward the event - hnd->mOnPickupPickedUp(pickup, player); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnPickupRespawn(int pickup) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPickupRespawn) - { - // Forward the event - hnd->mOnPickupRespawn(pickup); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnVehicleUpdate(int vehicle, int type) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnVehicleUpdate) - { - // Forward the event - hnd->mOnVehicleUpdate(vehicle, type); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnVehicleExplode(int vehicle) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnVehicleExplode) - { - // Forward the event - hnd->mOnVehicleExplode(vehicle); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnVehicleRespawn(int vehicle) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnVehicleRespawn) - { - // Forward the event - hnd->mOnVehicleRespawn(vehicle); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnObjectShot(int object, int player, int weapon) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnObjectShot) - { - // Forward the event - hnd->mOnObjectShot(object, player, weapon); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnObjectBump(int object, int player) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnObjectBump) - { - // Forward the event - hnd->mOnObjectBump(object, player); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -int StateHnd::OnPublicMessage(int player, const char * message) -{ - // Allow to startup by default - int res = 1; - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPublicMessage) - { - // Forward the event and save the result - res = hnd->mOnPublicMessage(player, message); - } - // Are we allowed to continue? - if (!res) - { - break; - } - } - // Return the result - return res; -} - - -// ------------------------------------------------------------------------------------------------ -int StateHnd::OnCommandMessage(int player, const char * command) -{ - // Allow to startup by default - int res = 1; - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnCommandMessage) - { - // Forward the event and save the result - res = hnd->mOnCommandMessage(player, command); - } - // Are we allowed to continue? - if (!res) - { - break; - } - } - // Return the result - return res; -} - - -// ------------------------------------------------------------------------------------------------ -int StateHnd::OnPrivateMessage(int player, int target, const char * message) -{ - // Allow to startup by default - int res = 1; - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPrivateMessage) - { - // Forward the event and save the result - res = hnd->mOnPrivateMessage(player, target, message); - } - // Are we allowed to continue? - if (!res) - { - break; - } - } - // Return the result - return res; -} - - -// ------------------------------------------------------------------------------------------------ -int StateHnd::OnInternalCommand(unsigned int type, const char * text) -{ - // Allow to startup by default - int res = 1; - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnInternalCommand) - { - // Forward the event and save the result - res = hnd->mOnInternalCommand(type, text); - } - // Are we allowed to continue? - if (!res) - { - break; - } - } - // Return the result - return res; -} - - -// ------------------------------------------------------------------------------------------------ -int StateHnd::OnLoginAttempt(char * name, const char * passwd, const char * ipaddr) -{ - // Disallow to startup by default - int res = 0; - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnLoginAttempt) - { - // Forward the event and save the result - res = hnd->mOnLoginAttempt(name, passwd, ipaddr); - } - // Are we allowed to continue? - if (!res) - { - break; - } - } - // Return the result - return res; -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnEntityPoolChange(int type, int entity, unsigned int deleted) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnEntityPoolChange) - { - // Forward the event - hnd->mOnEntityPoolChange(type, entity, deleted); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnKeyBindDown(int player, int keybind) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnKeyBindDown) - { - // Forward the event - hnd->mOnKeyBindDown(player, keybind); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnKeyBindUp(int player, int keybind) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnKeyBindUp) - { - // Forward the event - hnd->mOnKeyBindUp(player, keybind); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnPlayerAwayChange(int player, unsigned int status) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPlayerAwayChange) - { - // Forward the event - hnd->mOnPlayerAwayChange(player, status); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnPlayerSpectate(int player, int target) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPlayerSpectate) - { - // Forward the event - hnd->mOnPlayerSpectate(player, target); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnPlayerCrashReport(int player, const char * report) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnPlayerCrashReport) - { - // Forward the event - hnd->mOnPlayerCrashReport(player, report); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnServerPerformanceReport(int count, const char ** description, unsigned long long * millispent) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnServerPerformanceReport) - { - // Forward the event - hnd->mOnServerPerformanceReport(count, description, millispent); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnCheckpointEntered(int checkpoint, int player) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnCheckpointEntered) - { - // Forward the event - hnd->mOnCheckpointEntered(checkpoint, player); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnCheckpointExited(int checkpoint, int player) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnCheckpointExited) - { - // Forward the event - hnd->mOnCheckpointExited(checkpoint, player); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnSphereEntered(int sphere, int player) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnSphereEntered) - { - // Forward the event - hnd->mOnSphereEntered(sphere, player); - } - } -} - - -// ------------------------------------------------------------------------------------------------ -void StateHnd::OnSphereExited(int sphere, int player) -{ - // Forward the call to the listed handles - for (auto & hnd : s_Handles) - { - // Does the state have this callback? - if (hnd->mOnSphereExited) - { - // Forward the event - hnd->mOnSphereExited(sphere, player); - } - } -} - -// ------------------------------------------------------------------------------------------------ -void StateHnd::ToggleEvent(Int32 evt, bool toggle) -{ - switch (evt) - { - case EvOnFrame: - _Clbk->OnFrame = toggle ? &StateHnd::OnFrame : nullptr; - break; - case EvOnPlayerConnect: - _Clbk->OnPlayerConnect = toggle ? &StateHnd::OnPlayerConnect : nullptr; - break; - case EvOnPlayerDisconnect: - _Clbk->OnPlayerDisconnect = toggle ? &StateHnd::OnPlayerDisconnect : nullptr; - break; - case EvOnPlayerBeginTyping: - _Clbk->OnPlayerBeginTyping = toggle ? &StateHnd::OnPlayerBeginTyping : nullptr; - break; - case EvOnPlayerEndTyping: - _Clbk->OnPlayerEndTyping = toggle ? &StateHnd::OnPlayerEndTyping : nullptr; - break; - case EvOnPlayerRequestClass: - _Clbk->OnPlayerRequestClass = toggle ? &StateHnd::OnPlayerRequestClass : nullptr; - break; - case EvOnPlayerRequestSpawn: - _Clbk->OnPlayerRequestSpawn = toggle ? &StateHnd::OnPlayerRequestSpawn : nullptr; - break; - case EvOnPlayerSpawn: - _Clbk->OnPlayerSpawn = toggle ? &StateHnd::OnPlayerSpawn : nullptr; - break; - case EvOnPlayerDeath: - _Clbk->OnPlayerDeath = toggle ? &StateHnd::OnPlayerDeath : nullptr; - break; - case EvOnPlayerUpdate: - _Clbk->OnPlayerUpdate = toggle ? &StateHnd::OnPlayerUpdate : nullptr; - break; - case EvOnPlayerRequestEnter: - _Clbk->OnPlayerRequestEnter = toggle ? &StateHnd::OnPlayerRequestEnter : nullptr; - break; - case EvOnPlayerEnterVehicle: - _Clbk->OnPlayerEnterVehicle = toggle ? &StateHnd::OnPlayerEnterVehicle : nullptr; - break; - case EvOnPlayerExitVehicle: - _Clbk->OnPlayerExitVehicle = toggle ? &StateHnd::OnPlayerExitVehicle : nullptr; - break; - case EvOnPlayerNameChange: - _Clbk->OnPlayerNameChange = toggle ? &StateHnd::OnPlayerNameChange : nullptr; - break; - case EvOnPlayerStateChange: - _Clbk->OnPlayerStateChange = toggle ? &StateHnd::OnPlayerStateChange : nullptr; - break; - case EvOnPlayerActionChange: - _Clbk->OnPlayerActionChange = toggle ? &StateHnd::OnPlayerActionChange : nullptr; - break; - case EvOnPlayerOnFireChange: - _Clbk->OnPlayerOnFireChange = toggle ? &StateHnd::OnPlayerOnFireChange : nullptr; - break; - case EvOnPlayerCrouchChange: - _Clbk->OnPlayerCrouchChange = toggle ? &StateHnd::OnPlayerCrouchChange : nullptr; - break; - case EvOnPlayerGameKeysChange: - _Clbk->OnPlayerGameKeysChange = toggle ? &StateHnd::OnPlayerGameKeysChange : nullptr; - break; - case EvOnPickupClaimPicked: - _Clbk->OnPickupClaimPicked = toggle ? &StateHnd::OnPickupClaimPicked : nullptr; - break; - case EvOnPickupPickedUp: - _Clbk->OnPickupPickedUp = toggle ? &StateHnd::OnPickupPickedUp : nullptr; - break; - case EvOnPickupRespawn: - _Clbk->OnPickupRespawn = toggle ? &StateHnd::OnPickupRespawn : nullptr; - break; - case EvOnVehicleUpdate: - _Clbk->OnVehicleUpdate = toggle ? &StateHnd::OnVehicleUpdate : nullptr; - break; - case EvOnVehicleExplode: - _Clbk->OnVehicleExplode = toggle ? &StateHnd::OnVehicleExplode : nullptr; - break; - case EvOnVehicleRespawn: - _Clbk->OnVehicleRespawn = toggle ? &StateHnd::OnVehicleRespawn : nullptr; - break; - case EvOnObjectShot: - _Clbk->OnObjectShot = toggle ? &StateHnd::OnObjectShot : nullptr; - break; - case EvOnObjectBump: - _Clbk->OnObjectBump = toggle ? &StateHnd::OnObjectBump : nullptr; - break; - case EvOnPublicMessage: - _Clbk->OnPublicMessage = toggle ? &StateHnd::OnPublicMessage : nullptr; - break; - case EvOnCommandMessage: - _Clbk->OnCommandMessage = toggle ? &StateHnd::OnCommandMessage : nullptr; - break; - case EvOnPrivateMessage: - _Clbk->OnPrivateMessage = toggle ? &StateHnd::OnPrivateMessage : nullptr; - break; - case EvOnLoginAttempt: - _Clbk->OnLoginAttempt = toggle ? &StateHnd::OnLoginAttempt : nullptr; - break; - case EvOnEntityPoolChange: - _Clbk->OnEntityPoolChange = toggle ? &StateHnd::OnEntityPoolChange : nullptr; - break; - case EvOnKeyBindDown: - _Clbk->OnKeyBindDown = toggle ? &StateHnd::OnKeyBindDown : nullptr; - break; - case EvOnKeyBindUp: - _Clbk->OnKeyBindUp = toggle ? &StateHnd::OnKeyBindUp : nullptr; - break; - case EvOnPlayerAwayChange: - _Clbk->OnPlayerAwayChange = toggle ? &StateHnd::OnPlayerAwayChange : nullptr; - break; - case EvOnPlayerSpectate: - _Clbk->OnPlayerSpectate = toggle ? &StateHnd::OnPlayerSpectate : nullptr; - break; - case EvOnPlayerCrashReport: - _Clbk->OnPlayerCrashReport = toggle ? &StateHnd::OnPlayerCrashReport : nullptr; - break; - case EvOnServerPerformanceReport: - _Clbk->OnServerPerformanceReport = toggle ? &StateHnd::OnServerPerformanceReport : nullptr; - break; - case EvOnCheckpointEntered: - _Clbk->OnCheckpointEntered = toggle ? &StateHnd::OnCheckpointEntered : nullptr; - break; - case EvOnCheckpointExited: - _Clbk->OnCheckpointExited = toggle ? &StateHnd::OnCheckpointExited : nullptr; - break; - case EvOnSphereEntered: - _Clbk->OnSphereEntered = toggle ? &StateHnd::OnSphereEntered : nullptr; - break; - case EvOnSphereExited: - _Clbk->OnSphereExited = toggle ? &StateHnd::OnSphereExited : nullptr; - break; - default: - STHROWF("Unknown server event"); - } -} - -} // Namespace:: SqMod diff --git a/modules/tcc/Common.hpp b/modules/tcc/Common.hpp deleted file mode 100644 index bb71da93..00000000 --- a/modules/tcc/Common.hpp +++ /dev/null @@ -1,700 +0,0 @@ -#ifndef _SQTCC_COMMON_HPP_ -#define _SQTCC_COMMON_HPP_ - -// ------------------------------------------------------------------------------------------------ -#include "ModBase.hpp" - -// ------------------------------------------------------------------------------------------------ -#include - -// ------------------------------------------------------------------------------------------------ -#include - -// ------------------------------------------------------------------------------------------------ -#include -#include - -// ------------------------------------------------------------------------------------------------ -#ifdef __cplusplus -extern "C" { -#endif - -struct TCCState; - -#ifdef __cplusplus -} // extern "C" -#endif - -// ------------------------------------------------------------------------------------------------ -namespace SqMod { - -/* ------------------------------------------------------------------------------------------------ - * SOFTWARE INFORMATION -*/ -#define SQTCC_NAME "Squirrel TCC Module" -#define SQTCC_AUTHOR "Sandu Liviu Catalin (S.L.C)" -#define SQTCC_COPYRIGHT "Copyright (C) 2016 Sandu Liviu Catalin" -#define SQTCC_HOST_NAME "SqModTCCHost" -#define SQTCC_VERSION 001 -#define SQTCC_VERSION_STR "0.0.1" -#define SQTCC_VERSION_MAJOR 0 -#define SQTCC_VERSION_MINOR 0 -#define SQTCC_VERSION_PATCH 1 - -/* ------------------------------------------------------------------------------------------------ - * Retrieve the temporary buffer. -*/ -SStr GetTempBuff(); - -/* ------------------------------------------------------------------------------------------------ - * Retrieve the size of the temporary buffer. -*/ -Uint32 GetTempBuffSize(); - -/* ------------------------------------------------------------------------------------------------ - * Throw a formatted exception. -*/ -void SqThrowF(CSStr str, ...); - -/* ------------------------------------------------------------------------------------------------ - * Generate a formatted string. -*/ -CSStr FmtStr(CSStr str, ...); - -/* ------------------------------------------------------------------------------------------------ - * Implements RAII to restore the VM stack to it's initial size on function exit. -*/ -struct StackGuard -{ - /* -------------------------------------------------------------------------------------------- - * Default constructor. - */ - StackGuard(); - - /* -------------------------------------------------------------------------------------------- - * Base constructor. - */ - StackGuard(HSQUIRRELVM vm); - - /* -------------------------------------------------------------------------------------------- - * Destructor. - */ - ~StackGuard(); - -private: - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. - */ - StackGuard(const StackGuard &); - - /* -------------------------------------------------------------------------------------------- - * Move constructor. - */ - StackGuard(StackGuard &&); - - /* -------------------------------------------------------------------------------------------- - * Copy assignment operator. - */ - StackGuard & operator = (const StackGuard &); - - /* -------------------------------------------------------------------------------------------- - * Move assignment operator. - */ - StackGuard & operator = (StackGuard &&); - -private: - - // -------------------------------------------------------------------------------------------- - HSQUIRRELVM m_VM; // The VM where the stack should be restored. - Int32 m_Top; // The top of the stack when this instance was created. -}; - -/* ------------------------------------------------------------------------------------------------ - * Helper structure for retrieving a value from the stack as a string or a formatted string. -*/ -struct StackStrF -{ - // -------------------------------------------------------------------------------------------- - CSStr mPtr; // Pointer to the C string that was retrieved. - SQInteger mLen; // The string length if it could be retrieved. - SQRESULT mRes; // The result of the retrieval attempts. - HSQOBJECT mObj; // Strong reference to the string object. - HSQUIRRELVM mVM; // The associated virtual machine. - - /* -------------------------------------------------------------------------------------------- - * Base constructor. - */ - StackStrF(HSQUIRRELVM vm, SQInteger idx, bool fmt = true); - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. (disabled) - */ - StackStrF(const StackStrF & o) = delete; - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. (disabled) - */ - StackStrF(StackStrF && o) = delete; - - /* -------------------------------------------------------------------------------------------- - * Destructor. - */ - ~StackStrF(); - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. (disabled) - */ - StackStrF & operator = (const StackStrF & o) = delete; - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. (disabled) - */ - StackStrF & operator = (StackStrF && o) = delete; -}; - -// ------------------------------------------------------------------------------------------------ -class State; -class Symbol; -class StateHnd; - -/* ------------------------------------------------------------------------------------------------ - * Register the standard API on the specified compiler state. -*/ -extern void RegisterAPI(StateHnd & s); - -/* ------------------------------------------------------------------------------------------------ - * Server events that can be toggled. -*/ -enum EventType -{ - EvUnknown = 0, - EvOnFrame, - EvOnPlayerConnect, - EvOnPlayerDisconnect, - EvOnPlayerBeginTyping, - EvOnPlayerEndTyping, - EvOnPlayerRequestClass, - EvOnPlayerRequestSpawn, - EvOnPlayerSpawn, - EvOnPlayerDeath, - EvOnPlayerUpdate, - EvOnPlayerRequestEnter, - EvOnPlayerEnterVehicle, - EvOnPlayerExitVehicle, - EvOnPlayerNameChange, - EvOnPlayerStateChange, - EvOnPlayerActionChange, - EvOnPlayerOnFireChange, - EvOnPlayerCrouchChange, - EvOnPlayerGameKeysChange, - EvOnPickupClaimPicked, - EvOnPickupPickedUp, - EvOnPickupRespawn, - EvOnVehicleUpdate, - EvOnVehicleExplode, - EvOnVehicleRespawn, - EvOnObjectShot, - EvOnObjectBump, - EvOnPublicMessage, - EvOnCommandMessage, - EvOnPrivateMessage, - EvOnLoginAttempt, - EvOnEntityPoolChange, - EvOnKeyBindDown, - EvOnKeyBindUp, - EvOnPlayerAwayChange, - EvOnPlayerSpectate, - EvOnPlayerCrashReport, - EvOnServerPerformanceReport, - EvOnCheckpointEntered, - EvOnCheckpointExited, - EvOnSphereEntered, - EvOnSphereExited, - EvCount -}; - -/* ------------------------------------------------------------------------------------------------ - * Manages a reference counted compiler state handle. -*/ -class StateHnd -{ - // -------------------------------------------------------------------------------------------- - friend class State; - friend class Symbol; - -public: - - // -------------------------------------------------------------------------------------------- - typedef TCCState Type; // The managed type. - - // -------------------------------------------------------------------------------------------- - typedef Type* Pointer; // Pointer to the managed type. - typedef const Type* ConstPtr; // Constant pointer to the managed type. - - // -------------------------------------------------------------------------------------------- - typedef Type& Reference; // Reference to the managed type. - typedef const Type& ConstRef; // Constant reference to the managed type. - - // -------------------------------------------------------------------------------------------- - typedef unsigned int Counter; // Reference counter type. - - /* -------------------------------------------------------------------------------------------- - * Validate the managed handle and throw exception if invalid. - */ - void Validate() const; - -protected: - - /* -------------------------------------------------------------------------------------------- - * The structure that holds the data associated with a certain state. - */ - struct Handle - { - // ---------------------------------------------------------------------------------------- - Pointer mPtr; // The TCC state handle resource. - Counter mRef; // Reference count to the managed handle. - - // ---------------------------------------------------------------------------------------- - SDK_OnInitServer mOnInitServer; - SDK_OnShutdownServer mOnShutdownServer; - SDK_OnFrame mOnFrame; - SDK_OnPlayerConnect mOnPlayerConnect; - SDK_OnPlayerDisconnect mOnPlayerDisconnect; - SDK_OnPlayerBeginTyping mOnPlayerBeginTyping; - SDK_OnPlayerEndTyping mOnPlayerEndTyping; - SDK_OnPlayerRequestClass mOnPlayerRequestClass; - SDK_OnPlayerRequestSpawn mOnPlayerRequestSpawn; - SDK_OnPlayerSpawn mOnPlayerSpawn; - SDK_OnPlayerDeath mOnPlayerDeath; - SDK_OnPlayerUpdate mOnPlayerUpdate; - SDK_OnPlayerRequestEnter mOnPlayerRequestEnter; - SDK_OnPlayerEnterVehicle mOnPlayerEnterVehicle; - SDK_OnPlayerExitVehicle mOnPlayerExitVehicle; - SDK_OnPlayerNameChange mOnPlayerNameChange; - SDK_OnPlayerStateChange mOnPlayerStateChange; - SDK_OnPlayerActionChange mOnPlayerActionChange; - SDK_OnPlayerOnFireChange mOnPlayerOnFireChange; - SDK_OnPlayerCrouchChange mOnPlayerCrouchChange; - SDK_OnPlayerGameKeysChange mOnPlayerGameKeysChange; - SDK_OnPickupClaimPicked mOnPickupClaimPicked; - SDK_OnPickupPickedUp mOnPickupPickedUp; - SDK_OnPickupRespawn mOnPickupRespawn; - SDK_OnVehicleUpdate mOnVehicleUpdate; - SDK_OnVehicleExplode mOnVehicleExplode; - SDK_OnVehicleRespawn mOnVehicleRespawn; - SDK_OnObjectShot mOnObjectShot; - SDK_OnObjectBump mOnObjectBump; - SDK_OnPublicMessage mOnPublicMessage; - SDK_OnCommandMessage mOnCommandMessage; - SDK_OnPrivateMessage mOnPrivateMessage; - SDK_OnInternalCommand mOnInternalCommand; - SDK_OnLoginAttempt mOnLoginAttempt; - SDK_OnEntityPoolChange mOnEntityPoolChange; - SDK_OnKeyBindDown mOnKeyBindDown; - SDK_OnKeyBindUp mOnKeyBindUp; - SDK_OnPlayerAwayChange mOnPlayerAwayChange; - SDK_OnPlayerSpectate mOnPlayerSpectate; - SDK_OnPlayerCrashReport mOnPlayerCrashReport; - SDK_OnServerPerformanceReport mOnServerPerformanceReport; - SDK_OnCheckpointEntered mOnCheckpointEntered; - SDK_OnCheckpointExited mOnCheckpointExited; - SDK_OnSphereEntered mOnSphereEntered; - SDK_OnSphereExited mOnSphereExited; - - // ---------------------------------------------------------------------------------------- - bool mRelocated; // Whether the state was relocated. - bool mNoErrors; // Don't output errors even if there is no error handler. - - // ---------------------------------------------------------------------------------------- - Function mErrorHandler; // The custom script error handler. - - // ---------------------------------------------------------------------------------------- - String mName; // The name given to this state. - - /* ---------------------------------------------------------------------------------------- - * Base constructor. - */ - Handle(Counter counter, CSStr name); - - /* ---------------------------------------------------------------------------------------- - * Destructor. - */ - ~Handle(); - }; - -private: - - // -------------------------------------------------------------------------------------------- - typedef std::vector< Handle * > Handles; // List of handles that receive callbacks. - - // -------------------------------------------------------------------------------------------- - static Handles s_Handles; - - /* -------------------------------------------------------------------------------------------- - * See whether the specified state instance is in the handles list. - */ - static bool IsListed(Handle * hnd); - - /* -------------------------------------------------------------------------------------------- - * Add the specified state instance to the handles list to receive callbacks. - */ - static void Remember(Handle * hnd); - - /* -------------------------------------------------------------------------------------------- - * Remove the specified state instance from the handles list. - */ - static void Forget(Handle * hnd); - - /* -------------------------------------------------------------------------------------------- - * Make the specified handle to be the first in the list. - */ - static void ToHead(Handle * hnd); - -protected: - - /* -------------------------------------------------------------------------------------------- - * The error handler assigned to every created state. - */ - static void ErrorHandler(void * opaque, const char * msg); - - /* -------------------------------------------------------------------------------------------- - * Add a symbol to the compiled program. - */ - void PushSymbol(CSStr name, const void * value); - - /* -------------------------------------------------------------------------------------------- - * Return symbol value or NULL if not found. - */ - void * PullSymbol(CSStr name) const; - -private: - - // -------------------------------------------------------------------------------------------- - Handle* m_Hnd; - - /* -------------------------------------------------------------------------------------------- - * Grab a strong reference to a state handle. - */ - void Grab() - { - if (m_Hnd) - { - ++(m_Hnd->mRef); - } - } - - /* -------------------------------------------------------------------------------------------- - * Drop a strong reference to a state handle. - */ - void Drop() - { - if (m_Hnd && --(m_Hnd->mRef) == 0) - { - delete m_Hnd; // Let the destructor take care of cleaning up (if necessary) - } - } - - /* -------------------------------------------------------------------------------------------- - * Base constructor. - */ - StateHnd(CSStr name) - : m_Hnd(name ? new Handle(1, name) : nullptr) - { - RegisterAPI(*this); - } - -public: - - /* -------------------------------------------------------------------------------------------- - * Default constructor (null). - */ - StateHnd() - : m_Hnd(nullptr) - { - /* ... */ - } - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. - */ - StateHnd(const StateHnd & o) - : m_Hnd(o.m_Hnd) - { - Grab(); - } - - /* -------------------------------------------------------------------------------------------- - * Move constructor. - */ - StateHnd(StateHnd && o) - : m_Hnd(o.m_Hnd) - { - o.m_Hnd = nullptr; - } - - /* -------------------------------------------------------------------------------------------- - * Destructor. - */ - ~StateHnd() - { - Drop(); - } - - /* -------------------------------------------------------------------------------------------- - * Copy assignment operator. - */ - StateHnd & operator = (const StateHnd & o) - { - if (m_Hnd != o.m_Hnd) - { - Drop(); - m_Hnd = o.m_Hnd; - Grab(); - } - return *this; - } - - /* -------------------------------------------------------------------------------------------- - * Move assignment operator. - */ - StateHnd & operator = (StateHnd && o) - { - if (m_Hnd != o.m_Hnd) - { - m_Hnd = o.m_Hnd; - o.m_Hnd = nullptr; - } - - return *this; - } - - /* -------------------------------------------------------------------------------------------- - * Perform an equality comparison between two state handles. - */ - bool operator == (const StateHnd & o) const - { - return (m_Hnd == o.m_Hnd); - } - - /* -------------------------------------------------------------------------------------------- - * Perform an inequality comparison between two state handles. - */ - bool operator != (const StateHnd & o) const - { - return (m_Hnd != o.m_Hnd); - } - - /* -------------------------------------------------------------------------------------------- - * Implicit conversion to boolean for use in boolean operations. - */ - operator bool () const - { - return m_Hnd && m_Hnd->mPtr; - } - - /* -------------------------------------------------------------------------------------------- - * Implicit conversion to the managed instance. - */ - operator Pointer () - { - return m_Hnd ? m_Hnd->mPtr : nullptr; - } - - /* -------------------------------------------------------------------------------------------- - * Implicit conversion to the managed instance. - */ - operator Pointer () const - { - return m_Hnd ? m_Hnd->mPtr : nullptr; - } - - /* -------------------------------------------------------------------------------------------- - * Implicit conversion to the managed instance. - */ - operator Reference () - { - assert(m_Hnd && m_Hnd->mPtr); - return *(m_Hnd->mPtr); - } - - /* -------------------------------------------------------------------------------------------- - * Implicit conversion to the managed instance. - */ - operator ConstRef () const - { - assert(m_Hnd && m_Hnd->mPtr); - return *(m_Hnd->mPtr); - } - - /* -------------------------------------------------------------------------------------------- - * Member operator for dereferencing the managed pointer. - */ - Handle * operator -> () const - { - assert(m_Hnd); - return m_Hnd; - } - - /* -------------------------------------------------------------------------------------------- - * Indirection operator for obtaining a reference of the managed pointer. - */ - Handle & operator * () const - { - assert(m_Hnd); - return *m_Hnd; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the raw handle structure pointer. - */ - Handle * HndPtr() - { - return m_Hnd; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the raw handle structure pointer. - */ - Handle * HndPtr() const - { - return m_Hnd; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the number of active references to the managed instance. - */ - Counter Count() const - { - return m_Hnd ? m_Hnd->mRef : 0; - } - - /* -------------------------------------------------------------------------------------------- - * Set options as from command line (multiple supported). - */ - void SetOptions(CSStr opt) const; - - /* -------------------------------------------------------------------------------------------- - * Define preprocessor symbol 'sym'. Can put optional value. - */ - void DefineSymbol(CSStr sym, CSStr value) const; - - /* -------------------------------------------------------------------------------------------- - * Undefine preprocess symbol 'sym'. - */ - void UndefineSymbol(CSStr sym) const; - - /* -------------------------------------------------------------------------------------------- - * Add include path. - */ - void AddIncludePath(CSStr path) const; - - /* -------------------------------------------------------------------------------------------- - * Add in system include path. - */ - void AddSysIncludePath(CSStr path) const; - - /* -------------------------------------------------------------------------------------------- - * Set CONFIG_TCCDIR at runtime. - */ - void SetLibPath(CSStr path) const; - - /* -------------------------------------------------------------------------------------------- - * Equivalent to -Lpath option. - */ - void AddLibraryPath(CSStr path) const; - - /* -------------------------------------------------------------------------------------------- - * The library name is the same as the argument of the '-l' option. - */ - void AddLibrary(CSStr name) const; - - /* -------------------------------------------------------------------------------------------- - * Compile a string containing a C source. - */ - void CompileString(CSStr str) const; - - /* -------------------------------------------------------------------------------------------- - * Add a file (C file, dll, object, library, ld script). - */ - void AddFile(CSStr filename, Int32 type) const; - - /* -------------------------------------------------------------------------------------------- - * Do all relocations (needed before using tcc_get_symbol()) - */ - void Relocate() const; - - /* -------------------------------------------------------------------------------------------- - * Add a symbol to the compiled program. - */ - template < typename T > void AddSymbol(CSStr name, T value) - { - PushSymbol(name, reinterpret_cast< const void * >(value)); - } - - /* -------------------------------------------------------------------------------------------- - * Return symbol value or NULL if not found. - */ - template < typename T > T GetSymbol(CSStr name) const - { - return reinterpret_cast< T >(PullSymbol(name)); - } - - /* -------------------------------------------------------------------------------------------- - * Server callbacks. - */ - static int OnInitServer(void); - static void OnShutdownServer(void); - static void OnFrame(float delta); - static void OnPlayerConnect(int player); - static void OnPlayerDisconnect(int player, int reason); - static void OnPlayerBeginTyping(int player); - static void OnPlayerEndTyping(int player); - static int OnPlayerRequestClass(int player, int offset); - static int OnPlayerRequestSpawn(int player); - static void OnPlayerSpawn(int player); - static void OnPlayerDeath(int player, int killer, int reason, int body_part); - static void OnPlayerUpdate(int player, int type); - static int OnPlayerRequestEnter(int player, int vehicle, int slot); - static void OnPlayerEnterVehicle(int player, int vehicle, int slot); - static void OnPlayerExitVehicle(int player, int vehicle); - static void OnPlayerNameChange(int player, const char * previous, const char * current); - static void OnPlayerStateChange(int player, int previous, int current); - static void OnPlayerActionChange(int player, int previous, int current); - static void OnPlayerOnFireChange(int player, unsigned int state); - static void OnPlayerCrouchChange(int player, unsigned int state); - static void OnPlayerGameKeysChange(int player, int previous, int current); - static int OnPickupClaimPicked(int pickup, int player); - static void OnPickupPickedUp(int pickup, int player); - static void OnPickupRespawn(int pickup); - static void OnVehicleUpdate(int vehicle, int type); - static void OnVehicleExplode(int vehicle); - static void OnVehicleRespawn(int vehicle); - static void OnObjectShot(int object, int player, int weapon); - static void OnObjectBump(int object, int player); - static int OnPublicMessage(int player, const char * message); - static int OnCommandMessage(int player, const char * command); - static int OnPrivateMessage(int player, int target, const char * message); - static int OnInternalCommand(unsigned int type, const char * text); - static int OnLoginAttempt(char * name, const char * passwd, const char * ipaddr); - static void OnEntityPoolChange(int type, int entity, unsigned int deleted); - static void OnKeyBindDown(int player, int keybind); - static void OnKeyBindUp(int player, int keybind); - static void OnPlayerAwayChange(int player, unsigned int status); - static void OnPlayerSpectate(int player, int target); - static void OnPlayerCrashReport(int player, const char * report); - static void OnServerPerformanceReport(int count, const char ** description, unsigned long long * millispent); - static void OnCheckpointEntered(int checkpoint, int player); - static void OnCheckpointExited(int checkpoint, int player); - static void OnSphereEntered(int sphere, int player); - static void OnSphereExited(int sphere, int player); - - /* -------------------------------------------------------------------------------------------- - * Enable or disable a certain server event. - */ - static void ToggleEvent(Int32 evt, bool toggle); -}; - -} // Namespace:: SqMod - -#endif // _SQTCC_COMMON_HPP_ diff --git a/modules/tcc/Module.cpp b/modules/tcc/Module.cpp deleted file mode 100644 index 503b3c0b..00000000 --- a/modules/tcc/Module.cpp +++ /dev/null @@ -1,504 +0,0 @@ -// -------------------------------------------------------------------------------------------- -#include "Module.hpp" -#include "Common.hpp" -#include "State.hpp" -#include "Symbol.hpp" - -// -------------------------------------------------------------------------------------------- -#include - -// -------------------------------------------------------------------------------------------- -#include -#include -#include - -// -------------------------------------------------------------------------------------------- -#if defined(WIN32) || defined(_WIN32) - #include -#endif - -namespace SqMod { - -// -------------------------------------------------------------------------------------------- -PluginFuncs* _Func = nullptr; -PluginCallbacks* _Clbk = nullptr; -PluginInfo* _Info = nullptr; - -// -------------------------------------------------------------------------------------------- -HSQAPI _SqAPI = nullptr; -HSQEXPORTS _SqMod = nullptr; -HSQUIRRELVM _SqVM = nullptr; - -/* ------------------------------------------------------------------------------------------------ - * Bind speciffic functions to certain server events. -*/ -void BindCallbacks(); - -/* ------------------------------------------------------------------------------------------------ - * Undo changes made with BindCallbacks(). -*/ -void UnbindCallbacks(); - -/* -------------------------------------------------------------------------------------------- - * Register the module API under the specified virtual machine. -*/ -void RegisterAPI(HSQUIRRELVM vm); - -/* -------------------------------------------------------------------------------------------- - * Initialize the plugin by obtaining the API provided by the host plugin. -*/ -void OnSquirrelInitialize() -{ - // Attempt to import the plugin API exported by the host plugin - _SqMod = sq_api_import(_Func); - // Did we failed to obtain the plugin exports? - if(!_SqMod) - { - OutputError("Failed to attach [%s] on host plugin.", SQTCC_NAME); - } - else - { - // Obtain the Squirrel API - _SqAPI = _SqMod->GetSquirrelAPI(); - // Expand the Squirrel API into global functions - sq_api_expand(_SqAPI); - } -} - -/* -------------------------------------------------------------------------------------------- - * Load the module on the virtual machine provided by the host module. -*/ -void OnSquirrelLoad() -{ - // Make sure that we have a valid plugin API - if (!_SqMod) - { - return; /* Unable to proceed. */ - } - // Obtain the Squirrel API and VM - _SqVM = _SqMod->GetSquirrelVM(); - // Make sure that a valid virtual machine exists - if (!_SqVM) - { - return; /* Unable to proceed. */ - } - // Set this as the default database - DefaultVM::Set(_SqVM); - // Register the module API - RegisterAPI(_SqVM); - // Notify about the current status - OutputMessage("Registered: %s", SQTCC_NAME); -} - -/* -------------------------------------------------------------------------------------------- - * The virtual machine is about to be terminated and script resources should be released. -*/ -void OnSquirrelTerminate() -{ - OutputMessage("Terminating: %s", SQTCC_NAME); - // Release the current database (if any) - DefaultVM::Set(nullptr); - // Release script resources... -} - -/* -------------------------------------------------------------------------------------------- - * Validate the module API to make sure we don't run into issues. -*/ -bool CheckAPIVer(CCStr ver) -{ - // Obtain the numeric representation of the API version - long vernum = std::strtol(ver, nullptr, 10); - // Check against version mismatch - if (vernum == SQMOD_API_VER) - { - return true; - } - // Log the incident - OutputError("API version mismatch on %s", SQTCC_NAME); - OutputMessage("=> Requested: %ld Have: %ld", vernum, SQMOD_API_VER); - // Invoker should not attempt to communicate through the module API - return false; -} - -/* -------------------------------------------------------------------------------------------- - * React to command sent by other plugins. -*/ -static int OnInternalCommand(unsigned int type, const char * text) -{ - // Forward the call to compiler states - int res = StateHnd::OnInternalCommand(type, text); - // Now we can process it - switch(type) - { - case SQMOD_INITIALIZE_CMD: - if (CheckAPIVer(text)) - { - OnSquirrelInitialize(); - } - break; - case SQMOD_LOAD_CMD: - OnSquirrelLoad(); - break; - case SQMOD_TERMINATE_CMD: - OnSquirrelTerminate(); - break; - default: break; - } - // Return the result - return res; -} - -/* -------------------------------------------------------------------------------------------- - * The server was initialized and this plugin was loaded successfully. -*/ -static int OnInitServer() -{ - return StateHnd::OnInitServer(); -} - -static void OnShutdownServer(void) -{ - // Forward the call to compiler states - StateHnd::OnShutdownServer(); - // The server may still send callbacks - UnbindCallbacks(); -} - -// ------------------------------------------------------------------------------------------------ -void BindCallbacks() -{ - _Clbk->OnInitServer = OnInitServer; - _Clbk->OnInternalCommand = OnInternalCommand; - _Clbk->OnShutdownServer = OnShutdownServer; - _Clbk->OnFrame = &StateHnd::OnFrame; - _Clbk->OnPlayerConnect = &StateHnd::OnPlayerConnect; - _Clbk->OnPlayerDisconnect = &StateHnd::OnPlayerDisconnect; - _Clbk->OnPlayerBeginTyping = &StateHnd::OnPlayerBeginTyping; - _Clbk->OnPlayerEndTyping = &StateHnd::OnPlayerEndTyping; - _Clbk->OnPlayerRequestClass = &StateHnd::OnPlayerRequestClass; - _Clbk->OnPlayerRequestSpawn = &StateHnd::OnPlayerRequestSpawn; - _Clbk->OnPlayerSpawn = &StateHnd::OnPlayerSpawn; - _Clbk->OnPlayerDeath = &StateHnd::OnPlayerDeath; - _Clbk->OnPlayerUpdate = &StateHnd::OnPlayerUpdate; - _Clbk->OnPlayerRequestEnter = &StateHnd::OnPlayerRequestEnter; - _Clbk->OnPlayerEnterVehicle = &StateHnd::OnPlayerEnterVehicle; - _Clbk->OnPlayerExitVehicle = &StateHnd::OnPlayerExitVehicle; - _Clbk->OnPlayerNameChange = &StateHnd::OnPlayerNameChange; - _Clbk->OnPlayerStateChange = &StateHnd::OnPlayerStateChange; - _Clbk->OnPlayerActionChange = &StateHnd::OnPlayerActionChange; - _Clbk->OnPlayerOnFireChange = &StateHnd::OnPlayerOnFireChange; - _Clbk->OnPlayerCrouchChange = &StateHnd::OnPlayerCrouchChange; - _Clbk->OnPlayerGameKeysChange = &StateHnd::OnPlayerGameKeysChange; - _Clbk->OnPickupClaimPicked = &StateHnd::OnPickupClaimPicked; - _Clbk->OnPickupPickedUp = &StateHnd::OnPickupPickedUp; - _Clbk->OnPickupRespawn = &StateHnd::OnPickupRespawn; - _Clbk->OnVehicleUpdate = &StateHnd::OnVehicleUpdate; - _Clbk->OnVehicleExplode = &StateHnd::OnVehicleExplode; - _Clbk->OnVehicleRespawn = &StateHnd::OnVehicleRespawn; - _Clbk->OnObjectShot = &StateHnd::OnObjectShot; - _Clbk->OnObjectBump = &StateHnd::OnObjectBump; - _Clbk->OnPublicMessage = &StateHnd::OnPublicMessage; - _Clbk->OnCommandMessage = &StateHnd::OnCommandMessage; - _Clbk->OnPrivateMessage = &StateHnd::OnPrivateMessage; - _Clbk->OnLoginAttempt = &StateHnd::OnLoginAttempt; - _Clbk->OnEntityPoolChange = &StateHnd::OnEntityPoolChange; - _Clbk->OnKeyBindDown = &StateHnd::OnKeyBindDown; - _Clbk->OnKeyBindUp = &StateHnd::OnKeyBindUp; - _Clbk->OnPlayerAwayChange = &StateHnd::OnPlayerAwayChange; - _Clbk->OnPlayerSpectate = &StateHnd::OnPlayerSpectate; - _Clbk->OnPlayerCrashReport = &StateHnd::OnPlayerCrashReport; - _Clbk->OnServerPerformanceReport = &StateHnd::OnServerPerformanceReport; - _Clbk->OnCheckpointEntered = &StateHnd::OnCheckpointEntered; - _Clbk->OnCheckpointExited = &StateHnd::OnCheckpointExited; - _Clbk->OnSphereEntered = &StateHnd::OnSphereEntered; - _Clbk->OnSphereExited = &StateHnd::OnSphereExited; -} - -// ------------------------------------------------------------------------------------------------ -void UnbindCallbacks() -{ - _Clbk->OnInitServer = nullptr; - _Clbk->OnInternalCommand = nullptr; - _Clbk->OnShutdownServer = nullptr; - _Clbk->OnFrame = nullptr; - _Clbk->OnPlayerConnect = nullptr; - _Clbk->OnPlayerDisconnect = nullptr; - _Clbk->OnPlayerBeginTyping = nullptr; - _Clbk->OnPlayerEndTyping = nullptr; - _Clbk->OnPlayerRequestClass = nullptr; - _Clbk->OnPlayerRequestSpawn = nullptr; - _Clbk->OnPlayerSpawn = nullptr; - _Clbk->OnPlayerDeath = nullptr; - _Clbk->OnPlayerUpdate = nullptr; - _Clbk->OnPlayerRequestEnter = nullptr; - _Clbk->OnPlayerEnterVehicle = nullptr; - _Clbk->OnPlayerExitVehicle = nullptr; - _Clbk->OnPlayerNameChange = nullptr; - _Clbk->OnPlayerStateChange = nullptr; - _Clbk->OnPlayerActionChange = nullptr; - _Clbk->OnPlayerOnFireChange = nullptr; - _Clbk->OnPlayerCrouchChange = nullptr; - _Clbk->OnPlayerGameKeysChange = nullptr; - _Clbk->OnPickupClaimPicked = nullptr; - _Clbk->OnPickupPickedUp = nullptr; - _Clbk->OnPickupRespawn = nullptr; - _Clbk->OnVehicleUpdate = nullptr; - _Clbk->OnVehicleExplode = nullptr; - _Clbk->OnVehicleRespawn = nullptr; - _Clbk->OnObjectShot = nullptr; - _Clbk->OnObjectBump = nullptr; - _Clbk->OnPublicMessage = nullptr; - _Clbk->OnCommandMessage = nullptr; - _Clbk->OnPrivateMessage = nullptr; - _Clbk->OnLoginAttempt = nullptr; - _Clbk->OnEntityPoolChange = nullptr; - _Clbk->OnKeyBindDown = nullptr; - _Clbk->OnKeyBindUp = nullptr; - _Clbk->OnPlayerAwayChange = nullptr; - _Clbk->OnPlayerSpectate = nullptr; - _Clbk->OnPlayerCrashReport = nullptr; - _Clbk->OnServerPerformanceReport = nullptr; - _Clbk->OnCheckpointEntered = nullptr; - _Clbk->OnCheckpointExited = nullptr; - _Clbk->OnSphereEntered = nullptr; - _Clbk->OnSphereExited = nullptr; -} - -// -------------------------------------------------------------------------------------------- -void RegisterAPI(HSQUIRRELVM vm) -{ - Table tccns(vm); - - tccns.Bind(_SC("State"), Class< State >(vm, _SC("SqTccState")) - // Constructors - .Ctor< CSStr >() - // Metamethods - .Func(_SC("_cmp"), &State::Cmp) - .SquirrelFunc(_SC("_typename"), &State::Typename) - .Func(_SC("_tostring"), &State::ToString) - // Properties - .Prop(_SC("Valid"), &State::IsValid) - .Prop(_SC("Refs"), &State::GetRefCount) - .Prop(_SC("Name"), &State::GetName, &State::SetName) - .Prop(_SC("Events"), &State::GetEvents, &State::SetEvents) - // Member Methods - .Func(_SC("Release"), &State::Release) - .Func(_SC("MakeHead"), &State::MakeHead) - .Func(_SC("SetOptions"), &State::SetOptions) - .Func(_SC("UndefineSymbol"), &State::UndefineSymbol) - .Func(_SC("AddIncludePath"), &State::AddIncludePath) - .Func(_SC("AddSysIncludePath"), &State::AddSysIncludePath) - .Func(_SC("SetLibPath"), &State::SetLibPath) - .Func(_SC("AddLibraryPath"), &State::AddLibraryPath) - .Func(_SC("AddLibrary"), &State::AddLibrary) - .Func(_SC("CompileString"), &State::CompileString) - .Func(_SC("AddSource"), &State::AddSource) - .Func(_SC("AddBinary"), &State::AddBinary) - .Func(_SC("AddAsm"), &State::AddAsm) - .Func(_SC("AddAsmPP"), &State::AddAsmPP) - .Func(_SC("Relocate"), &State::Relocate) - .Func(_SC("GetSymbol"), &State::GetSymbol) - // Member Overloads - .Overload< void (State::*)(CSStr) const >(_SC("DefineSymbol"), &State::DefineSymbol) - .Overload< void (State::*)(CSStr, CSStr) const >(_SC("DefineSymbol"), &State::DefineSymbol) - ); - - tccns.Bind(_SC("Symbol"), Class< Symbol >(vm, _SC("SqTccSymbol")) - // Constructors - .Ctor< const State &, CSStr >() - // Metamethods - .Func(_SC("_cmp"), &Symbol::Cmp) - .SquirrelFunc(_SC("_typename"), &Symbol::Typename) - .Func(_SC("_tostring"), &Symbol::ToString) - // Properties - .Prop(_SC("Valid"), &Symbol::IsValid) - .Prop(_SC("Refs"), &Symbol::GetRefCount) - .Prop(_SC("State"), &Symbol::GetStateRef) - // Member Methods - .Func(_SC("Release"), &Symbol::Release) - // Squirrel Methods - .SquirrelFunc(_SC("Forward"), &Symbol::Forward) - ); - - tccns.Func(_SC("ToggleEvent"), &StateHnd::ToggleEvent); - - RootTable(vm).Bind(_SC("SqTCC"), tccns); - - ConstTable(vm).Enum(_SC("ETccEvent"), Enumeration(vm) - .Const(_SC("Frame"), EvOnFrame) - .Const(_SC("PlayerConnect"), EvOnPlayerConnect) - .Const(_SC("PlayerDisconnect"), EvOnPlayerDisconnect) - .Const(_SC("PlayerBeginTyping"), EvOnPlayerBeginTyping) - .Const(_SC("PlayerEndTyping"), EvOnPlayerEndTyping) - .Const(_SC("PlayerRequestClass"), EvOnPlayerRequestClass) - .Const(_SC("PlayerRequestSpawn"), EvOnPlayerRequestSpawn) - .Const(_SC("PlayerSpawn"), EvOnPlayerSpawn) - .Const(_SC("PlayerDeath"), EvOnPlayerDeath) - .Const(_SC("PlayerUpdate"), EvOnPlayerUpdate) - .Const(_SC("PlayerRequestEnter"), EvOnPlayerRequestEnter) - .Const(_SC("PlayerEnterVehicle"), EvOnPlayerEnterVehicle) - .Const(_SC("PlayerExitVehicle"), EvOnPlayerExitVehicle) - .Const(_SC("PlayerNameChange"), EvOnPlayerNameChange) - .Const(_SC("PlayerStateChange"), EvOnPlayerStateChange) - .Const(_SC("PlayerActionChange"), EvOnPlayerActionChange) - .Const(_SC("PlayerOnFireChange"), EvOnPlayerOnFireChange) - .Const(_SC("PlayerCrouchChange"), EvOnPlayerCrouchChange) - .Const(_SC("PlayerGameKeysChange"), EvOnPlayerGameKeysChange) - .Const(_SC("PickupClaimPicked"), EvOnPickupClaimPicked) - .Const(_SC("PickupPickedUp"), EvOnPickupPickedUp) - .Const(_SC("PickupRespawn"), EvOnPickupRespawn) - .Const(_SC("VehicleUpdate"), EvOnVehicleUpdate) - .Const(_SC("VehicleExplode"), EvOnVehicleExplode) - .Const(_SC("VehicleRespawn"), EvOnVehicleRespawn) - .Const(_SC("ObjectShot"), EvOnObjectShot) - .Const(_SC("ObjectBump"), EvOnObjectBump) - .Const(_SC("PublicMessage"), EvOnPublicMessage) - .Const(_SC("CommandMessage"), EvOnCommandMessage) - .Const(_SC("PrivateMessage"), EvOnPrivateMessage) - .Const(_SC("LoginAttempt"), EvOnLoginAttempt) - .Const(_SC("EntityPoolChange"), EvOnEntityPoolChange) - .Const(_SC("KeyBindDown"), EvOnKeyBindDown) - .Const(_SC("KeyBindUp"), EvOnKeyBindUp) - .Const(_SC("PlayerAwayChange"), EvOnPlayerAwayChange) - .Const(_SC("PlayerSpectate"), EvOnPlayerSpectate) - .Const(_SC("PlayerCrashReport"), EvOnPlayerCrashReport) - .Const(_SC("ServerPerformanceReport"), EvOnServerPerformanceReport) - .Const(_SC("CheckpointEntered"), EvOnCheckpointEntered) - .Const(_SC("CheckpointExited"), EvOnCheckpointExited) - .Const(_SC("SphereEntered"), EvOnSphereEntered) - .Const(_SC("SphereExited"), EvOnSphereExited) - ); -} - -// -------------------------------------------------------------------------------------------- -void OutputMessageImpl(const char * msg, va_list args) -{ -#if defined(WIN32) || defined(_WIN32) - HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE); - - CONSOLE_SCREEN_BUFFER_INFO csb_before; - GetConsoleScreenBufferInfo( hstdout, &csb_before); - SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN); - printf("[SQMOD] "); - - SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); - vprintf(msg, args); - puts(""); - - SetConsoleTextAttribute(hstdout, csb_before.wAttributes); -#else - printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27); - vprintf(msg, args); - puts(""); -#endif -} - -// -------------------------------------------------------------------------------------------- -void OutputErrorImpl(const char * msg, va_list args) -{ -#if defined(WIN32) || defined(_WIN32) - HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE); - - CONSOLE_SCREEN_BUFFER_INFO csb_before; - GetConsoleScreenBufferInfo( hstdout, &csb_before); - SetConsoleTextAttribute(hstdout, FOREGROUND_RED | FOREGROUND_INTENSITY); - printf("[SQMOD] "); - - SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); - vprintf(msg, args); - puts(""); - - SetConsoleTextAttribute(hstdout, csb_before.wAttributes); -#else - printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27); - vprintf(msg, args); - puts(""); -#endif -} - -// -------------------------------------------------------------------------------------------- -void OutputDebug(const char * msg, ...) -{ -#ifdef _DEBUG - // Initialize the arguments list - va_list args; - va_start(args, msg); - // Call the output function - OutputMessageImpl(msg, args); - // Finalize the arguments list - va_end(args); -#else - SQMOD_UNUSED_VAR(msg); -#endif -} - -// -------------------------------------------------------------------------------------------- -void OutputMessage(const char * msg, ...) -{ - // Initialize the arguments list - va_list args; - va_start(args, msg); - // Call the output function - OutputMessageImpl(msg, args); - // Finalize the arguments list - va_end(args); -} - -// -------------------------------------------------------------------------------------------- -void OutputError(const char * msg, ...) -{ - // Initialize the arguments list - va_list args; - va_start(args, msg); - // Call the output function - OutputErrorImpl(msg, args); - // Finalize the arguments list - va_end(args); -} - -} // Namespace:: SqMod - -// -------------------------------------------------------------------------------------------- -SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs* functions, PluginCallbacks* callbacks, PluginInfo* info) -{ - using namespace SqMod; - // Output plugin header - puts(""); - OutputMessage("--------------------------------------------------------------------"); - OutputMessage("Plugin: %s", SQTCC_NAME); - OutputMessage("Author: %s", SQTCC_AUTHOR); - OutputMessage("Legal: %s", SQTCC_COPYRIGHT); - OutputMessage("--------------------------------------------------------------------"); - puts(""); - // Attempt to find the host plugin ID - int host_plugin_id = functions->FindPlugin((char *)(SQMOD_HOST_NAME)); - // See if our plugin was loaded after the host plugin - if (host_plugin_id < 0) - { - OutputError("%s could find the host plugin", SQTCC_NAME); - // Don't load! - return SQMOD_FAILURE; - } - // Should never reach this point but just in case - else if (host_plugin_id > (info->nPluginId)) - { - OutputError("%s loaded after the host plugin", SQTCC_NAME); - // Don't load! - return SQMOD_FAILURE; - } - // Store server proxies - _Func = functions; - _Clbk = callbacks; - _Info = info; - // Assign plugin information - _Info->uPluginVer = SQTCC_VERSION; - std::strcpy(_Info->szName, SQTCC_HOST_NAME); - // Bind callbacks - BindCallbacks(); - // Notify that the plugin was successfully loaded - OutputMessage("Successfully loaded %s", SQTCC_NAME); - // Dummy spacing - puts(""); - // Done! - return SQMOD_SUCCESS; -} diff --git a/modules/tcc/Module.hpp b/modules/tcc/Module.hpp deleted file mode 100644 index 8b24547a..00000000 --- a/modules/tcc/Module.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _SQTCC_MODULE_HPP_ -#define _SQTCC_MODULE_HPP_ - -// ------------------------------------------------------------------------------------------------ -#include "SqMod.h" - -// ------------------------------------------------------------------------------------------------ -namespace SqMod { - -/* ------------------------------------------------------------------------------------------------ - * Proxies to comunicate with the server. -*/ -extern PluginFuncs* _Func; -extern PluginCallbacks* _Clbk; -extern PluginInfo* _Info; - -/* ------------------------------------------------------------------------------------------------ - * Proxies to comunicate with the Squirrel plugin. -*/ -extern HSQAPI _SqAPI; -extern HSQEXPORTS _SqMod; -extern HSQUIRRELVM _SqVM; - -/* ------------------------------------------------------------------------------------------------ - * Output a message only if the _DEBUG was defined. -*/ -void OutputDebug(const char * msg, ...); - -/* ------------------------------------------------------------------------------------------------ - * Output a formatted user message to the console. -*/ -void OutputMessage(const char * msg, ...); - -/* ------------------------------------------------------------------------------------------------ - * Output a formatted error message to the console. -*/ -void OutputError(const char * msg, ...); - -} // Namespace:: SqMod - -#endif // _SQTCC_MODULE_HPP_ diff --git a/modules/tcc/State.cpp b/modules/tcc/State.cpp deleted file mode 100644 index 772b4fcc..00000000 --- a/modules/tcc/State.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// ------------------------------------------------------------------------------------------------ -#include "State.hpp" -#include "Symbol.hpp" - -// ------------------------------------------------------------------------------------------------ -#include - -// ------------------------------------------------------------------------------------------------ -namespace SqMod { - -// ------------------------------------------------------------------------------------------------ -SQInteger State::Typename(HSQUIRRELVM vm) -{ - static SQChar name[] = _SC("SqTccState"); - sq_pushstring(vm, name, sizeof(name)); - return 1; -} - -// ------------------------------------------------------------------------------------------------ -void State::AddSource(CSStr filename) const -{ - m_Handle.AddFile(filename, TCC_FILETYPE_C); -} - -// ------------------------------------------------------------------------------------------------ -void State::AddBinary(CSStr filename) const -{ - m_Handle.AddFile(filename, TCC_FILETYPE_BINARY); -} - -// ------------------------------------------------------------------------------------------------ -void State::AddAsm(CSStr filename) const -{ - m_Handle.AddFile(filename, TCC_FILETYPE_ASM); -} - -// ------------------------------------------------------------------------------------------------ -void State::AddAsmPP(CSStr filename) const -{ - m_Handle.AddFile(filename, TCC_FILETYPE_ASM_PP); -} - -// ------------------------------------------------------------------------------------------------ -Symbol State::GetSymbol(CSStr name) const -{ - // Is the specified name even valid? - if (!name || *name == '\0') - { - STHROWF("Invalid or empty symbol name: null"); - } - // Return the requested symbol - return Symbol(m_Handle, name, m_Handle.GetSymbol< Symbol::SymPtr >(name)); -} - -} // Namespace:: SqMod diff --git a/modules/tcc/State.hpp b/modules/tcc/State.hpp deleted file mode 100644 index 0006ad84..00000000 --- a/modules/tcc/State.hpp +++ /dev/null @@ -1,358 +0,0 @@ -#ifndef _SQTCC_STATE_HPP_ -#define _SQTCC_STATE_HPP_ - -// ------------------------------------------------------------------------------------------------ -#include "Common.hpp" - -// ------------------------------------------------------------------------------------------------ -namespace SqMod { - -/* ------------------------------------------------------------------------------------------------ - * Class used to manage a TCC compiler state. -*/ -class State -{ -private: - - // -------------------------------------------------------------------------------------------- - StateHnd m_Handle; // The handle to the managed compiler state resource. - -public: - - /* -------------------------------------------------------------------------------------------- - * Base constructor. - */ - State(CSStr name) - : m_Handle(name) - { - /* ... */ - } - - /* -------------------------------------------------------------------------------------------- - * Direct handle constructor. - */ - State(const StateHnd & h) - : m_Handle(h) - { - /* ... */ - } - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. - */ - State(const State & o) - : m_Handle(o.m_Handle) - { - /* ... */ - } - - /* -------------------------------------------------------------------------------------------- - * Move constructor. - */ - State(State && o) - : m_Handle(o.m_Handle) - { - /* ... */ - } - - /* -------------------------------------------------------------------------------------------- - * Destructor. - */ - ~State() - { - /* Let the reference manager destroy the state when necessary. */ - } - - /* -------------------------------------------------------------------------------------------- - * Copy assignment operator. - */ - State & operator = (const State & o) - { - m_Handle = o.m_Handle; - return *this; - } - - /* -------------------------------------------------------------------------------------------- - * Move assignment operator. - */ - State & operator = (State && o) - { - m_Handle = o.m_Handle; - return *this; - } - - /* -------------------------------------------------------------------------------------------- - * Perform an equality comparison between two states. - */ - bool operator == (const State & o) const - { - return (m_Handle == o.m_Handle); - } - - /* -------------------------------------------------------------------------------------------- - * Perform an inequality comparison between two states. - */ - bool operator != (const State & o) const - { - return (m_Handle != o.m_Handle); - } - - /* -------------------------------------------------------------------------------------------- - * Implicit conversion to the raw state handle. - */ - operator TCCState * () - { - return m_Handle; - } - - /* -------------------------------------------------------------------------------------------- - * Implicit conversion to the raw state handle. - */ - operator TCCState * () const - { - return m_Handle; - } - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to compare two instances of this type. - */ - Int32 Cmp(const State & o) const - { - if (m_Handle == m_Handle) - { - return 0; - } - else if (m_Handle.m_Hnd > o.m_Handle.m_Hnd) - { - return 1; - } - else - { - return -1; - } - } - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to convert an instance of this type to a string. - */ - CSStr ToString() const - { - return m_Handle ? m_Handle->mName.c_str() : _SC(""); - } - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to retrieve the name from instances of this type. - */ - static SQInteger Typename(HSQUIRRELVM vm); - - /* -------------------------------------------------------------------------------------------- - * See whether this state is valid. - */ - bool IsValid() const - { - return m_Handle; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated state handle. - */ - const StateHnd & GetHandle() const - { - return m_Handle; - } - - /* -------------------------------------------------------------------------------------------- - * Return the number of active references to this state handle. - */ - Uint32 GetRefCount() const - { - return m_Handle.Count(); - } - - /* -------------------------------------------------------------------------------------------- - * Release the reference to the associated database state. - */ - void Release() - { - m_Handle.Drop(); - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated state name. - */ - const String & GetName() const - { - // Validate the managed state - m_Handle.Validate(); - // Return the requested information - return m_Handle->mName; - } - - /* -------------------------------------------------------------------------------------------- - * Modify the associated state name. - */ - void SetName(CSStr name) - { - // Validate the managed state - m_Handle.Validate(); - // Apply the specified value - m_Handle->mName.assign(name ? name : _SC("")); - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated state receives events. - */ - bool GetEvents() const - { - // Validate the managed state - m_Handle.Validate(); - // Return the requested information - return StateHnd::IsListed(m_Handle.m_Hnd); - } - - /* -------------------------------------------------------------------------------------------- - * Modify the associated state receives events. - */ - void SetEvents(bool toggle) - { - // Validate the managed state - m_Handle.Validate(); - // Perform the requested operation - if (toggle) - { - StateHnd::Remember(m_Handle.m_Hnd); - } - else - { - StateHnd::Forget(m_Handle.m_Hnd); - } - } - - /* -------------------------------------------------------------------------------------------- - * Move the associated state to the head of the list. - */ - void MakeHead() const - { - // Validate the managed state - m_Handle.Validate(); - // Perform the requested operation - StateHnd::ToHead(m_Handle.m_Hnd); - } - - /* -------------------------------------------------------------------------------------------- - * Set options as from command line (multiple supported). - */ - void SetOptions(CSStr opt) const - { - m_Handle.SetOptions(opt); - } - - /* -------------------------------------------------------------------------------------------- - * Define preprocessor symbol 'sym' without value. - */ - void DefineSymbol(CSStr sym) const - { - m_Handle.DefineSymbol(sym, nullptr); - } - - /* -------------------------------------------------------------------------------------------- - * Define preprocessor symbol 'sym' with value. - */ - void DefineSymbol(CSStr sym, CSStr value) const - { - m_Handle.DefineSymbol(sym, value); - } - - /* -------------------------------------------------------------------------------------------- - * Undefine preprocess symbol 'sym'. - */ - void UndefineSymbol(CSStr sym) const - { - m_Handle.UndefineSymbol(sym); - } - - /* -------------------------------------------------------------------------------------------- - * Add include path. - */ - void AddIncludePath(CSStr path) const - { - m_Handle.AddIncludePath(path); - } - - /* -------------------------------------------------------------------------------------------- - * Add in system include path. - */ - void AddSysIncludePath(CSStr path) const - { - m_Handle.AddSysIncludePath(path); - } - - /* -------------------------------------------------------------------------------------------- - * Set CONFIG_TCCDIR at runtime. - */ - void SetLibPath(CSStr path) const - { - m_Handle.SetLibPath(path); - } - - /* -------------------------------------------------------------------------------------------- - * Equivalent to -Lpath option. - */ - void AddLibraryPath(CSStr path) const - { - m_Handle.AddLibraryPath(path); - } - - /* -------------------------------------------------------------------------------------------- - * The library name is the same as the argument of the '-l' option. - */ - void AddLibrary(CSStr name) const - { - m_Handle.AddLibrary(name); - } - - /* -------------------------------------------------------------------------------------------- - * Compile a string containing a C source. - */ - void CompileString(CSStr str) const - { - m_Handle.CompileString(str); - } - - /* -------------------------------------------------------------------------------------------- - * Add a file containing C source. - */ - void AddSource(CSStr filename) const; - - /* -------------------------------------------------------------------------------------------- - * Add a binary file DLL, Object, Library etc. - */ - void AddBinary(CSStr filename) const; - - /* -------------------------------------------------------------------------------------------- - * Add a file containing assembly code. - */ - void AddAsm(CSStr filename) const; - - /* -------------------------------------------------------------------------------------------- - * Add a file containing assembly code. - */ - void AddAsmPP(CSStr filename) const; - - /* -------------------------------------------------------------------------------------------- - * Do all relocations (needed before using tcc_get_symbol()) - */ - void Relocate() const - { - m_Handle.Relocate(); - } - - /* -------------------------------------------------------------------------------------------- - * Return symbol from the compiled code. - */ - Symbol GetSymbol(CSStr name) const; -}; - -} // Namespace:: SqMod - -#endif // _SQTCC_STATE_HPP_ diff --git a/modules/tcc/Symbol.cpp b/modules/tcc/Symbol.cpp deleted file mode 100644 index 3ee22d7b..00000000 --- a/modules/tcc/Symbol.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// ------------------------------------------------------------------------------------------------ -#include "Symbol.hpp" -#include "State.hpp" - -// ------------------------------------------------------------------------------------------------ -#include - -// ------------------------------------------------------------------------------------------------ -namespace SqMod { - -// ------------------------------------------------------------------------------------------------ -SQInteger Symbol::Typename(HSQUIRRELVM vm) -{ - static SQChar name[] = _SC("SqTccSymbol"); - sq_pushstring(vm, name, sizeof(name)); - return 1; -} - -// ------------------------------------------------------------------------------------------------ -Symbol::Symbol(const State & state, CSStr name) - : Symbol(state.GetSymbol(name)) -{ - /* ... */ -} - -// ------------------------------------------------------------------------------------------------ -Symbol::Symbol(const StateHnd & state, CSStr name, SymPtr sym) - : m_Handle(sym), m_State(state), m_Name(name ? name : _SC("")) -{ - /* ... */ -} - -// ------------------------------------------------------------------------------------------------ -State Symbol::GetStateRef() const -{ - return State(m_State); -} - -// ------------------------------------------------------------------------------------------------ -SQInteger Symbol::Forward(HSQUIRRELVM vm) -{ - // The symbol instance - Symbol * symbol = nullptr; - // Attempt to retrieve the symbol instance - try - { - symbol = Var< Symbol * >(vm, 1).value; - } - catch (const Sqrat::Exception & e) - { - // Propagate the error - return sq_throwerror(vm, e.Message().c_str()); - } - // Do we have a valid symbol instance? - if (!symbol) - { - return sq_throwerror(vm, "Invalid symbol instance"); - } - // Do we have a valid symbol identifier? - else if (!symbol->IsValid()) - { - return sq_throwerror(vm, "Invalid symbol reference"); - } - // Cast the symbol to a squirrel function, forward the call and return the result - return reinterpret_cast< SQFUNCTION >((*symbol).m_Handle)(vm); -} - -} // Namespace:: SqMod diff --git a/modules/tcc/Symbol.hpp b/modules/tcc/Symbol.hpp deleted file mode 100644 index 53c1bb5f..00000000 --- a/modules/tcc/Symbol.hpp +++ /dev/null @@ -1,215 +0,0 @@ -#ifndef _SQTCC_SYMBOL_HPP_ -#define _SQTCC_SYMBOL_HPP_ - -// ------------------------------------------------------------------------------------------------ -#include "Common.hpp" - -// ------------------------------------------------------------------------------------------------ -namespace SqMod { - -/* ------------------------------------------------------------------------------------------------ - * -*/ -class Symbol -{ - // -------------------------------------------------------------------------------------------- - friend class State; - -public: - - // -------------------------------------------------------------------------------------------- - typedef void * SymPtr; // The type of value that represents a symbol in the compiler state. - -private: - - // -------------------------------------------------------------------------------------------- - SymPtr m_Handle; // Pointer to the actual retrieved symbol. - StateHnd m_State; // The state from where this symbol was retrieved. - String m_Name; // The name of the retrieved symbol. - -protected: - - /* -------------------------------------------------------------------------------------------- - * Use the specified symbol and name. - */ - Symbol(const StateHnd & state, CSStr name, SymPtr sym); - -public: - - /* -------------------------------------------------------------------------------------------- - * Extract the symbol from the specified state. - */ - Symbol(const State & state, CSStr name); - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. - */ - Symbol(const Symbol & o) - : m_Handle(o.m_Handle) - , m_State(o.m_State) - , m_Name(o.m_Name) - { - /* ... */ - } - - /* -------------------------------------------------------------------------------------------- - * Move constructor. - */ - Symbol(Symbol && o) - : m_Handle(o.m_Handle) - , m_State(o.m_State) - , m_Name(o.m_Name) - { - /* ... */ - } - - /* -------------------------------------------------------------------------------------------- - * Destructor. - */ - ~Symbol() - { - /* Let the reference manager destroy the state when necessary. */ - } - - /* -------------------------------------------------------------------------------------------- - * Copy assignment operator. - */ - Symbol & operator = (const Symbol & o) - { - m_Handle = o.m_Handle; - m_State = o.m_State; - m_Name = o.m_Name; - return *this; - } - - /* -------------------------------------------------------------------------------------------- - * Move assignment operator. - */ - Symbol & operator = (Symbol && o) - { - m_Handle = o.m_Handle; - m_State = o.m_State; - m_Name = o.m_Name; - return *this; - } - - /* -------------------------------------------------------------------------------------------- - * Perform an equality comparison between two symbols. - */ - bool operator == (const Symbol & o) const - { - return (m_Handle == o.m_Handle); - } - - /* -------------------------------------------------------------------------------------------- - * Perform an inequality comparison between two symbols. - */ - bool operator != (const Symbol & o) const - { - return (m_Handle != o.m_Handle); - } - - /* -------------------------------------------------------------------------------------------- - * Implicit conversion to the raw state handle. - */ - operator TCCState * () - { - return m_State; - } - - /* -------------------------------------------------------------------------------------------- - * Implicit conversion to the raw state handle. - */ - operator TCCState * () const - { - return m_State; - } - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to compare two instances of this type. - */ - Int32 Cmp(const Symbol & o) const - { - if (m_Handle == m_Handle) - { - return 0; - } - else if (m_Handle > o.m_Handle) - { - return 1; - } - else - { - return -1; - } - } - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to convert an instance of this type to a string. - */ - const String & ToString() const - { - return m_Name; - } - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to retrieve the name from instances of this type. - */ - static SQInteger Typename(HSQUIRRELVM vm); - - /* -------------------------------------------------------------------------------------------- - * See whether this symbol is valid. - */ - bool IsValid() const - { - return m_Handle; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated symbol handle. - */ - SymPtr GetHandle() const - { - return m_Handle; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated state handle. - */ - const StateHnd & GetState() const - { - return m_State; - } - - /* -------------------------------------------------------------------------------------------- - * Return the number of active references to this state handle. - */ - Uint32 GetRefCount() const - { - return m_State.Count(); - } - - /* -------------------------------------------------------------------------------------------- - * Release the reference to the associated database state. - */ - void Release() - { - m_Handle = nullptr; - m_Name.clear(); - m_State.Drop(); - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated state as a reference in script. - */ - State GetStateRef() const; - - /* -------------------------------------------------------------------------------------------- - * Forward this call to the actual associated symbol. - */ - static SQInteger Forward(HSQUIRRELVM vm); -}; - -} // Namespace:: SqMod - -#endif // _SQTCC_SYMBOL_HPP_ diff --git a/modules/xml/Module.cpp b/modules/xml/Module.cpp index aefbb687..08d880f4 100644 --- a/modules/xml/Module.cpp +++ b/modules/xml/Module.cpp @@ -124,12 +124,12 @@ bool CheckAPIVer(CCStr ver) /* -------------------------------------------------------------------------------------------- * React to command sent by other plugins. */ -static int OnInternalCommand(unsigned int type, const char * text) +static uint8_t OnPluginCommand(uint32_t command_identifier, CCStr message) { - switch(type) + switch(command_identifier) { case SQMOD_INITIALIZE_CMD: - if (CheckAPIVer(text)) + if (CheckAPIVer(message)) { OnSquirrelInitialize(); } @@ -148,12 +148,12 @@ static int OnInternalCommand(unsigned int type, const char * text) /* -------------------------------------------------------------------------------------------- * The server was initialized and this plugin was loaded successfully. */ -static int OnInitServer() +static uint8_t OnServerInitialise() { return 1; } -static void OnShutdownServer(void) +static void OnServerShutdown(void) { // The server may still send callbacks UnbindCallbacks(); @@ -162,17 +162,17 @@ static void OnShutdownServer(void) // ------------------------------------------------------------------------------------------------ void BindCallbacks() { - _Clbk->OnInitServer = OnInitServer; - _Clbk->OnInternalCommand = OnInternalCommand; - _Clbk->OnShutdownServer = OnShutdownServer; + _Clbk->OnServerInitialise = OnServerInitialise; + _Clbk->OnServerShutdown = OnServerShutdown; + _Clbk->OnPluginCommand = OnPluginCommand; } // ------------------------------------------------------------------------------------------------ void UnbindCallbacks() { - _Clbk->OnInitServer = nullptr; - _Clbk->OnInternalCommand = nullptr; - _Clbk->OnShutdownServer = nullptr; + _Clbk->OnServerInitialise = nullptr; + _Clbk->OnServerShutdown = nullptr; + _Clbk->OnPluginCommand = nullptr; } // -------------------------------------------------------------------------------------------- @@ -482,17 +482,17 @@ void OutputMessageImpl(const char * msg, va_list args) CONSOLE_SCREEN_BUFFER_INFO csb_before; GetConsoleScreenBufferInfo( hstdout, &csb_before); SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN); - printf("[SQMOD] "); + std::printf("[SQMOD] "); SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); - vprintf(msg, args); - puts(""); + std::vprintf(msg, args); + std::puts(""); SetConsoleTextAttribute(hstdout, csb_before.wAttributes); #else - printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27); - vprintf(msg, args); - puts(""); + std::printf("%c[0;32m[SQMOD]%c[0m", 27, 27); + std::vprintf(msg, args); + std::puts(""); #endif } @@ -505,17 +505,17 @@ void OutputErrorImpl(const char * msg, va_list args) CONSOLE_SCREEN_BUFFER_INFO csb_before; GetConsoleScreenBufferInfo( hstdout, &csb_before); SetConsoleTextAttribute(hstdout, FOREGROUND_RED | FOREGROUND_INTENSITY); - printf("[SQMOD] "); + std::printf("[SQMOD] "); SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); - vprintf(msg, args); - puts(""); + std::vprintf(msg, args); + std::puts(""); SetConsoleTextAttribute(hstdout, csb_before.wAttributes); #else - printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27); - vprintf(msg, args); - puts(""); + std::printf("%c[0;91m[SQMOD]%c[0m", 27, 27); + std::vprintf(msg, args); + std::puts(""); #endif } @@ -583,7 +583,7 @@ SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs* functions, PluginCallb return SQMOD_FAILURE; } // Should never reach this point but just in case - else if (host_plugin_id > (info->nPluginId)) + else if (static_cast< Uint32 >(host_plugin_id) > info->pluginId) { OutputError("%s loaded after the host plugin", SQXML_NAME); // Don't load! @@ -593,9 +593,12 @@ SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs* functions, PluginCallb _Func = functions; _Clbk = callbacks; _Info = info; - // Assign plugin information - _Info->uPluginVer = SQXML_VERSION; - std::strcpy(_Info->szName, SQXML_HOST_NAME); + // Assign plugin version + _Info->pluginVersion = SQXML_VERSION; + _Info->apiMajorVersion = PLUGIN_API_MAJOR; + _Info->apiMinorVersion = PLUGIN_API_MINOR; + // Assign the plugin name + std::snprintf(_Info->name, sizeof(_Info->name), "%s", SQXML_HOST_NAME); // Bind callbacks BindCallbacks(); // Notify that the plugin was successfully loaded diff --git a/shared/SqMod.inl b/shared/SqMod.inl index 3cfb878f..58c6ada1 100644 --- a/shared/SqMod.inl +++ b/shared/SqMod.inl @@ -195,7 +195,7 @@ HSQEXPORTS sq_api_import(PluginFuncs * vcapi) // Attempt to find the main plugin ID int plugin_id = vcapi->FindPlugin((char *)(SQMOD_HOST_NAME)); // Attempt to retrieve the plugin exports - void ** plugin_exports = vcapi->GetPluginExports(plugin_id, &struct_size); + const void ** plugin_exports = vcapi->GetPluginExports(plugin_id, &struct_size); // See if we have any imports from Squirrel if (plugin_exports == NULL || struct_size <= 0) { diff --git a/source/Base/AABB.cpp b/source/Base/AABB.cpp index 22fb9d8e..01137ba5 100644 --- a/source/Base/AABB.cpp +++ b/source/Base/AABB.cpp @@ -17,7 +17,7 @@ SQChar AABB::Delim = ','; // ------------------------------------------------------------------------------------------------ SQInteger AABB::Typename(HSQUIRRELVM vm) { - static SQChar name[] = _SC("AABB"); + static const SQChar name[] = _SC("AABB"); sq_pushstring(vm, name, sizeof(name)); return 1; } @@ -31,14 +31,14 @@ AABB::AABB() // ------------------------------------------------------------------------------------------------ AABB::AABB(Value sv) - : min(-sv), max(fabs(sv)) + : min(-sv), max(std::fabs(sv)) { /* ... */ } // ------------------------------------------------------------------------------------------------ AABB::AABB(Value xv, Value yv, Value zv) - : min(-xv, -yv, -zv), max(fabs(xv), fabs(yv), fabs(zv)) + : min(-xv, -yv, -zv), max(std::fabs(xv), std::fabs(yv), std::fabs(zv)) { /* ... */ } @@ -61,7 +61,7 @@ AABB::AABB(const Vector3 & vmin, const Vector3 & vmax) AABB & AABB::operator = (Value s) { min.Set(-s); - max.Set(fabs(s)); + max.Set(std::fabs(s)); return *this; } @@ -281,11 +281,17 @@ bool AABB::operator >= (const AABB & b) const Int32 AABB::Cmp(const AABB & o) const { if (*this == o) + { return 0; + } else if (*this > o) + { return 1; + } else + { return -1; + } } // ------------------------------------------------------------------------------------------------ @@ -298,13 +304,13 @@ CSStr AABB::ToString() const void AABB::Set(Value ns) { min = -ns; - max = fabs(ns); + max = std::fabs(ns); } void AABB::Set(Value nx, Value ny, Value nz) { min.Set(-nx, -ny, -nz); - max.Set(fabs(nx), fabs(ny), fabs(nz)); + max.Set(std::fabs(nx), std::fabs(ny), std::fabs(nz)); } void AABB::Set(Value xmin, Value ymin, Value zmin, Value xmax, Value ymax, Value zmax) @@ -349,7 +355,7 @@ void AABB::Set(const Vector4 & nmin, const Vector4 & nmax) // ------------------------------------------------------------------------------------------------ void AABB::Set(CSStr values, SQChar delim) { - Set(GetAABB(values, delim)); + Set(AABB::Get(values, delim)); } // ------------------------------------------------------------------------------------------------ @@ -359,13 +365,13 @@ AABB AABB::Abs() const } // ------------------------------------------------------------------------------------------------ -const AABB & GetAABB(CSStr str) +const AABB & AABB::Get(CSStr str) { - return GetAABB(str, AABB::Delim); + return AABB::Get(str, AABB::Delim); } // ------------------------------------------------------------------------------------------------ -const AABB & GetAABB(CSStr str, SQChar delim) +const AABB & AABB::Get(CSStr str, SQChar delim) { // The format specifications that will be used to scan the string static SQChar fs[] = _SC(" %f , %f , %f , %f , %f , %f "); @@ -389,89 +395,132 @@ const AABB & GetAABB(CSStr str, SQChar delim) return box; } +// ------------------------------------------------------------------------------------------------ +const AABB & GetAABB() +{ + static AABB box; + box.Clear(); + return box; +} + +const AABB & GetAABB(Float32 sv) +{ + static AABB box; + box.Set(sv); + return box; +} + +const AABB & GetAABB(Float32 xv, Float32 yv, Float32 zv) +{ + static AABB box; + box.Set(xv, yv, zv); + return box; +} + +const AABB & GetAABB(Float32 xmin, Float32 ymin, Float32 zmin, Float32 xmax, Float32 ymax, Float32 zmax) +{ + static AABB box; + box.Set(xmin, ymin, zmin, xmax, ymax, zmax); + return box; +} + +const AABB & GetAABB(const Vector3 & vmin, const Vector3 & vmax) +{ + static AABB box; + box.Set(vmin, vmax); + return box; +} + +const AABB & GetAABB(const AABB & o) +{ + static AABB box; + box.Set(o); + return box; +} + // ================================================================================================ void Register_AABB(HSQUIRRELVM vm) { typedef AABB::Value Val; RootTable(vm).Bind(_SC("AABB"), Class< AABB >(vm, _SC("AABB")) - /* Constructors */ + // Constructors .Ctor() .Ctor< Val >() .Ctor< Val, Val, Val >() .Ctor< Val, Val, Val, Val, Val, Val >() .Ctor< const Vector3 &, const Vector3 & >() - /* Static Members */ - .SetStaticValue(_SC("delim"), &AABB::Delim) - /* Member Variables */ - .Var(_SC("min"), &AABB::min) - .Var(_SC("max"), &AABB::max) - /* Properties */ - .Prop(_SC("abs"), &AABB::Abs) - /* Core Metamethods */ + // Static Members + .SetStaticValue(_SC("Delim"), &AABB::Delim) + // Member Variables + .Var(_SC("Min"), &AABB::min) + .Var(_SC("Max"), &AABB::max) + // Properties + .Prop(_SC("Abs"), &AABB::Abs) + // Core Metamethods .Func(_SC("_tostring"), &AABB::ToString) .SquirrelFunc(_SC("_typename"), &AABB::Typename) .Func(_SC("_cmp"), &AABB::Cmp) - /* Metamethods */ - .Func(_SC("_add"), &AABB::operator +) - .Func(_SC("_sub"), &AABB::operator -) - .Func(_SC("_mul"), &AABB::operator *) - .Func(_SC("_div"), &AABB::operator /) - .Func(_SC("_modulo"), &AABB::operator %) - .Func(_SC("_unm"), &AABB::operator -) - /* Setters */ - .Overload(_SC("Set"), &AABB::Set) - .Overload(_SC("Set"), &AABB::Set) - .Overload(_SC("Set"), &AABB::Set) - .Overload(_SC("SetBox"), &AABB::Set) - .Overload(_SC("SetVec3"), &AABB::Set) - .Overload(_SC("SetVec3"), &AABB::Set) - .Overload(_SC("SetVec4"), &AABB::Set) - .Overload(_SC("SetVec4"), &AABB::Set) - .Overload(_SC("SetStr"), &AABB::Set) - /* Utility Methods */ + // Metamethods + .Func< AABB (AABB::*)(const AABB &) const >(_SC("_add"), &AABB::operator +) + .Func< AABB (AABB::*)(const AABB &) const >(_SC("_sub"), &AABB::operator -) + .Func< AABB (AABB::*)(const AABB &) const >(_SC("_mul"), &AABB::operator *) + .Func< AABB (AABB::*)(const AABB &) const >(_SC("_div"), &AABB::operator /) + .Func< AABB (AABB::*)(const AABB &) const >(_SC("_modulo"), &AABB::operator %) + .Func< AABB (AABB::*)(void) const >(_SC("_unm"), &AABB::operator -) + // Setters + .Overload< void (AABB::*)(Val) >(_SC("Set"), &AABB::Set) + .Overload< void (AABB::*)(Val, Val, Val) >(_SC("Set"), &AABB::Set) + .Overload< void (AABB::*)(Val, Val, Val, Val, Val, Val) >(_SC("Set"), &AABB::Set) + .Overload< void (AABB::*)(const AABB &) >(_SC("SetBox"), &AABB::Set) + .Overload< void (AABB::*)(const Vector3 &) >(_SC("SetVec3"), &AABB::Set) + .Overload< void (AABB::*)(const Vector3 &, const Vector3 &) >(_SC("SetVec3"), &AABB::Set) + .Overload< void (AABB::*)(const Vector4 &) >(_SC("SetVec4"), &AABB::Set) + .Overload< void (AABB::*)(const Vector4 &, const Vector4 &) >(_SC("SetVec4"), &AABB::Set) + .Overload< void (AABB::*)(CSStr, SQChar) >(_SC("SetStr"), &AABB::Set) + // Utility Methods .Func(_SC("Clear"), &AABB::Clear) - /* Operator Exposure */ - .Func(_SC("opAddAssign"), &AABB::operator +=) - .Func(_SC("opSubAssign"), &AABB::operator -=) - .Func(_SC("opMulAssign"), &AABB::operator *=) - .Func(_SC("opDivAssign"), &AABB::operator /=) - .Func(_SC("opModAssign"), &AABB::operator %=) - - .Func(_SC("opAddAssignS"), &AABB::operator +=) - .Func(_SC("opSubAssignS"), &AABB::operator -=) - .Func(_SC("opMulAssignS"), &AABB::operator *=) - .Func(_SC("opDivAssignS"), &AABB::operator /=) - .Func(_SC("opModAssignS"), &AABB::operator %=) - - .Func(_SC("opPreInc"), &AABB::operator ++) - .Func(_SC("opPreDec"), &AABB::operator --) - .Func(_SC("opPostInc"), &AABB::operator ++) - .Func(_SC("opPostDec"), &AABB::operator --) - - .Func(_SC("opAdd"), &AABB::operator +) - .Func(_SC("opAddS"), &AABB::operator +) - .Func(_SC("opSub"), &AABB::operator -) - .Func(_SC("opSubS"), &AABB::operator -) - .Func(_SC("opMul"), &AABB::operator *) - .Func(_SC("opMulS"), &AABB::operator *) - .Func(_SC("opDiv"), &AABB::operator /) - .Func(_SC("opDivS"), &AABB::operator /) - .Func(_SC("opMod"), &AABB::operator %) - .Func(_SC("opModS"), &AABB::operator %) - - .Func(_SC("opUnPlus"), &AABB::operator +) - .Func(_SC("opUnMinus"), &AABB::operator -) - - .Func(_SC("opEqual"), &AABB::operator ==) - .Func(_SC("opNotEqual"), &AABB::operator !=) - .Func(_SC("opLessThan"), &AABB::operator <) - .Func(_SC("opGreaterThan"), &AABB::operator >) - .Func(_SC("opLessEqual"), &AABB::operator <=) - .Func(_SC("opGreaterEqual"), &AABB::operator >=) // Static Overloads - .StaticOverload< const AABB & (*)(CSStr) >(_SC("FromStr"), &GetAABB) - .StaticOverload< const AABB & (*)(CSStr, SQChar) >(_SC("FromStr"), &GetAABB) + .StaticOverload< const AABB & (*)(CSStr) >(_SC("FromStr"), &AABB::Get) + .StaticOverload< const AABB & (*)(CSStr, SQChar) >(_SC("FromStr"), &AABB::Get) + // Operator Exposure + .Func< AABB & (AABB::*)(const AABB &) >(_SC("opAddAssign"), &AABB::operator +=) + .Func< AABB & (AABB::*)(const AABB &) >(_SC("opSubAssign"), &AABB::operator -=) + .Func< AABB & (AABB::*)(const AABB &) >(_SC("opMulAssign"), &AABB::operator *=) + .Func< AABB & (AABB::*)(const AABB &) >(_SC("opDivAssign"), &AABB::operator /=) + .Func< AABB & (AABB::*)(const AABB &) >(_SC("opModAssign"), &AABB::operator %=) + + .Func< AABB & (AABB::*)(AABB::Value) >(_SC("opAddAssignS"), &AABB::operator +=) + .Func< AABB & (AABB::*)(AABB::Value) >(_SC("opSubAssignS"), &AABB::operator -=) + .Func< AABB & (AABB::*)(AABB::Value) >(_SC("opMulAssignS"), &AABB::operator *=) + .Func< AABB & (AABB::*)(AABB::Value) >(_SC("opDivAssignS"), &AABB::operator /=) + .Func< AABB & (AABB::*)(AABB::Value) >(_SC("opModAssignS"), &AABB::operator %=) + + .Func< AABB & (AABB::*)(void) >(_SC("opPreInc"), &AABB::operator ++) + .Func< AABB & (AABB::*)(void) >(_SC("opPreDec"), &AABB::operator --) + .Func< AABB (AABB::*)(int) >(_SC("opPostInc"), &AABB::operator ++) + .Func< AABB (AABB::*)(int) >(_SC("opPostDec"), &AABB::operator --) + + .Func< AABB (AABB::*)(const AABB &) const >(_SC("opAdd"), &AABB::operator +) + .Func< AABB (AABB::*)(AABB::Value) const >(_SC("opAddS"), &AABB::operator +) + .Func< AABB (AABB::*)(const AABB &) const >(_SC("opSub"), &AABB::operator -) + .Func< AABB (AABB::*)(AABB::Value) const >(_SC("opSubS"), &AABB::operator -) + .Func< AABB (AABB::*)(const AABB &) const >(_SC("opMul"), &AABB::operator *) + .Func< AABB (AABB::*)(AABB::Value) const >(_SC("opMulS"), &AABB::operator *) + .Func< AABB (AABB::*)(const AABB &) const >(_SC("opDiv"), &AABB::operator /) + .Func< AABB (AABB::*)(AABB::Value) const >(_SC("opDivS"), &AABB::operator /) + .Func< AABB (AABB::*)(const AABB &) const >(_SC("opMod"), &AABB::operator %) + .Func< AABB (AABB::*)(AABB::Value) const >(_SC("opModS"), &AABB::operator %) + + .Func< AABB (AABB::*)(void) const >(_SC("opUnPlus"), &AABB::operator +) + .Func< AABB (AABB::*)(void) const >(_SC("opUnMinus"), &AABB::operator -) + + .Func< bool (AABB::*)(const AABB &) const >(_SC("opEqual"), &AABB::operator ==) + .Func< bool (AABB::*)(const AABB &) const >(_SC("opNotEqual"), &AABB::operator !=) + .Func< bool (AABB::*)(const AABB &) const >(_SC("opLessThan"), &AABB::operator <) + .Func< bool (AABB::*)(const AABB &) const >(_SC("opGreaterThan"), &AABB::operator >) + .Func< bool (AABB::*)(const AABB &) const >(_SC("opLessEqual"), &AABB::operator <=) + .Func< bool (AABB::*)(const AABB &) const >(_SC("opGreaterEqual"), &AABB::operator >=) ); } diff --git a/source/Base/AABB.hpp b/source/Base/AABB.hpp index e6af59ff..82246871 100644 --- a/source/Base/AABB.hpp +++ b/source/Base/AABB.hpp @@ -7,16 +7,6 @@ // ------------------------------------------------------------------------------------------------ namespace SqMod { -/* ------------------------------------------------------------------------------------------------ - * Extract the values for components of the AABB type from a string. -*/ -const AABB & GetAABB(CSStr str); - -/* ------------------------------------------------------------------------------------------------ - * Extract the values for components of the AABB type from a string. -*/ -const AABB & GetAABB(CSStr str, SQChar delim); - /* ------------------------------------------------------------------------------------------------ * Class used to represent an axis aligned bounding box in three-dimensional space. */ @@ -351,6 +341,17 @@ struct AABB * Retrieve a new instance of this type with absolute component values. */ AABB Abs() const; + + /* -------------------------------------------------------------------------------------------- + * Extract the values for components of the AABB type from a string. + */ + static const AABB & Get(CSStr str); + + /* -------------------------------------------------------------------------------------------- + * Extract the values for components of the AABB type from a string. + */ + static const AABB & Get(CSStr str, SQChar delim); + }; } // Namespace:: SqMod diff --git a/source/Base/Buffer.cpp b/source/Base/Buffer.cpp index a68e57b4..e4d15fa1 100644 --- a/source/Base/Buffer.cpp +++ b/source/Base/Buffer.cpp @@ -4,7 +4,6 @@ // ------------------------------------------------------------------------------------------------ #include #include -#include #include #include @@ -35,9 +34,9 @@ void ThrowMemExcept(const char * msg, ...) // Variable arguments structure va_list args; // Get the specified arguments - va_start (args, msg); + va_start(args, msg); // Run the specified format - int ret = vsnprintf(buffer, sizeof(buffer), msg, args); + int ret = std::vsnprintf(buffer, sizeof(buffer), msg, args); // Check for formatting errors if (ret < 0) { @@ -53,7 +52,7 @@ void ThrowMemExcept(const char * msg, ...) static Buffer::Pointer AllocMem(Buffer::SzType size) { // Attempt to allocate memory directly - Buffer::Pointer ptr = reinterpret_cast< Buffer::Pointer >(malloc(size)); + Buffer::Pointer ptr = reinterpret_cast< Buffer::Pointer >(std::malloc(size)); // Validate the allocated memory if (!ptr) { @@ -96,9 +95,9 @@ private: struct Node { // ---------------------------------------------------------------------------------------- - SzType mCap; /* The size of the memory chunk. */ - Pointer mPtr; /* Pointer to the memory chunk. */ - Node* mNext; /* The next node in the list. */ + SzType mCap; // The size of the memory chunk. + Pointer mPtr; // Pointer to the memory chunk. + Node* mNext; // The next node in the list. /* ---------------------------------------------------------------------------------------- * Base constructor. @@ -137,7 +136,7 @@ private: // Free the memory (if any) if (node->mPtr) { - free(node->mPtr); + std::free(node->mPtr); } // Save the next node next = node->mNext; @@ -385,7 +384,7 @@ Buffer::Buffer(const Buffer & o) if (m_Cap) { Request(o.m_Cap); - memcpy(m_Ptr, o.m_Ptr, o.m_Cap); + std::memcpy(m_Ptr, o.m_Ptr, o.m_Cap); } } @@ -408,7 +407,7 @@ Buffer & Buffer::operator = (const Buffer & o) if (m_Cap && o.m_Cap <= m_Cap) { // It's safe to copy the data - memcpy(m_Ptr, o.m_Ptr, o.m_Cap); + std::memcpy(m_Ptr, o.m_Ptr, o.m_Cap); } // Do we even have data to copy? else if (!o.m_Cap) @@ -429,7 +428,7 @@ Buffer & Buffer::operator = (const Buffer & o) // Request a larger buffer Request(o.m_Cap); // Now it's safe to copy the data - memcpy(m_Ptr, o.m_Ptr, o.m_Cap); + std::memcpy(m_Ptr, o.m_Ptr, o.m_Cap); } // Also copy the edit cursor m_Cur = o.m_Cur; @@ -446,7 +445,7 @@ void Buffer::Grow(SzType n) // Acquire a bigger buffer Request(bkp.m_Cap + n); // Copy the data from the old buffer - memcpy(m_Ptr, bkp.m_Ptr, bkp.m_Cap); + std::memcpy(m_Ptr, bkp.m_Ptr, bkp.m_Cap); // Copy the previous edit cursor m_Cur = bkp.m_Cur; } @@ -487,7 +486,7 @@ void Buffer::Release() // Is there a memory manager available? if (!m_Mem) { - free(m_Ptr); // Deallocate the memory directly + std::free(m_Ptr); // Deallocate the memory directly } // Find out to which category does this buffer belong else if (m_Cap <= 1024) @@ -523,7 +522,7 @@ Buffer::SzType Buffer::Write(SzType pos, ConstPtr data, SzType size) Grow((pos + size) - m_Cap + 32); } // Copy the data into the internal buffer - memcpy(m_Ptr + pos, data, size); + std::memcpy(m_Ptr + pos, data, size); // Return the amount of data written to the buffer return size; } @@ -556,14 +555,14 @@ Buffer::SzType Buffer::WriteF(SzType pos, const char * fmt, va_list args) va_copy(args_cpy, args); // Attempt to write to the current buffer // (if empty, it should tell us the necessary size) - int ret = vsnprintf(m_Ptr + pos, m_Cap, fmt, args); + int ret = std::vsnprintf(m_Ptr + pos, m_Cap, fmt, args); // Do we need a bigger buffer? if ((pos + ret) >= m_Cap) { // Acquire a larger buffer Grow((pos + ret) - m_Cap + 32); // Retry writing the requested information - ret = vsnprintf(m_Ptr + pos, m_Cap, fmt, args_cpy); + ret = std::vsnprintf(m_Ptr + pos, m_Cap, fmt, args_cpy); } // Return the value 0 if data could not be written if (ret < 0) @@ -581,7 +580,7 @@ Buffer::SzType Buffer::WriteS(SzType pos, ConstPtr str) if (str && *str != '\0') { // Forward this to the regular write function - return Write(pos, str, strlen(str)); + return Write(pos, str, std::strlen(str)); } // Nothing to write return 0; @@ -605,7 +604,7 @@ void Buffer::AppendS(const char * str) // Is there any string to write? if (str) { - m_Cur += Write(m_Cur, str, strlen(str)); + m_Cur += Write(m_Cur, str, std::strlen(str)); } } diff --git a/source/Base/Buffer.hpp b/source/Base/Buffer.hpp index fda828bf..82c3b8c9 100644 --- a/source/Base/Buffer.hpp +++ b/source/Base/Buffer.hpp @@ -161,6 +161,17 @@ public: assert(m_Ptr); return *m_Ptr; } + + /* -------------------------------------------------------------------------------------------- + * Release the reference to the managed instance. + */ + void Reset() + { + if (m_Ptr) + { + Drop(); + } + } }; // ------------------------------------------------------------------------------------------------ @@ -206,7 +217,7 @@ private: public: /* -------------------------------------------------------------------------------------------- - * Default constructor (null). Not null of a previous buffer was marked as movable. + * Default constructor. (null) */ Buffer() : m_Ptr(nullptr) @@ -365,20 +376,20 @@ public: } /* -------------------------------------------------------------------------------------------- - * Retrieve the a certain element. + * Retrieve a certain element type at the specified position. */ template < typename T = Value > T & At(SzType n) { - assert(n < m_Cap); + assert(n < static_cast< SzType >(m_Cap / sizeof(T))); return reinterpret_cast< T * >(m_Ptr)[n]; } /* -------------------------------------------------------------------------------------------- - * Retrieve the a certain element. + * Retrieve a certain element type at the specified position. */ template < typename T = Value > const T & At(SzType n) const { - assert(n < m_Cap); + assert(n < static_cast< SzType >(m_Cap / sizeof(T))); return reinterpret_cast< const T * >(m_Ptr)[n]; } @@ -456,7 +467,7 @@ public: template < typename T = Value > T & Back() { assert(m_Cap >= sizeof(T)); - return reinterpret_cast< T * >(m_Ptr)[m_Cap-1]; + return reinterpret_cast< T * >(m_Ptr)[(m_Cap / sizeof(T))-1]; } /* -------------------------------------------------------------------------------------------- @@ -465,7 +476,7 @@ public: template < typename T = Value > const T & Back() const { assert(m_Cap >= sizeof(T)); - return reinterpret_cast< const T * >(m_Ptr)[m_Cap-1]; + return reinterpret_cast< const T * >(m_Ptr)[(m_Cap / sizeof(T))-1]; } /* -------------------------------------------------------------------------------------------- @@ -474,7 +485,7 @@ public: template < typename T = Value > T & Prev() { assert(m_Cap >= (sizeof(T) * 2)); - return reinterpret_cast< T * >(m_Ptr)[m_Cap-2]; + return reinterpret_cast< T * >(m_Ptr)[(m_Cap / sizeof(T))-2]; } /* -------------------------------------------------------------------------------------------- @@ -483,7 +494,7 @@ public: template < typename T = Value > const T & Prev() const { assert(m_Cap >= (sizeof(T) * 2)); - return reinterpret_cast< const T * >(m_Ptr)[m_Cap-2]; + return reinterpret_cast< const T * >(m_Ptr)[(m_Cap / sizeof(T))-2]; } /* -------------------------------------------------------------------------------------------- @@ -532,7 +543,7 @@ public: } /* -------------------------------------------------------------------------------------------- - * Reposition the edit cursor to a fixed position within the buffer. + * Append a value to the current cursor location and advance the cursor. */ template < typename T = Value > void Push(T v) { @@ -571,7 +582,7 @@ public: template < typename T = Value > T & Before() { assert(m_Cur >= sizeof(T)); - return reinterpret_cast< T * >(m_Ptr)[m_Cur-1]; + return reinterpret_cast< T * >(m_Ptr)[(m_Cur / sizeof(T))-1]; } /* -------------------------------------------------------------------------------------------- @@ -580,7 +591,7 @@ public: template < typename T = Value > const T & Before() const { assert(m_Cur >= sizeof(T)); - return reinterpret_cast< const T * >(m_Ptr)[m_Cur-1]; + return reinterpret_cast< const T * >(m_Ptr)[(m_Cur / sizeof(T))-1]; } /* -------------------------------------------------------------------------------------------- @@ -588,8 +599,8 @@ public: */ template < typename T = Value > T & After() { - assert((m_Cur + sizeof(T)) <= (m_Cap - sizeof(T))); - return reinterpret_cast< T * >(m_Ptr)[m_Cur+1]; + assert(m_Cap >= sizeof(T) && (m_Cur + sizeof(T)) <= (m_Cap - sizeof(T))); + return reinterpret_cast< T * >(m_Ptr)[(m_Cur / sizeof(T))+1]; } /* -------------------------------------------------------------------------------------------- @@ -597,8 +608,8 @@ public: */ template < typename T = Value > const T & After() const { - assert((m_Cur + sizeof(T)) <= (m_Cap - sizeof(T))); - return reinterpret_cast< const T * >(m_Ptr)[m_Cur+1]; + assert(m_Cap >= sizeof(T) && (m_Cur + sizeof(T)) <= (m_Cap - sizeof(T))); + return reinterpret_cast< const T * >(m_Ptr)[(m_Cur / sizeof(T))+1]; } /* -------------------------------------------------------------------------------------------- @@ -691,6 +702,18 @@ public: } } + /* -------------------------------------------------------------------------------------------- + * Release the managed memory and manager. + */ + void ResetAll() + { + if (m_Ptr) + { + Release(); + } + m_Mem.Reset(); + } + /* -------------------------------------------------------------------------------------------- * Swap the contents of two buffers. */ diff --git a/source/Base/Circle.cpp b/source/Base/Circle.cpp index bc2747d2..1673ea61 100644 --- a/source/Base/Circle.cpp +++ b/source/Base/Circle.cpp @@ -20,7 +20,7 @@ SQChar Circle::Delim = ','; // ------------------------------------------------------------------------------------------------ SQInteger Circle::Typename(HSQUIRRELVM vm) { - static SQChar name[] = _SC("Circle"); + static const SQChar name[] = _SC("Circle"); sq_pushstring(vm, name, sizeof(name)); return 1; } @@ -98,7 +98,7 @@ Circle & Circle::operator /= (const Circle & c) Circle & Circle::operator %= (const Circle & c) { pos %= c.pos; - rad = fmod(rad, c.rad); + rad = std::fmod(rad, c.rad); return *this; } @@ -130,7 +130,7 @@ Circle & Circle::operator /= (Value r) Circle & Circle::operator %= (Value r) { - rad = fmod(rad, r); + rad = std::fmod(rad, r); return *this; } @@ -220,7 +220,7 @@ Circle Circle::operator / (const Circle & c) const Circle Circle::operator % (const Circle & c) const { - return Circle(pos % c.pos, fmod(rad, c.rad)); + return Circle(pos % c.pos, std::fmod(rad, c.rad)); } // ------------------------------------------------------------------------------------------------ @@ -246,7 +246,7 @@ Circle Circle::operator / (Value r) const Circle Circle::operator % (Value r) const { - return Circle(fmod(rad, r)); + return Circle(std::fmod(rad, r)); } // ------------------------------------------------------------------------------------------------ @@ -278,7 +278,7 @@ Circle Circle::operator % (const Vector2 & p) const // ------------------------------------------------------------------------------------------------ Circle Circle::operator + () const { - return Circle(pos.Abs(), fabs(rad)); + return Circle(pos.Abs(), std::fabs(rad)); } Circle Circle::operator - () const @@ -321,11 +321,17 @@ bool Circle::operator >= (const Circle & c) const Int32 Circle::Cmp(const Circle & o) const { if (*this == o) + { return 0; + } else if (*this > o) + { return 1; + } else + { return -1; + } } // ------------------------------------------------------------------------------------------------ @@ -372,7 +378,7 @@ void Circle::Set(Value nx, Value ny, Value nr) // ------------------------------------------------------------------------------------------------ void Circle::Set(CSStr values, SQChar delim) { - Set(GetCircle(values, delim)); + Set(Circle::Get(values, delim)); } // ------------------------------------------------------------------------------------------------ @@ -385,17 +391,25 @@ void Circle::Generate() void Circle::Generate(Value min, Value max, bool r) { if (EpsLt(max, min)) + { STHROWF("max value is lower than min value"); + } else if (r) + { rad = GetRandomFloat32(min, max); + } else + { pos.Generate(min, max); + } } void Circle::Generate(Value xmin, Value xmax, Value ymin, Value ymax) { if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin)) + { STHROWF("max value is lower than min value"); + } pos.Generate(xmin, xmax, ymin, ymax); } @@ -403,7 +417,9 @@ void Circle::Generate(Value xmin, Value xmax, Value ymin, Value ymax) void Circle::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value rmin, Value rmax) { if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin) || EpsLt(rmax, rmin)) + { STHROWF("max value is lower than min value"); + } pos.Generate(xmin, xmax, ymin, ymax); rad = GetRandomFloat32(rmin, rmax); @@ -412,17 +428,17 @@ void Circle::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value rmin // ------------------------------------------------------------------------------------------------ Circle Circle::Abs() const { - return Circle(pos.Abs(), fabs(rad)); + return Circle(pos.Abs(), std::fabs(rad)); } // ------------------------------------------------------------------------------------------------ -const Circle & GetCircle(CSStr str) +const Circle & Circle::Get(CSStr str) { - return GetCircle(str, Circle::Delim); + return Circle::Get(str, Circle::Delim); } // ------------------------------------------------------------------------------------------------ -const Circle & GetCircle(CSStr str, SQChar delim) +const Circle & Circle::Get(CSStr str, SQChar delim) { // The format specifications that will be used to scan the string static SQChar fs[] = _SC(" %f , %f , %f "); @@ -443,99 +459,135 @@ const Circle & GetCircle(CSStr str, SQChar delim) return circle; } +// ------------------------------------------------------------------------------------------------ +const Circle & GetCircle() +{ + static Circle circle; + circle.Clear(); + return circle; +} + +const Circle & GetCircle(Float32 rv) +{ + static Circle circle; + circle.Set(rv); + return circle; +} + +const Circle & GetCircle(const Vector2 & pv, Float32 rv) +{ + static Circle circle; + circle.Set(pv, rv); + return circle; +} + +const Circle & GetCircle(Float32 xv, Float32 yv, Float32 rv) +{ + static Circle circle; + circle.Set(xv, yv, rv); + return circle; +} + +const Circle & GetCircle(const Circle & o) +{ + static Circle circle; + circle.Set(o); + return circle; +} + // ================================================================================================ void Register_Circle(HSQUIRRELVM vm) { typedef Circle::Value Val; RootTable(vm).Bind(_SC("Circle"), Class< Circle >(vm, _SC("Circle")) - /* Constructors */ + // Constructors .Ctor() .Ctor< Val >() .Ctor< const Vector2 &, Val >() .Ctor< Val, Val, Val >() - /* Static Members */ + // Static Members .SetStaticValue(_SC("Delim"), &Circle::Delim) - /* Member Variables */ - .Var(_SC("pos"), &Circle::pos) - .Var(_SC("rad"), &Circle::rad) - /* Properties */ - .Prop(_SC("abs"), &Circle::Abs) - /* Core Metamethods */ + // Member Variables + .Var(_SC("Pos"), &Circle::pos) + .Var(_SC("Rad"), &Circle::rad) + // Properties + .Prop(_SC("Abs"), &Circle::Abs) + // Core Metamethods .Func(_SC("_tostring"), &Circle::ToString) .SquirrelFunc(_SC("_typename"), &Circle::Typename) .Func(_SC("_cmp"), &Circle::Cmp) - /* Metamethods */ - .Func(_SC("_add"), &Circle::operator +) - .Func(_SC("_sub"), &Circle::operator -) - .Func(_SC("_mul"), &Circle::operator *) - .Func(_SC("_div"), &Circle::operator /) - .Func(_SC("_modulo"), &Circle::operator %) - .Func(_SC("_unm"), &Circle::operator -) - /* Setters */ - .Overload(_SC("Set"), &Circle::Set) - .Overload(_SC("Set"), &Circle::Set) - .Overload(_SC("Set"), &Circle::Set) - .Overload(_SC("SetRad"), &Circle::Set) - .Overload(_SC("SetVec2"), &Circle::Set) - .Overload(_SC("SetVec2"), &Circle::Set) - .Overload(_SC("SetStr"), &Circle::Set) - /* Utility Methods */ + // Metamethods + .Func< Circle (Circle::*)(const Circle &) const >(_SC("_add"), &Circle::operator +) + .Func< Circle (Circle::*)(const Circle &) const >(_SC("_sub"), &Circle::operator -) + .Func< Circle (Circle::*)(const Circle &) const >(_SC("_mul"), &Circle::operator *) + .Func< Circle (Circle::*)(const Circle &) const >(_SC("_div"), &Circle::operator /) + .Func< Circle (Circle::*)(const Circle &) const >(_SC("_modulo"), &Circle::operator %) + .Func< Circle (Circle::*)(void) const >(_SC("_unm"), &Circle::operator -) + // Setters + .Overload< void (Circle::*)(const Circle &) >(_SC("Set"), &Circle::Set) + .Overload< void (Circle::*)(const Vector2 &, Val) >(_SC("Set"), &Circle::Set) + .Overload< void (Circle::*)(Val, Val, Val) >(_SC("Set"), &Circle::Set) + .Overload< void (Circle::*)(Val) >(_SC("SetRad"), &Circle::Set) + .Overload< void (Circle::*)(const Vector2 &) >(_SC("SetVec2"), &Circle::Set) + .Overload< void (Circle::*)(Val, Val) >(_SC("SetVec2"), &Circle::Set) + .Overload< void (Circle::*)(CSStr, SQChar) >(_SC("SetStr"), &Circle::Set) + // Utility Methods .Func(_SC("Clear"), &Circle::Clear) - /* Operator Exposure */ - .Func(_SC("opAddAssign"), &Circle::operator +=) - .Func(_SC("opSubAssign"), &Circle::operator -=) - .Func(_SC("opMulAssign"), &Circle::operator *=) - .Func(_SC("opDivAssign"), &Circle::operator /=) - .Func(_SC("opModAssign"), &Circle::operator %=) - - .Func(_SC("opAddAssignR"), &Circle::operator +=) - .Func(_SC("opSubAssignR"), &Circle::operator -=) - .Func(_SC("opMulAssignR"), &Circle::operator *=) - .Func(_SC("opDivAssignR"), &Circle::operator /=) - .Func(_SC("opModAssignR"), &Circle::operator %=) - - .Func(_SC("opAddAssignP"), &Circle::operator +=) - .Func(_SC("opSubAssignP"), &Circle::operator -=) - .Func(_SC("opMulAssignP"), &Circle::operator *=) - .Func(_SC("opDivAssignP"), &Circle::operator /=) - .Func(_SC("opModAssignP"), &Circle::operator %=) - - .Func(_SC("opPreInc"), &Circle::operator ++) - .Func(_SC("opPreDec"), &Circle::operator --) - .Func(_SC("opPostInc"), &Circle::operator ++) - .Func(_SC("opPostDec"), &Circle::operator --) - - .Func(_SC("opAdd"), &Circle::operator +) - .Func(_SC("opSub"), &Circle::operator -) - .Func(_SC("opMul"), &Circle::operator *) - .Func(_SC("opDiv"), &Circle::operator /) - .Func(_SC("opMod"), &Circle::operator %) - - .Func(_SC("opAddR"), &Circle::operator +) - .Func(_SC("opSubR"), &Circle::operator -) - .Func(_SC("opMulR"), &Circle::operator *) - .Func(_SC("opDivR"), &Circle::operator /) - .Func(_SC("opModR"), &Circle::operator %) - - .Func(_SC("opAddP"), &Circle::operator +) - .Func(_SC("opSubP"), &Circle::operator -) - .Func(_SC("opMulP"), &Circle::operator *) - .Func(_SC("opDivP"), &Circle::operator /) - .Func(_SC("opModP"), &Circle::operator %) - - .Func(_SC("opUnPlus"), &Circle::operator +) - .Func(_SC("opUnMinus"), &Circle::operator -) - - .Func(_SC("opEqual"), &Circle::operator ==) - .Func(_SC("opNotEqual"), &Circle::operator !=) - .Func(_SC("opLessThan"), &Circle::operator <) - .Func(_SC("opGreaterThan"), &Circle::operator >) - .Func(_SC("opLessEqual"), &Circle::operator <=) - .Func(_SC("opGreaterEqual"), &Circle::operator >=) // Static Overloads - .StaticOverload< const Circle & (*)(CSStr) >(_SC("FromStr"), &GetCircle) - .StaticOverload< const Circle & (*)(CSStr, SQChar) >(_SC("FromStr"), &GetCircle) + .StaticOverload< const Circle & (*)(CSStr) >(_SC("FromStr"), &Circle::Get) + .StaticOverload< const Circle & (*)(CSStr, SQChar) >(_SC("FromStr"), &Circle::Get) + // Operator Exposure + .Func< Circle & (Circle::*)(const Circle &) >(_SC("opAddAssign"), &Circle::operator +=) + .Func< Circle & (Circle::*)(const Circle &) >(_SC("opSubAssign"), &Circle::operator -=) + .Func< Circle & (Circle::*)(const Circle &) >(_SC("opMulAssign"), &Circle::operator *=) + .Func< Circle & (Circle::*)(const Circle &) >(_SC("opDivAssign"), &Circle::operator /=) + .Func< Circle & (Circle::*)(const Circle &) >(_SC("opModAssign"), &Circle::operator %=) + + .Func< Circle & (Circle::*)(Circle::Value) >(_SC("opAddAssignR"), &Circle::operator +=) + .Func< Circle & (Circle::*)(Circle::Value) >(_SC("opSubAssignR"), &Circle::operator -=) + .Func< Circle & (Circle::*)(Circle::Value) >(_SC("opMulAssignR"), &Circle::operator *=) + .Func< Circle & (Circle::*)(Circle::Value) >(_SC("opDivAssignR"), &Circle::operator /=) + .Func< Circle & (Circle::*)(Circle::Value) >(_SC("opModAssignR"), &Circle::operator %=) + + .Func< Circle & (Circle::*)(const Vector2 &) >(_SC("opAddAssignP"), &Circle::operator +=) + .Func< Circle & (Circle::*)(const Vector2 &) >(_SC("opSubAssignP"), &Circle::operator -=) + .Func< Circle & (Circle::*)(const Vector2 &) >(_SC("opMulAssignP"), &Circle::operator *=) + .Func< Circle & (Circle::*)(const Vector2 &) >(_SC("opDivAssignP"), &Circle::operator /=) + .Func< Circle & (Circle::*)(const Vector2 &) >(_SC("opModAssignP"), &Circle::operator %=) + + .Func< Circle & (Circle::*)(void) >(_SC("opPreInc"), &Circle::operator ++) + .Func< Circle & (Circle::*)(void) >(_SC("opPreDec"), &Circle::operator --) + .Func< Circle (Circle::*)(int) >(_SC("opPostInc"), &Circle::operator ++) + .Func< Circle (Circle::*)(int) >(_SC("opPostDec"), &Circle::operator --) + + .Func< Circle (Circle::*)(const Circle &) const >(_SC("opAdd"), &Circle::operator +) + .Func< Circle (Circle::*)(const Circle &) const >(_SC("opSub"), &Circle::operator -) + .Func< Circle (Circle::*)(const Circle &) const >(_SC("opMul"), &Circle::operator *) + .Func< Circle (Circle::*)(const Circle &) const >(_SC("opDiv"), &Circle::operator /) + .Func< Circle (Circle::*)(const Circle &) const >(_SC("opMod"), &Circle::operator %) + + .Func< Circle (Circle::*)(Circle::Value) const >(_SC("opAddR"), &Circle::operator +) + .Func< Circle (Circle::*)(Circle::Value) const >(_SC("opSubR"), &Circle::operator -) + .Func< Circle (Circle::*)(Circle::Value) const >(_SC("opMulR"), &Circle::operator *) + .Func< Circle (Circle::*)(Circle::Value) const >(_SC("opDivR"), &Circle::operator /) + .Func< Circle (Circle::*)(Circle::Value) const >(_SC("opModR"), &Circle::operator %) + + .Func< Circle (Circle::*)(const Vector2 &) const >(_SC("opAddP"), &Circle::operator +) + .Func< Circle (Circle::*)(const Vector2 &) const >(_SC("opSubP"), &Circle::operator -) + .Func< Circle (Circle::*)(const Vector2 &) const >(_SC("opMulP"), &Circle::operator *) + .Func< Circle (Circle::*)(const Vector2 &) const >(_SC("opDivP"), &Circle::operator /) + .Func< Circle (Circle::*)(const Vector2 &) const >(_SC("opModP"), &Circle::operator %) + + .Func< Circle (Circle::*)(void) const >(_SC("opUnPlus"), &Circle::operator +) + .Func< Circle (Circle::*)(void) const >(_SC("opUnMinus"), &Circle::operator -) + + .Func< bool (Circle::*)(const Circle &) const >(_SC("opEqual"), &Circle::operator ==) + .Func< bool (Circle::*)(const Circle &) const >(_SC("opNotEqual"), &Circle::operator !=) + .Func< bool (Circle::*)(const Circle &) const >(_SC("opLessThan"), &Circle::operator <) + .Func< bool (Circle::*)(const Circle &) const >(_SC("opGreaterThan"), &Circle::operator >) + .Func< bool (Circle::*)(const Circle &) const >(_SC("opLessEqual"), &Circle::operator <=) + .Func< bool (Circle::*)(const Circle &) const >(_SC("opGreaterEqual"), &Circle::operator >=) ); } diff --git a/source/Base/Circle.hpp b/source/Base/Circle.hpp index 7c2c8cb6..f5ce3aae 100644 --- a/source/Base/Circle.hpp +++ b/source/Base/Circle.hpp @@ -8,16 +8,6 @@ // ------------------------------------------------------------------------------------------------ namespace SqMod { -/* ------------------------------------------------------------------------------------------------ - * Extract the values for components of the Circle type from a string. -*/ -const Circle & GetCircle(CSStr str); - -/* ------------------------------------------------------------------------------------------------ - * Extract the values for components of the Circle type from a string. -*/ -const Circle & GetCircle(CSStr str, SQChar delim); - /* ------------------------------------------------------------------------------------------------ * Class used to represent a two-dimensional circle. */ @@ -386,13 +376,25 @@ struct Circle */ void Clear() { - pos.Clear(); rad = 0.0; + pos.Clear(); + rad = 0.0; } /* -------------------------------------------------------------------------------------------- * Retrieve a new instance of this type with absolute component values. */ Circle Abs() const; + + /* -------------------------------------------------------------------------------------------- + * Extract the values for components of the Circle type from a string. + */ + static const Circle & Get(CSStr str); + + /* -------------------------------------------------------------------------------------------- + * Extract the values for components of the Circle type from a string. + */ + static const Circle & Get(CSStr str, SQChar delim); + }; } // Namespace:: SqMod diff --git a/source/Base/Color3.cpp b/source/Base/Color3.cpp index 1ff307a3..e54a989b 100644 --- a/source/Base/Color3.cpp +++ b/source/Base/Color3.cpp @@ -21,7 +21,7 @@ SQChar Color3::Delim = ','; // ------------------------------------------------------------------------------------------------ SQInteger Color3::Typename(HSQUIRRELVM vm) { - static SQChar name[] = _SC("Color3"); + static const SQChar name[] = _SC("Color3"); sq_pushstring(vm, name, sizeof(name)); return 1; } @@ -428,11 +428,17 @@ Color3::operator Color4 () const Int32 Color3::Cmp(const Color3 & o) const { if (*this == o) + { return 0; + } else if (*this > o) + { return 1; + } else + { return -1; + } } // ------------------------------------------------------------------------------------------------ @@ -474,7 +480,7 @@ void Color3::Set(const Color4 & c) // ------------------------------------------------------------------------------------------------ void Color3::Set(CSStr str, SQChar delim) { - Set(GetColor3(str, delim)); + Set(Color3::Get(str, delim)); } // ------------------------------------------------------------------------------------------------ @@ -533,7 +539,9 @@ void Color3::Generate() void Color3::Generate(Value min, Value max) { if (max < min) + { STHROWF("max value is lower than min value"); + } r = GetRandomUint8(min, max); g = GetRandomUint8(min, max); @@ -543,7 +551,9 @@ void Color3::Generate(Value min, Value max) void Color3::Generate(Value rmin, Value rmax, Value gmin, Value gmax, Value bmin, Value bmax) { if (rmax < rmin || gmax < gmin || bmax < bmin) + { STHROWF("max value is lower than min value"); + } r = GetRandomUint8(rmin, rmax); g = GetRandomUint8(gmin, gmax); @@ -565,13 +575,13 @@ void Color3::Inverse() } // ------------------------------------------------------------------------------------------------ -const Color3 & GetColor3(CSStr str) +const Color3 & Color3::Get(CSStr str) { - return GetColor3(str, Color3::Delim); + return Color3::Get(str, Color3::Delim); } // ------------------------------------------------------------------------------------------------ -const Color3 & GetColor3(CSStr str, SQChar delim) +const Color3 & Color3::Get(CSStr str, SQChar delim) { // The format specifications that will be used to scan the string static SQChar fs[] = _SC(" %u , %u , %u "); @@ -601,115 +611,144 @@ const Color3 & GetColor3(CSStr str, SQChar delim) return col; } +// ------------------------------------------------------------------------------------------------ +const Color3 & GetColor3() +{ + static Color3 col; + col.Clear(); + return col; +} + +const Color3 & GetColor3(Uint8 sv) +{ + static Color3 col; + col.Set(sv); + return col; +} + +const Color3 & GetColor3(Uint8 rv, Uint8 gv, Uint8 bv) +{ + static Color3 col; + col.Set(rv, gv, bv); + return col; +} + +const Color3 & GetColor3(const Color3 & o) +{ + static Color3 col; + col.Set(o); + return col; +} + // ================================================================================================ void Register_Color3(HSQUIRRELVM vm) { typedef Color3::Value Val; RootTable(vm).Bind(_SC("Color3"), Class< Color3 >(vm, _SC("Color3")) - /* Constructors */ + // Constructors .Ctor() .Ctor< Val >() .Ctor< Val, Val, Val >() - /* Static Members */ + // Static Members .SetStaticValue(_SC("Delim"), &Color3::Delim) - /* Member Variables */ - .Var(_SC("r"), &Color3::r) - .Var(_SC("g"), &Color3::g) - .Var(_SC("b"), &Color3::b) - /* Properties */ - .Prop(_SC("rgb"), &Color3::GetRGB, &Color3::SetRGB) - .Prop(_SC("rgba"), &Color3::GetRGBA, &Color3::SetRGBA) - .Prop(_SC("argb"), &Color3::GetARGB, &Color3::SetARGB) - .Prop(_SC("str"), &Color3::SetCol) - /* Core Metamethods */ + // Member Variables + .Var(_SC("R"), &Color3::r) + .Var(_SC("G"), &Color3::g) + .Var(_SC("B"), &Color3::b) + // Properties + .Prop(_SC("RGB"), &Color3::GetRGB, &Color3::SetRGB) + .Prop(_SC("RGBA"), &Color3::GetRGBA, &Color3::SetRGBA) + .Prop(_SC("ARGB"), &Color3::GetARGB, &Color3::SetARGB) + .Prop(_SC("Str"), &Color3::SetCol) + // Core Metamethods .Func(_SC("_tostring"), &Color3::ToString) .SquirrelFunc(_SC("_typename"), &Color3::Typename) .Func(_SC("_cmp"), &Color3::Cmp) - /* Metamethods */ - .Func(_SC("_add"), &Color3::operator +) - .Func(_SC("_sub"), &Color3::operator -) - .Func(_SC("_mul"), &Color3::operator *) - .Func(_SC("_div"), &Color3::operator /) - .Func(_SC("_modulo"), &Color3::operator %) - .Func(_SC("_unm"), &Color3::operator -) - /* Setters */ - .Overload(_SC("Set"), &Color3::Set) - .Overload(_SC("Set"), &Color3::Set) - .Overload(_SC("SetCol3"), &Color3::Set) - .Overload(_SC("SetCol4"), &Color3::Set) - .Overload(_SC("SetStr"), &Color3::Set) - /* Random Generators */ - .Overload(_SC("Generate"), &Color3::Generate) - .Overload(_SC("Generate"), &Color3::Generate) - .Overload(_SC("Generate"), &Color3::Generate) - /* Utility Methods */ + // Metamethods + .Func< Color3 (Color3::*)(const Color3 &) const >(_SC("_add"), &Color3::operator +) + .Func< Color3 (Color3::*)(const Color3 &) const >(_SC("_sub"), &Color3::operator -) + .Func< Color3 (Color3::*)(const Color3 &) const >(_SC("_mul"), &Color3::operator *) + .Func< Color3 (Color3::*)(const Color3 &) const >(_SC("_div"), &Color3::operator /) + .Func< Color3 (Color3::*)(const Color3 &) const >(_SC("_modulo"), &Color3::operator %) + .Func< Color3 (Color3::*)(void) const >(_SC("_unm"), &Color3::operator -) + // Setters + .Overload< void (Color3::*)(Val) >(_SC("Set"), &Color3::Set) + .Overload< void (Color3::*)(Val, Val, Val) >(_SC("Set"), &Color3::Set) + .Overload< void (Color3::*)(const Color3 &) >(_SC("SetCol3"), &Color3::Set) + .Overload< void (Color3::*)(const Color4 &) >(_SC("SetCol4"), &Color3::Set) + .Overload< void (Color3::*)(CSStr, SQChar) >(_SC("SetStr"), &Color3::Set) + // Random Generators + .Overload< void (Color3::*)(void) >(_SC("Generate"), &Color3::Generate) + .Overload< void (Color3::*)(Val, Val) >(_SC("Generate"), &Color3::Generate) + .Overload< void (Color3::*)(Val, Val, Val, Val, Val, Val) >(_SC("Generate"), &Color3::Generate) + // Utility Methods .Func(_SC("Clear"), &Color3::Clear) .Func(_SC("Random"), &Color3::Random) .Func(_SC("Inverse"), &Color3::Inverse) - /* Operator Exposure */ - .Func(_SC("opAddAssign"), &Color3::operator +=) - .Func(_SC("opSubAssign"), &Color3::operator -=) - .Func(_SC("opMulAssign"), &Color3::operator *=) - .Func(_SC("opDivAssign"), &Color3::operator /=) - .Func(_SC("opModAssign"), &Color3::operator %=) - .Func(_SC("opAndAssign"), &Color3::operator &=) - .Func(_SC("opOrAssign"), &Color3::operator |=) - .Func(_SC("opXorAssign"), &Color3::operator ^=) - .Func(_SC("opShlAssign"), &Color3::operator <<=) - .Func(_SC("opShrAssign"), &Color3::operator >>=) - - .Func(_SC("opAddAssignS"), &Color3::operator +=) - .Func(_SC("opSubAssignS"), &Color3::operator -=) - .Func(_SC("opMulAssignS"), &Color3::operator *=) - .Func(_SC("opDivAssignS"), &Color3::operator /=) - .Func(_SC("opModAssignS"), &Color3::operator %=) - .Func(_SC("opAndAssignS"), &Color3::operator &=) - .Func(_SC("opOrAssignS"), &Color3::operator |=) - .Func(_SC("opXorAssignS"), &Color3::operator ^=) - .Func(_SC("opShlAssignS"), &Color3::operator <<=) - .Func(_SC("opShrAssignS"), &Color3::operator >>=) - - .Func(_SC("opPreInc"), &Color3::operator ++) - .Func(_SC("opPreDec"), &Color3::operator --) - .Func(_SC("opPostInc"), &Color3::operator ++) - .Func(_SC("opPostDec"), &Color3::operator --) - - .Func(_SC("opAdd"), &Color3::operator +) - .Func(_SC("opSub"), &Color3::operator -) - .Func(_SC("opMul"), &Color3::operator *) - .Func(_SC("opDiv"), &Color3::operator /) - .Func(_SC("opMod"), &Color3::operator %) - .Func(_SC("opAnd"), &Color3::operator &) - .Func(_SC("opOr"), &Color3::operator |) - .Func(_SC("opShl"), &Color3::operator ^) - .Func(_SC("opShl"), &Color3::operator <<) - .Func(_SC("opShr"), &Color3::operator >>) - - .Func(_SC("opAddS"), &Color3::operator +) - .Func(_SC("opSubS"), &Color3::operator -) - .Func(_SC("opMulS"), &Color3::operator *) - .Func(_SC("opDivS"), &Color3::operator /) - .Func(_SC("opModS"), &Color3::operator %) - .Func(_SC("opAndS"), &Color3::operator &) - .Func(_SC("opOrS"), &Color3::operator |) - .Func(_SC("opShlS"), &Color3::operator ^) - .Func(_SC("opShlS"), &Color3::operator <<) - .Func(_SC("opShrS"), &Color3::operator >>) - - .Func(_SC("opUnPlus"), &Color3::operator +) - .Func(_SC("opUnMinus"), &Color3::operator -) - .Func(_SC("opCom"), &Color3::operator ~) - - .Func(_SC("opEqual"), &Color3::operator ==) - .Func(_SC("opNotEqual"), &Color3::operator !=) - .Func(_SC("opLessThan"), &Color3::operator <) - .Func(_SC("opGreaterThan"), &Color3::operator >) - .Func(_SC("opLessEqual"), &Color3::operator <=) - .Func(_SC("opGreaterEqual"), &Color3::operator >=) // Static Overloads - .StaticOverload< const Color3 & (*)(CSStr) >(_SC("FromStr"), &GetColor3) - .StaticOverload< const Color3 & (*)(CSStr, SQChar) >(_SC("FromStr"), &GetColor3) + .StaticOverload< const Color3 & (*)(CSStr) >(_SC("FromStr"), &Color3::Get) + .StaticOverload< const Color3 & (*)(CSStr, SQChar) >(_SC("FromStr"), &Color3::Get) + // Operator Exposure + .Func< Color3 & (Color3::*)(const Color3 &) >(_SC("opAddAssign"), &Color3::operator +=) + .Func< Color3 & (Color3::*)(const Color3 &) >(_SC("opSubAssign"), &Color3::operator -=) + .Func< Color3 & (Color3::*)(const Color3 &) >(_SC("opMulAssign"), &Color3::operator *=) + .Func< Color3 & (Color3::*)(const Color3 &) >(_SC("opDivAssign"), &Color3::operator /=) + .Func< Color3 & (Color3::*)(const Color3 &) >(_SC("opModAssign"), &Color3::operator %=) + .Func< Color3 & (Color3::*)(const Color3 &) >(_SC("opAndAssign"), &Color3::operator &=) + .Func< Color3 & (Color3::*)(const Color3 &) >(_SC("opOrAssign"), &Color3::operator |=) + .Func< Color3 & (Color3::*)(const Color3 &) >(_SC("opXorAssign"), &Color3::operator ^=) + .Func< Color3 & (Color3::*)(const Color3 &) >(_SC("opShlAssign"), &Color3::operator <<=) + .Func< Color3 & (Color3::*)(const Color3 &) >(_SC("opShrAssign"), &Color3::operator >>=) + + .Func< Color3 & (Color3::*)(Color3::Value) >(_SC("opAddAssignS"), &Color3::operator +=) + .Func< Color3 & (Color3::*)(Color3::Value) >(_SC("opSubAssignS"), &Color3::operator -=) + .Func< Color3 & (Color3::*)(Color3::Value) >(_SC("opMulAssignS"), &Color3::operator *=) + .Func< Color3 & (Color3::*)(Color3::Value) >(_SC("opDivAssignS"), &Color3::operator /=) + .Func< Color3 & (Color3::*)(Color3::Value) >(_SC("opModAssignS"), &Color3::operator %=) + .Func< Color3 & (Color3::*)(Color3::Value) >(_SC("opAndAssignS"), &Color3::operator &=) + .Func< Color3 & (Color3::*)(Color3::Value) >(_SC("opOrAssignS"), &Color3::operator |=) + .Func< Color3 & (Color3::*)(Color3::Value) >(_SC("opXorAssignS"), &Color3::operator ^=) + .Func< Color3 & (Color3::*)(Color3::Value) >(_SC("opShlAssignS"), &Color3::operator <<=) + .Func< Color3 & (Color3::*)(Color3::Value) >(_SC("opShrAssignS"), &Color3::operator >>=) + + .Func< Color3 & (Color3::*)(void) >(_SC("opPreInc"), &Color3::operator ++) + .Func< Color3 & (Color3::*)(void) >(_SC("opPreDec"), &Color3::operator --) + .Func< Color3 (Color3::*)(int) >(_SC("opPostInc"), &Color3::operator ++) + .Func< Color3 (Color3::*)(int) >(_SC("opPostDec"), &Color3::operator --) + + .Func< Color3 (Color3::*)(const Color3 &) const >(_SC("opAdd"), &Color3::operator +) + .Func< Color3 (Color3::*)(const Color3 &) const >(_SC("opSub"), &Color3::operator -) + .Func< Color3 (Color3::*)(const Color3 &) const >(_SC("opMul"), &Color3::operator *) + .Func< Color3 (Color3::*)(const Color3 &) const >(_SC("opDiv"), &Color3::operator /) + .Func< Color3 (Color3::*)(const Color3 &) const >(_SC("opMod"), &Color3::operator %) + .Func< Color3 (Color3::*)(const Color3 &) const >(_SC("opAnd"), &Color3::operator &) + .Func< Color3 (Color3::*)(const Color3 &) const >(_SC("opOr"), &Color3::operator |) + .Func< Color3 (Color3::*)(const Color3 &) const >(_SC("opShl"), &Color3::operator ^) + .Func< Color3 (Color3::*)(const Color3 &) const >(_SC("opShl"), &Color3::operator <<) + .Func< Color3 (Color3::*)(const Color3 &) const >(_SC("opShr"), &Color3::operator >>) + + .Func< Color3 (Color3::*)(Color3::Value) const >(_SC("opAddS"), &Color3::operator +) + .Func< Color3 (Color3::*)(Color3::Value) const >(_SC("opSubS"), &Color3::operator -) + .Func< Color3 (Color3::*)(Color3::Value) const >(_SC("opMulS"), &Color3::operator *) + .Func< Color3 (Color3::*)(Color3::Value) const >(_SC("opDivS"), &Color3::operator /) + .Func< Color3 (Color3::*)(Color3::Value) const >(_SC("opModS"), &Color3::operator %) + .Func< Color3 (Color3::*)(Color3::Value) const >(_SC("opAndS"), &Color3::operator &) + .Func< Color3 (Color3::*)(Color3::Value) const >(_SC("opOrS"), &Color3::operator |) + .Func< Color3 (Color3::*)(Color3::Value) const >(_SC("opShlS"), &Color3::operator ^) + .Func< Color3 (Color3::*)(Color3::Value) const >(_SC("opShlS"), &Color3::operator <<) + .Func< Color3 (Color3::*)(Color3::Value) const >(_SC("opShrS"), &Color3::operator >>) + + .Func< Color3 (Color3::*)(void) const >(_SC("opUnPlus"), &Color3::operator +) + .Func< Color3 (Color3::*)(void) const >(_SC("opUnMinus"), &Color3::operator -) + .Func< Color3 (Color3::*)(void) const >(_SC("opCom"), &Color3::operator ~) + + .Func< bool (Color3::*)(const Color3 &) const >(_SC("opEqual"), &Color3::operator ==) + .Func< bool (Color3::*)(const Color3 &) const >(_SC("opNotEqual"), &Color3::operator !=) + .Func< bool (Color3::*)(const Color3 &) const >(_SC("opLessThan"), &Color3::operator <) + .Func< bool (Color3::*)(const Color3 &) const >(_SC("opGreaterThan"), &Color3::operator >) + .Func< bool (Color3::*)(const Color3 &) const >(_SC("opLessEqual"), &Color3::operator <=) + .Func< bool (Color3::*)(const Color3 &) const >(_SC("opGreaterEqual"), &Color3::operator >=) ); } diff --git a/source/Base/Color3.hpp b/source/Base/Color3.hpp index 400f1bcc..3fd5ef67 100644 --- a/source/Base/Color3.hpp +++ b/source/Base/Color3.hpp @@ -7,16 +7,6 @@ // ------------------------------------------------------------------------------------------------ namespace SqMod { -/* ------------------------------------------------------------------------------------------------ - * Extract the values for components of the Color3 type from a string. -*/ -const Color3 & GetColor3(CSStr str); - -/* ------------------------------------------------------------------------------------------------ - * Extract the values for components of the Color3 type from a string. -*/ -const Color3 & GetColor3(CSStr str, SQChar delim); - /* ------------------------------------------------------------------------------------------------ * Class used to represent an opaque RGB color. */ @@ -476,6 +466,17 @@ struct Color3 * Inverse the color. */ void Inverse(); + + /* -------------------------------------------------------------------------------------------- + * Extract the values for components of the Color3 type from a string. + */ + static const Color3 & Get(CSStr str); + + /* -------------------------------------------------------------------------------------------- + * Extract the values for components of the Color3 type from a string. + */ + static const Color3 & Get(CSStr str, SQChar delim); + }; } // Namespace:: SqMod diff --git a/source/Base/Color4.cpp b/source/Base/Color4.cpp index 5007836d..aa61441c 100644 --- a/source/Base/Color4.cpp +++ b/source/Base/Color4.cpp @@ -21,7 +21,7 @@ SQChar Color4::Delim = ','; // ------------------------------------------------------------------------------------------------ SQInteger Color4::Typename(HSQUIRRELVM vm) { - static SQChar name[] = _SC("Color4"); + static const SQChar name[] = _SC("Color4"); sq_pushstring(vm, name, sizeof(name)); return 1; } @@ -460,11 +460,17 @@ Color4::operator Color3 () const Int32 Color4::Cmp(const Color4 & o) const { if (*this == o) + { return 0; + } else if (*this > o) + { return 1; + } else + { return -1; + } } // ------------------------------------------------------------------------------------------------ @@ -517,7 +523,7 @@ void Color4::Set(const Color3 & c) // ------------------------------------------------------------------------------------------------ void Color4::Set(CSStr str, SQChar delim) { - Set(GetColor4(str, delim)); + Set(Color4::Get(str, delim)); } // ------------------------------------------------------------------------------------------------ @@ -579,7 +585,9 @@ void Color4::Generate() void Color4::Generate(Value min, Value max) { if (max < min) + { STHROWF("max value is lower than min value"); + } r = GetRandomUint8(min, max); g = GetRandomUint8(min, max); @@ -590,7 +598,9 @@ void Color4::Generate(Value min, Value max) void Color4::Generate(Value rmin, Value rmax, Value gmin, Value gmax, Value bmin, Value bmax, Value amin, Value amax) { if (rmax < rmin || gmax < gmin || bmax < bmin || amax < amin) + { STHROWF("max value is lower than min value"); + } r = GetRandomUint8(rmin, rmax); g = GetRandomUint8(gmin, gmax); @@ -614,13 +624,13 @@ void Color4::Inverse() } // ------------------------------------------------------------------------------------------------ -const Color4 & GetColor4(CSStr str) +const Color4 & Color4::Get(CSStr str) { - return GetColor4(str, Color4::Delim); + return Color4::Get(str, Color4::Delim); } // ------------------------------------------------------------------------------------------------ -const Color4 & GetColor4(CSStr str, SQChar delim) +const Color4 & Color4::Get(CSStr str, SQChar delim) { // The format specifications that will be used to scan the string static SQChar fs[] = _SC(" %u , %u , %u , %u "); @@ -642,7 +652,7 @@ const Color4 & GetColor4(CSStr str, SQChar delim) // The sscanf function requires at least 32 bit integers Uint32 r = 0, g = 0, b = 0, a = 0; // Attempt to extract the component values from the specified string - sscanf(str, fs, &r, &g, &b, &a); + std::sscanf(str, fs, &r, &g, &b, &a); // Cast the extracted integers to the value used by the Color4 type col.r = static_cast< Color4::Value >(Clamp(r, min, max)); col.g = static_cast< Color4::Value >(Clamp(g, min, max)); @@ -652,118 +662,154 @@ const Color4 & GetColor4(CSStr str, SQChar delim) return col; } +// ------------------------------------------------------------------------------------------------ +const Color4 & GetColor4() +{ + static Color4 col; + col.Clear(); + return col; +} + +const Color4 & GetColor4(Uint8 sv) +{ + static Color4 col; + col.Set(sv); + return col; +} + +const Color4 & GetColor4(Uint8 rv, Uint8 gv, Uint8 bv) +{ + static Color4 col; + col.Set(rv, gv, bv); + return col; +} + +const Color4 & GetColor4(Uint8 rv, Uint8 gv, Uint8 bv, Uint8 av) +{ + static Color4 col; + col.Set(rv, gv, bv, av); + return col; +} + +const Color4 & GetColor4(const Color4 & o) +{ + static Color4 col; + col.Set(o); + return col; +} + // ================================================================================================ void Register_Color4(HSQUIRRELVM vm) { typedef Color4::Value Val; RootTable(vm).Bind(_SC("Color4"), Class< Color4 >(vm, _SC("Color4")) - /* Constructors */ + // Constructors .Ctor() .Ctor< Val >() .Ctor< Val, Val, Val >() .Ctor< Val, Val, Val, Val >() - /* Static Members */ + // Static Members .SetStaticValue(_SC("Delim"), &Color4::Delim) - /* Member Variables */ - .Var(_SC("r"), &Color4::r) - .Var(_SC("g"), &Color4::g) - .Var(_SC("b"), &Color4::b) - .Var(_SC("a"), &Color4::a) - /* Properties */ - .Prop(_SC("rgb"), &Color4::GetRGB, &Color4::SetRGB) - .Prop(_SC("rgba"), &Color4::GetRGBA, &Color4::SetRGBA) - .Prop(_SC("argb"), &Color4::GetARGB, &Color4::SetARGB) - .Prop(_SC("str"), &Color4::SetCol) - /* Core Metamethods */ + // Member Variables + .Var(_SC("R"), &Color4::r) + .Var(_SC("G"), &Color4::g) + .Var(_SC("B"), &Color4::b) + .Var(_SC("A"), &Color4::a) + // Properties + .Prop(_SC("RGB"), &Color4::GetRGB, &Color4::SetRGB) + .Prop(_SC("RGBA"), &Color4::GetRGBA, &Color4::SetRGBA) + .Prop(_SC("ARGB"), &Color4::GetARGB, &Color4::SetARGB) + .Prop(_SC("Str"), &Color4::SetCol) + // Core Metamethods .Func(_SC("_tostring"), &Color4::ToString) .SquirrelFunc(_SC("_typename"), &Color4::Typename) .Func(_SC("_cmp"), &Color4::Cmp) - /* Metamethods */ - .Func(_SC("_add"), &Color4::operator +) - .Func(_SC("_sub"), &Color4::operator -) - .Func(_SC("_mul"), &Color4::operator *) - .Func(_SC("_div"), &Color4::operator /) - .Func(_SC("_modulo"), &Color4::operator %) - .Func(_SC("_unm"), &Color4::operator -) - /* Setters */ - .Overload(_SC("Set"), &Color4::Set) - .Overload(_SC("Set"), &Color4::Set) - .Overload(_SC("Set"), &Color4::Set) - .Overload(_SC("SetCol4"), &Color4::Set) - .Overload(_SC("SetCol3"), &Color4::Set) - .Overload(_SC("SetStr"), &Color4::Set) - /* Random Generators */ - .Overload(_SC("Generate"), &Color4::Generate) - .Overload(_SC("Generate"), &Color4::Generate) - .Overload(_SC("Generate"), &Color4::Generate) - /* Utility Methods */ + // Metamethods + .Func< Color4 (Color4::*)(const Color4 &) const >(_SC("_add"), &Color4::operator +) + .Func< Color4 (Color4::*)(const Color4 &) const >(_SC("_sub"), &Color4::operator -) + .Func< Color4 (Color4::*)(const Color4 &) const >(_SC("_mul"), &Color4::operator *) + .Func< Color4 (Color4::*)(const Color4 &) const >(_SC("_div"), &Color4::operator /) + .Func< Color4 (Color4::*)(const Color4 &) const >(_SC("_modulo"), &Color4::operator %) + .Func< Color4 (Color4::*)(void) const >(_SC("_unm"), &Color4::operator -) + // Setters + .Overload< void (Color4::*)(Val) >(_SC("Set"), &Color4::Set) + .Overload< void (Color4::*)(Val, Val, Val) >(_SC("Set"), &Color4::Set) + .Overload< void (Color4::*)(Val, Val, Val, Val) >(_SC("Set"), &Color4::Set) + .Overload< void (Color4::*)(const Color4 &) >(_SC("SetCol4"), &Color4::Set) + .Overload< void (Color4::*)(const Color3 &) >(_SC("SetCol3"), &Color4::Set) + .Overload< void (Color4::*)(CSStr, SQChar) >(_SC("SetStr"), &Color4::Set) + // Random Generators + .Overload< void (Color4::*)(void) >(_SC("Generate"), &Color4::Generate) + .Overload< void (Color4::*)(Val, Val) >(_SC("Generate"), &Color4::Generate) + .Overload< void (Color4::*)(Val, Val, Val, Val, Val, Val, Val, Val) >(_SC("Generate"), &Color4::Generate) + // Utility Methods .Func(_SC("Clear"), &Color4::Clear) .Func(_SC("Random"), &Color4::Random) .Func(_SC("Inverse"), &Color4::Inverse) - /* Operator Exposure */ - .Func(_SC("opAddAssign"), &Color4::operator +=) - .Func(_SC("opSubAssign"), &Color4::operator -=) - .Func(_SC("opMulAssign"), &Color4::operator *=) - .Func(_SC("opDivAssign"), &Color4::operator /=) - .Func(_SC("opModAssign"), &Color4::operator %=) - .Func(_SC("opAndAssign"), &Color4::operator &=) - .Func(_SC("opOrAssign"), &Color4::operator |=) - .Func(_SC("opXorAssign"), &Color4::operator ^=) - .Func(_SC("opShlAssign"), &Color4::operator <<=) - .Func(_SC("opShrAssign"), &Color4::operator >>=) - - .Func(_SC("opAddAssignS"), &Color4::operator +=) - .Func(_SC("opSubAssignS"), &Color4::operator -=) - .Func(_SC("opMulAssignS"), &Color4::operator *=) - .Func(_SC("opDivAssignS"), &Color4::operator /=) - .Func(_SC("opModAssignS"), &Color4::operator %=) - .Func(_SC("opAndAssignS"), &Color4::operator &=) - .Func(_SC("opOrAssignS"), &Color4::operator |=) - .Func(_SC("opXorAssignS"), &Color4::operator ^=) - .Func(_SC("opShlAssignS"), &Color4::operator <<=) - .Func(_SC("opShrAssignS"), &Color4::operator >>=) - - .Func(_SC("opPreInc"), &Color4::operator ++) - .Func(_SC("opPreDec"), &Color4::operator --) - .Func(_SC("opPostInc"), &Color4::operator ++) - .Func(_SC("opPostDec"), &Color4::operator --) - - .Func(_SC("opAdd"), &Color4::operator +) - .Func(_SC("opSub"), &Color4::operator -) - .Func(_SC("opMul"), &Color4::operator *) - .Func(_SC("opDiv"), &Color4::operator /) - .Func(_SC("opMod"), &Color4::operator %) - .Func(_SC("opAnd"), &Color4::operator &) - .Func(_SC("opOr"), &Color4::operator |) - .Func(_SC("opShl"), &Color4::operator ^) - .Func(_SC("opShl"), &Color4::operator <<) - .Func(_SC("opShr"), &Color4::operator >>) - - .Func(_SC("opAddS"), &Color4::operator +) - .Func(_SC("opSubS"), &Color4::operator -) - .Func(_SC("opMulS"), &Color4::operator *) - .Func(_SC("opDivS"), &Color4::operator /) - .Func(_SC("opModS"), &Color4::operator %) - .Func(_SC("opAndS"), &Color4::operator &) - .Func(_SC("opOrS"), &Color4::operator |) - .Func(_SC("opShlS"), &Color4::operator ^) - .Func(_SC("opShlS"), &Color4::operator <<) - .Func(_SC("opShrS"), &Color4::operator >>) - - .Func(_SC("opUnPlus"), &Color4::operator +) - .Func(_SC("opUnMinus"), &Color4::operator -) - .Func(_SC("opCom"), &Color4::operator ~) - - .Func(_SC("opEqual"), &Color4::operator ==) - .Func(_SC("opNotEqual"), &Color4::operator !=) - .Func(_SC("opLessThan"), &Color4::operator <) - .Func(_SC("opGreaterThan"), &Color4::operator >) - .Func(_SC("opLessEqual"), &Color4::operator <=) - .Func(_SC("opGreaterEqual"), &Color4::operator >=) // Static Overloads - .StaticOverload< const Color4 & (*)(CSStr) >(_SC("FromStr"), &GetColor4) - .StaticOverload< const Color4 & (*)(CSStr, SQChar) >(_SC("FromStr"), &GetColor4) + .StaticOverload< const Color4 & (*)(CSStr) >(_SC("FromStr"), &Color4::Get) + .StaticOverload< const Color4 & (*)(CSStr, SQChar) >(_SC("FromStr"), &Color4::Get) + // Operator Exposure + .Func< Color4 & (Color4::*)(const Color4 &) >(_SC("opAddAssign"), &Color4::operator +=) + .Func< Color4 & (Color4::*)(const Color4 &) >(_SC("opSubAssign"), &Color4::operator -=) + .Func< Color4 & (Color4::*)(const Color4 &) >(_SC("opMulAssign"), &Color4::operator *=) + .Func< Color4 & (Color4::*)(const Color4 &) >(_SC("opDivAssign"), &Color4::operator /=) + .Func< Color4 & (Color4::*)(const Color4 &) >(_SC("opModAssign"), &Color4::operator %=) + .Func< Color4 & (Color4::*)(const Color4 &) >(_SC("opAndAssign"), &Color4::operator &=) + .Func< Color4 & (Color4::*)(const Color4 &) >(_SC("opOrAssign"), &Color4::operator |=) + .Func< Color4 & (Color4::*)(const Color4 &) >(_SC("opXorAssign"), &Color4::operator ^=) + .Func< Color4 & (Color4::*)(const Color4 &) >(_SC("opShlAssign"), &Color4::operator <<=) + .Func< Color4 & (Color4::*)(const Color4 &) >(_SC("opShrAssign"), &Color4::operator >>=) + + .Func< Color4 & (Color4::*)(Color4::Value) >(_SC("opAddAssignS"), &Color4::operator +=) + .Func< Color4 & (Color4::*)(Color4::Value) >(_SC("opSubAssignS"), &Color4::operator -=) + .Func< Color4 & (Color4::*)(Color4::Value) >(_SC("opMulAssignS"), &Color4::operator *=) + .Func< Color4 & (Color4::*)(Color4::Value) >(_SC("opDivAssignS"), &Color4::operator /=) + .Func< Color4 & (Color4::*)(Color4::Value) >(_SC("opModAssignS"), &Color4::operator %=) + .Func< Color4 & (Color4::*)(Color4::Value) >(_SC("opAndAssignS"), &Color4::operator &=) + .Func< Color4 & (Color4::*)(Color4::Value) >(_SC("opOrAssignS"), &Color4::operator |=) + .Func< Color4 & (Color4::*)(Color4::Value) >(_SC("opXorAssignS"), &Color4::operator ^=) + .Func< Color4 & (Color4::*)(Color4::Value) >(_SC("opShlAssignS"), &Color4::operator <<=) + .Func< Color4 & (Color4::*)(Color4::Value) >(_SC("opShrAssignS"), &Color4::operator >>=) + + .Func< Color4 & (Color4::*)(void) >(_SC("opPreInc"), &Color4::operator ++) + .Func< Color4 & (Color4::*)(void) >(_SC("opPreDec"), &Color4::operator --) + .Func< Color4 (Color4::*)(int) >(_SC("opPostInc"), &Color4::operator ++) + .Func< Color4 (Color4::*)(int) >(_SC("opPostDec"), &Color4::operator --) + + .Func< Color4 (Color4::*)(const Color4 &) const >(_SC("opAdd"), &Color4::operator +) + .Func< Color4 (Color4::*)(const Color4 &) const >(_SC("opSub"), &Color4::operator -) + .Func< Color4 (Color4::*)(const Color4 &) const >(_SC("opMul"), &Color4::operator *) + .Func< Color4 (Color4::*)(const Color4 &) const >(_SC("opDiv"), &Color4::operator /) + .Func< Color4 (Color4::*)(const Color4 &) const >(_SC("opMod"), &Color4::operator %) + .Func< Color4 (Color4::*)(const Color4 &) const >(_SC("opAnd"), &Color4::operator &) + .Func< Color4 (Color4::*)(const Color4 &) const >(_SC("opOr"), &Color4::operator |) + .Func< Color4 (Color4::*)(const Color4 &) const >(_SC("opShl"), &Color4::operator ^) + .Func< Color4 (Color4::*)(const Color4 &) const >(_SC("opShl"), &Color4::operator <<) + .Func< Color4 (Color4::*)(const Color4 &) const >(_SC("opShr"), &Color4::operator >>) + + .Func< Color4 (Color4::*)(Color4::Value) const >(_SC("opAddS"), &Color4::operator +) + .Func< Color4 (Color4::*)(Color4::Value) const >(_SC("opSubS"), &Color4::operator -) + .Func< Color4 (Color4::*)(Color4::Value) const >(_SC("opMulS"), &Color4::operator *) + .Func< Color4 (Color4::*)(Color4::Value) const >(_SC("opDivS"), &Color4::operator /) + .Func< Color4 (Color4::*)(Color4::Value) const >(_SC("opModS"), &Color4::operator %) + .Func< Color4 (Color4::*)(Color4::Value) const >(_SC("opAndS"), &Color4::operator &) + .Func< Color4 (Color4::*)(Color4::Value) const >(_SC("opOrS"), &Color4::operator |) + .Func< Color4 (Color4::*)(Color4::Value) const >(_SC("opShlS"), &Color4::operator ^) + .Func< Color4 (Color4::*)(Color4::Value) const >(_SC("opShlS"), &Color4::operator <<) + .Func< Color4 (Color4::*)(Color4::Value) const >(_SC("opShrS"), &Color4::operator >>) + + .Func< Color4 (Color4::*)(void) const >(_SC("opUnPlus"), &Color4::operator +) + .Func< Color4 (Color4::*)(void) const >(_SC("opUnMinus"), &Color4::operator -) + .Func< Color4 (Color4::*)(void) const >(_SC("opCom"), &Color4::operator ~) + + .Func< bool (Color4::*)(const Color4 &) const >(_SC("opEqual"), &Color4::operator ==) + .Func< bool (Color4::*)(const Color4 &) const >(_SC("opNotEqual"), &Color4::operator !=) + .Func< bool (Color4::*)(const Color4 &) const >(_SC("opLessThan"), &Color4::operator <) + .Func< bool (Color4::*)(const Color4 &) const >(_SC("opGreaterThan"), &Color4::operator >) + .Func< bool (Color4::*)(const Color4 &) const >(_SC("opLessEqual"), &Color4::operator <=) + .Func< bool (Color4::*)(const Color4 &) const >(_SC("opGreaterEqual"), &Color4::operator >=) ); } diff --git a/source/Base/Color4.hpp b/source/Base/Color4.hpp index 27dc7e79..c01337c2 100644 --- a/source/Base/Color4.hpp +++ b/source/Base/Color4.hpp @@ -7,16 +7,6 @@ // ------------------------------------------------------------------------------------------------ namespace SqMod { -/* ------------------------------------------------------------------------------------------------ - * Extract the values for components of the Color4 type from a string. -*/ -const Color4 & GetColor4(CSStr str); - -/* ------------------------------------------------------------------------------------------------ - * Extract the values for components of the Color4 type from a string. -*/ -const Color4 & GetColor4(CSStr str, SQChar delim); - /* ------------------------------------------------------------------------------------------------ * Class used to represent a transparent RGBA color. */ @@ -486,6 +476,17 @@ struct Color4 * Inverse the color. */ void Inverse(); + + /* -------------------------------------------------------------------------------------------- + * Extract the values for components of the Color4 type from a string. + */ + static const Color4 & Get(CSStr str); + + /* -------------------------------------------------------------------------------------------- + * Extract the values for components of the Color4 type from a string. + */ + static const Color4 & Get(CSStr str, SQChar delim); + }; } // Namespace:: SqMod diff --git a/source/Base/Quaternion.cpp b/source/Base/Quaternion.cpp index e2d98d80..c774a9cb 100644 --- a/source/Base/Quaternion.cpp +++ b/source/Base/Quaternion.cpp @@ -22,7 +22,7 @@ SQChar Quaternion::Delim = ','; // ------------------------------------------------------------------------------------------------ SQInteger Quaternion::Typename(HSQUIRRELVM vm) { - static SQChar name[] = _SC("Quaternion"); + static const SQChar name[] = _SC("Quaternion"); sq_pushstring(vm, name, sizeof(name)); return 1; } @@ -122,10 +122,10 @@ Quaternion & Quaternion::operator /= (const Quaternion & q) Quaternion & Quaternion::operator %= (const Quaternion & q) { - x = fmod(x, q.x); - y = fmod(y, q.y); - z = fmod(z, q.z); - w = fmod(w, q.w); + x = std::fmod(x, q.x); + y = std::fmod(y, q.y); + z = std::fmod(z, q.z); + w = std::fmod(w, q.w); return *this; } @@ -168,10 +168,10 @@ Quaternion & Quaternion::operator /= (Value s) Quaternion & Quaternion::operator %= (Value s) { - x = fmod(x, s); - y = fmod(y, s); - z = fmod(z, s); - w = fmod(w, s); + x = std::fmod(x, s); + y = std::fmod(y, s); + z = std::fmod(z, s); + w = std::fmod(w, s); return *this; } @@ -262,18 +262,18 @@ Quaternion Quaternion::operator / (Value s) const // ------------------------------------------------------------------------------------------------ Quaternion Quaternion::operator % (const Quaternion & q) const { - return Quaternion(fmod(x, q.x), fmod(y, q.y), fmod(z, q.z), fmod(w, q.w)); + return Quaternion(std::fmod(x, q.x), std::fmod(y, q.y), std::fmod(z, q.z), std::fmod(w, q.w)); } Quaternion Quaternion::operator % (Value s) const { - return Quaternion(fmod(x, s), fmod(y, s), fmod(z, s), fmod(w, s)); + return Quaternion(std::fmod(x, s), std::fmod(y, s), std::fmod(z, s), std::fmod(w, s)); } // ------------------------------------------------------------------------------------------------ Quaternion Quaternion::operator + () const { - return Quaternion(fabs(x), fabs(y), fabs(z), fabs(w)); + return Quaternion(std::fabs(x), std::fabs(y), std::fabs(z), std::fabs(w)); } Quaternion Quaternion::operator - () const @@ -316,11 +316,17 @@ bool Quaternion::operator >= (const Quaternion & q) const Int32 Quaternion::Cmp(const Quaternion & o) const { if (*this == o) + { return 0; + } else if (*this > o) + { return 1; + } else + { return -1; + } } // ------------------------------------------------------------------------------------------------ @@ -381,7 +387,7 @@ void Quaternion::Set(const Vector4 & v) // ------------------------------------------------------------------------------------------------ void Quaternion::Set(CSStr values, SQChar delim) { - Set(GetQuaternion(values, delim)); + Set(Quaternion::Get(values, delim)); } // ------------------------------------------------------------------------------------------------ @@ -396,7 +402,9 @@ void Quaternion::Generate() void Quaternion::Generate(Value min, Value max) { if (EpsLt(max, min)) + { STHROWF("max value is lower than min value"); + } x = GetRandomFloat32(min, max); y = GetRandomFloat32(min, max); @@ -407,7 +415,9 @@ void Quaternion::Generate(Value min, Value max) void Quaternion::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax, Value wmin, Value wmax) { if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin) || EpsLt(zmax, zmin) || EpsLt(wmax, wmin)) + { STHROWF("max value is lower than min value"); + } x = GetRandomFloat32(xmin, xmax); y = GetRandomFloat32(ymin, ymax); @@ -418,17 +428,17 @@ void Quaternion::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value // ------------------------------------------------------------------------------------------------ Quaternion Quaternion::Abs() const { - return Quaternion(fabs(x), fabs(y), fabs(z), fabs(w)); + return Quaternion(std::fabs(x), std::fabs(y), std::fabs(z), std::fabs(w)); } // ------------------------------------------------------------------------------------------------ -const Quaternion & GetQuaternion(CSStr str) +const Quaternion & Quaternion::Get(CSStr str) { - return GetQuaternion(str, Quaternion::Delim); + return Quaternion::Get(str, Quaternion::Delim); } // ------------------------------------------------------------------------------------------------ -const Quaternion & GetQuaternion(CSStr str, SQChar delim) +const Quaternion & Quaternion::Get(CSStr str, SQChar delim) { // The format specifications that will be used to scan the string static SQChar fs[] = _SC(" %f , %f , %f , %f "); @@ -445,98 +455,134 @@ const Quaternion & GetQuaternion(CSStr str, SQChar delim) fs[9] = delim; fs[14] = delim; // Attempt to extract the component values from the specified string - sscanf(str, fs, &quat.x, &quat.y, &quat.z, &quat.w); + std::sscanf(str, fs, &quat.x, &quat.y, &quat.z, &quat.w); // Return the resulted value return quat; } +// ------------------------------------------------------------------------------------------------ +const Quaternion & GetQuaternion() +{ + static Quaternion quat; + quat.Clear(); + return quat; +} + +const Quaternion & GetQuaternion(Float32 sv) +{ + static Quaternion quat; + quat.Set(sv); + return quat; +} + +const Quaternion & GetQuaternion(Float32 xv, Float32 yv, Float32 zv) +{ + static Quaternion quat; + quat.Set(xv, yv, zv); + return quat; +} + +const Quaternion & GetQuaternion(Float32 xv, Float32 yv, Float32 zv, Float32 wv) +{ + static Quaternion quat; + quat.Set(xv, yv, zv, wv); + return quat; +} + +const Quaternion & GetQuaternion(const Quaternion & o) +{ + static Quaternion quat; + quat.Set(o); + return quat; +} + // ================================================================================================ void Register_Quaternion(HSQUIRRELVM vm) { typedef Quaternion::Value Val; RootTable(vm).Bind(_SC("Quaternion"), Class< Quaternion >(vm, _SC("Quaternion")) - /* Constructors */ + // Constructors .Ctor() .Ctor< Val >() .Ctor< Val, Val, Val >() .Ctor< Val, Val, Val, Val >() - /* Static Members */ + // Static Members .SetStaticValue(_SC("Delim"), &Quaternion::Delim) - /* Member Variables */ - .Var(_SC("x"), &Quaternion::x) - .Var(_SC("y"), &Quaternion::y) - .Var(_SC("z"), &Quaternion::z) - .Var(_SC("w"), &Quaternion::w) - /* Properties */ - .Prop(_SC("abs"), &Quaternion::Abs) - /* Core Metamethods */ + // Member Variables + .Var(_SC("X"), &Quaternion::x) + .Var(_SC("Y"), &Quaternion::y) + .Var(_SC("Z"), &Quaternion::z) + .Var(_SC("W"), &Quaternion::w) + // Properties + .Prop(_SC("Abs"), &Quaternion::Abs) + // Core Metamethods .Func(_SC("_tostring"), &Quaternion::ToString) .SquirrelFunc(_SC("_typename"), &Quaternion::Typename) .Func(_SC("_cmp"), &Quaternion::Cmp) - /* Metamethods */ - .Func(_SC("_add"), &Quaternion::operator +) - .Func(_SC("_sub"), &Quaternion::operator -) - .Func(_SC("_mul"), &Quaternion::operator *) - .Func(_SC("_div"), &Quaternion::operator /) - .Func(_SC("_modulo"), &Quaternion::operator %) - .Func(_SC("_unm"), &Quaternion::operator -) - /* Setters */ - .Overload(_SC("Set"), &Quaternion::Set) - .Overload(_SC("Set"), &Quaternion::Set) - .Overload(_SC("Set"), &Quaternion::Set) - .Overload(_SC("SetQuat"), &Quaternion::Set) - .Overload(_SC("SetVec3"), &Quaternion::Set) - .Overload(_SC("SetVec4"), &Quaternion::Set) - .Overload(_SC("SetStr"), &Quaternion::Set) - /* Random Generators */ - .Overload(_SC("Generate"), &Quaternion::Generate) - .Overload(_SC("Generate"), &Quaternion::Generate) - .Overload(_SC("Generate"), &Quaternion::Generate) - /* Utility Methods */ + // Metamethods + .Func< Quaternion (Quaternion::*)(const Quaternion &) const >(_SC("_add"), &Quaternion::operator +) + .Func< Quaternion (Quaternion::*)(const Quaternion &) const >(_SC("_sub"), &Quaternion::operator -) + .Func< Quaternion (Quaternion::*)(const Quaternion &) const >(_SC("_mul"), &Quaternion::operator *) + .Func< Quaternion (Quaternion::*)(const Quaternion &) const >(_SC("_div"), &Quaternion::operator /) + .Func< Quaternion (Quaternion::*)(const Quaternion &) const >(_SC("_modulo"), &Quaternion::operator %) + .Func< Quaternion (Quaternion::*)(void) const >(_SC("_unm"), &Quaternion::operator -) + // Setters + .Overload< void (Quaternion::*)(Val) >(_SC("Set"), &Quaternion::Set) + .Overload< void (Quaternion::*)(Val, Val, Val) >(_SC("Set"), &Quaternion::Set) + .Overload< void (Quaternion::*)(Val, Val, Val, Val) >(_SC("Set"), &Quaternion::Set) + .Overload< void (Quaternion::*)(const Quaternion &) >(_SC("SetQuat"), &Quaternion::Set) + .Overload< void (Quaternion::*)(const Vector3 &) >(_SC("SetVec3"), &Quaternion::Set) + .Overload< void (Quaternion::*)(const Vector4 &) >(_SC("SetVec4"), &Quaternion::Set) + .Overload< void (Quaternion::*)(CSStr, SQChar) >(_SC("SetStr"), &Quaternion::Set) + // Random Generators + .Overload< void (Quaternion::*)(void) >(_SC("Generate"), &Quaternion::Generate) + .Overload< void (Quaternion::*)(Val, Val) >(_SC("Generate"), &Quaternion::Generate) + .Overload< void (Quaternion::*)(Val, Val, Val, Val, Val, Val, Val, Val) >(_SC("Generate"), &Quaternion::Generate) + // Utility Methods .Func(_SC("Clear"), &Quaternion::Clear) - /* Operator Exposure */ - .Func(_SC("opAddAssign"), &Quaternion::operator +=) - .Func(_SC("opSubAssign"), &Quaternion::operator -=) - .Func(_SC("opMulAssign"), &Quaternion::operator *=) - .Func(_SC("opDivAssign"), &Quaternion::operator /=) - .Func(_SC("opModAssign"), &Quaternion::operator %=) - - .Func(_SC("opAddAssignS"), &Quaternion::operator +=) - .Func(_SC("opSubAssignS"), &Quaternion::operator -=) - .Func(_SC("opMulAssignS"), &Quaternion::operator *=) - .Func(_SC("opDivAssignS"), &Quaternion::operator /=) - .Func(_SC("opModAssignS"), &Quaternion::operator %=) - - .Func(_SC("opPreInc"), &Quaternion::operator ++) - .Func(_SC("opPreDec"), &Quaternion::operator --) - .Func(_SC("opPostInc"), &Quaternion::operator ++) - .Func(_SC("opPostDec"), &Quaternion::operator --) - - .Func(_SC("opAdd"), &Quaternion::operator +) - .Func(_SC("opSub"), &Quaternion::operator -) - .Func(_SC("opMul"), &Quaternion::operator *) - .Func(_SC("opDiv"), &Quaternion::operator /) - .Func(_SC("opMod"), &Quaternion::operator %) - - .Func(_SC("opAddS"), &Quaternion::operator +) - .Func(_SC("opSubS"), &Quaternion::operator -) - .Func(_SC("opMulS"), &Quaternion::operator *) - .Func(_SC("opDivS"), &Quaternion::operator /) - .Func(_SC("opModS"), &Quaternion::operator %) - - .Func(_SC("opUnPlus"), &Quaternion::operator +) - .Func(_SC("opUnMinus"), &Quaternion::operator -) - - .Func(_SC("opEqual"), &Quaternion::operator ==) - .Func(_SC("opNotEqual"), &Quaternion::operator !=) - .Func(_SC("opLessThan"), &Quaternion::operator <) - .Func(_SC("opGreaterThan"), &Quaternion::operator >) - .Func(_SC("opLessEqual"), &Quaternion::operator <=) - .Func(_SC("opGreaterEqual"), &Quaternion::operator >=) // Static Overloads - .StaticOverload< const Quaternion & (*)(CSStr) >(_SC("FromStr"), &GetQuaternion) - .StaticOverload< const Quaternion & (*)(CSStr, SQChar) >(_SC("FromStr"), &GetQuaternion) + .StaticOverload< const Quaternion & (*)(CSStr) >(_SC("FromStr"), &Quaternion::Get) + .StaticOverload< const Quaternion & (*)(CSStr, SQChar) >(_SC("FromStr"), &Quaternion::Get) + // Operator Exposure + .Func< Quaternion & (Quaternion::*)(const Quaternion &) >(_SC("opAddAssign"), &Quaternion::operator +=) + .Func< Quaternion & (Quaternion::*)(const Quaternion &) >(_SC("opSubAssign"), &Quaternion::operator -=) + .Func< Quaternion & (Quaternion::*)(const Quaternion &) >(_SC("opMulAssign"), &Quaternion::operator *=) + .Func< Quaternion & (Quaternion::*)(const Quaternion &) >(_SC("opDivAssign"), &Quaternion::operator /=) + .Func< Quaternion & (Quaternion::*)(const Quaternion &) >(_SC("opModAssign"), &Quaternion::operator %=) + + .Func< Quaternion & (Quaternion::*)(Quaternion::Value) >(_SC("opAddAssignS"), &Quaternion::operator +=) + .Func< Quaternion & (Quaternion::*)(Quaternion::Value) >(_SC("opSubAssignS"), &Quaternion::operator -=) + .Func< Quaternion & (Quaternion::*)(Quaternion::Value) >(_SC("opMulAssignS"), &Quaternion::operator *=) + .Func< Quaternion & (Quaternion::*)(Quaternion::Value) >(_SC("opDivAssignS"), &Quaternion::operator /=) + .Func< Quaternion & (Quaternion::*)(Quaternion::Value) >(_SC("opModAssignS"), &Quaternion::operator %=) + + .Func< Quaternion & (Quaternion::*)(void) >(_SC("opPreInc"), &Quaternion::operator ++) + .Func< Quaternion & (Quaternion::*)(void) >(_SC("opPreDec"), &Quaternion::operator --) + .Func< Quaternion (Quaternion::*)(int) >(_SC("opPostInc"), &Quaternion::operator ++) + .Func< Quaternion (Quaternion::*)(int) >(_SC("opPostDec"), &Quaternion::operator --) + + .Func< Quaternion (Quaternion::*)(const Quaternion &) const >(_SC("opAdd"), &Quaternion::operator +) + .Func< Quaternion (Quaternion::*)(const Quaternion &) const >(_SC("opSub"), &Quaternion::operator -) + .Func< Quaternion (Quaternion::*)(const Quaternion &) const >(_SC("opMul"), &Quaternion::operator *) + .Func< Quaternion (Quaternion::*)(const Quaternion &) const >(_SC("opDiv"), &Quaternion::operator /) + .Func< Quaternion (Quaternion::*)(const Quaternion &) const >(_SC("opMod"), &Quaternion::operator %) + + .Func< Quaternion (Quaternion::*)(Quaternion::Value) const >(_SC("opAddS"), &Quaternion::operator +) + .Func< Quaternion (Quaternion::*)(Quaternion::Value) const >(_SC("opSubS"), &Quaternion::operator -) + .Func< Quaternion (Quaternion::*)(Quaternion::Value) const >(_SC("opMulS"), &Quaternion::operator *) + .Func< Quaternion (Quaternion::*)(Quaternion::Value) const >(_SC("opDivS"), &Quaternion::operator /) + .Func< Quaternion (Quaternion::*)(Quaternion::Value) const >(_SC("opModS"), &Quaternion::operator %) + + .Func< Quaternion (Quaternion::*)(void) const >(_SC("opUnPlus"), &Quaternion::operator +) + .Func< Quaternion (Quaternion::*)(void) const >(_SC("opUnMinus"), &Quaternion::operator -) + + .Func< bool (Quaternion::*)(const Quaternion &) const >(_SC("opEqual"), &Quaternion::operator ==) + .Func< bool (Quaternion::*)(const Quaternion &) const >(_SC("opNotEqual"), &Quaternion::operator !=) + .Func< bool (Quaternion::*)(const Quaternion &) const >(_SC("opLessThan"), &Quaternion::operator <) + .Func< bool (Quaternion::*)(const Quaternion &) const >(_SC("opGreaterThan"), &Quaternion::operator >) + .Func< bool (Quaternion::*)(const Quaternion &) const >(_SC("opLessEqual"), &Quaternion::operator <=) + .Func< bool (Quaternion::*)(const Quaternion &) const >(_SC("opGreaterEqual"), &Quaternion::operator >=) ); } diff --git a/source/Base/Quaternion.hpp b/source/Base/Quaternion.hpp index eb52e99c..8e6d16c8 100644 --- a/source/Base/Quaternion.hpp +++ b/source/Base/Quaternion.hpp @@ -7,16 +7,6 @@ // ------------------------------------------------------------------------------------------------ namespace SqMod { -/* ------------------------------------------------------------------------------------------------ - * Extract the values for components of the Quaternion type from a string. -*/ -const Quaternion & GetQuaternion(CSStr str); - -/* ------------------------------------------------------------------------------------------------ - * Extract the values for components of the Quaternion type from a string. -*/ -const Quaternion & GetQuaternion(CSStr str, SQChar delim); - /* ------------------------------------------------------------------------------------------------ * Quaternion class for representing rotations. */ @@ -341,6 +331,17 @@ struct Quaternion * Retrieve a new instance of this type with absolute component values. */ Quaternion Abs() const; + + /* -------------------------------------------------------------------------------------------- + * Extract the values for components of the Quaternion type from a string. + */ + static const Quaternion & Get(CSStr str); + + /* -------------------------------------------------------------------------------------------- + * Extract the values for components of the Quaternion type from a string. + */ + static const Quaternion & Get(CSStr str, SQChar delim); + }; } // Namespace:: SqMod diff --git a/source/Base/Shared.cpp b/source/Base/Shared.cpp index ff6701d0..660b0e02 100644 --- a/source/Base/Shared.cpp +++ b/source/Base/Shared.cpp @@ -1,11 +1,10 @@ // ------------------------------------------------------------------------------------------------ #include "Base/Shared.hpp" #include "Base/Buffer.hpp" +#include "Base/Color3.hpp" #include "Library/Random.hpp" #include "Library/String.hpp" - -// ------------------------------------------------------------------------------------------------ -#include "Base/Color3.hpp" +#include "Library/Numeric.hpp" // ------------------------------------------------------------------------------------------------ #include @@ -22,13 +21,9 @@ namespace SqMod { // ------------------------------------------------------------------------------------------------ -static const SQChar EMPTY_STR_CHAR = 0; -const SQChar * g_EmptyStr = &EMPTY_STR_CHAR; - -// ------------------------------------------------------------------------------------------------ -PluginFuncs* _Func = NULL; -PluginCallbacks* _Clbk = NULL; -PluginInfo* _Info = NULL; +PluginFuncs* _Func = nullptr; +PluginCallbacks* _Clbk = nullptr; +PluginInfo* _Info = nullptr; /* ------------------------------------------------------------------------------------------------ * Common buffer to reduce memory allocations. To be immediately copied upon return! @@ -36,108 +31,6 @@ PluginInfo* _Info = NULL; static SQChar g_Buffer[4096]; static SQChar g_NumBuff[1024]; -// ------------------------------------------------------------------------------------------------ -Object & NullObject() -{ - static Object o; - o.Release(); - return o; -} - -// ------------------------------------------------------------------------------------------------ -Array & NullArray() -{ - static Array a; - a.Release(); - return a; -} - -// ------------------------------------------------------------------------------------------------ -Function & NullFunction() -{ - static Function f; - f.Release(); - return f; -} - -// ------------------------------------------------------------------------------------------------ -bool SToB(CSStr str) -{ - // Temporary buffer to store the lowercase string - SQChar buffer[8]; - // The currently processed character - unsigned i = 0; - // Convert only the necessary characters to lowercase - while (i < 7 && *str != '\0') - { - buffer[i++] = static_cast< SQChar >(std::tolower(*(str++))); - } - // Add the null terminator - buffer[i] = '\0'; - // Compare the lowercase string and return the result - return (std::strcmp(buffer, "true") == 0 || std::strcmp(buffer, "yes") == 0 || - std::strcmp(buffer, "on") == 0 || std::strcmp(buffer, "1") == 0) ? true : false; -} - -// ------------------------------------------------------------------------------------------------ -void SqThrowF(CSStr fmt, ...) -{ - // Acquire a moderately sized buffer - Buffer b(128); - // Initialize the argument list - va_list args; - va_start (args, fmt); - // Attempt to run the specified format - if (b.WriteF(0, fmt, args) == 0) - { - // Attempt to write a generic message at least - b.At(b.WriteS(0, "Unknown error has occurred")) = '\0'; - } - // Release the argument list - va_end(args); - // Throw the exception with the resulted message - throw Sqrat::Exception(b.Get< SQChar >()); -} - -// ------------------------------------------------------------------------------------------------ -CSStr ToStrF(CSStr fmt, ...) -{ - // Prepare the arguments list - va_list args; - va_start(args, fmt); - // Attempt to run the specified format - int ret = vsnprintf(g_Buffer, sizeof(g_Buffer), fmt, args); - // See if the format function failed - if (ret < 0) - { - STHROWF("Failed to run the specified string format"); - } - // Finalized the arguments list - va_end(args); - // Return the resulted string - return g_Buffer; -} - -// ------------------------------------------------------------------------------------------------ -CSStr ToStringF(CSStr fmt, ...) -{ - // Acquire a moderately sized buffer - Buffer b(128); - // Prepare the arguments list - va_list args; - va_start (args, fmt); - // Attempt to run the specified format - if (b.WriteF(0, fmt, args) == 0) - { - // Make sure the string is null terminated - b.At(0) = 0; - } - // Finalized the arguments list - va_end(args); - // Return the resulted string - return b.Get< SQChar >(); -} - // ------------------------------------------------------------------------------------------------ static const Color3 SQ_Color_List[] = { @@ -283,6 +176,158 @@ static const Color3 SQ_Color_List[] = Color3(154, 205, 50) }; +// ------------------------------------------------------------------------------------------------ +const SLongInt & GetSLongInt() +{ + static SLongInt l; + l.SetNum(0); + return l; +} + +const SLongInt & GetSLongInt(Int64 n) +{ + static SLongInt l; + l.SetNum(n); + return l; +} + +const SLongInt & GetSLongInt(CSStr s) +{ + static SLongInt l; + l = s; + return l; +} + +const ULongInt & GetULongInt() +{ + static ULongInt l; + l.SetNum(0); + return l; +} + +const ULongInt & GetULongInt(Uint64 n) +{ + static ULongInt l; + l.SetNum(n); + return l; +} + +const ULongInt & GetULongInt(CSStr s) +{ + static ULongInt l; + l = s; + return l; +} + +// ------------------------------------------------------------------------------------------------ +Object & NullObject() +{ + static Object o; + o.Release(); + return o; +} + +// ------------------------------------------------------------------------------------------------ +Table & NullTable() +{ + static Table t; + t.Release(); + return t; +} + +// ------------------------------------------------------------------------------------------------ +Array & NullArray() +{ + static Array a; + a.Release(); + return a; +} + +// ------------------------------------------------------------------------------------------------ +Function & NullFunction() +{ + static Function f; + f.Release(); + return f; +} + +// ------------------------------------------------------------------------------------------------ +bool SToB(CSStr str) +{ + // Temporary buffer to store the lowercase string + SQChar buffer[8]; + // The currently processed character + unsigned i = 0; + // Convert only the necessary characters to lowercase + while (i < 7 && *str != '\0') + { + buffer[i++] = static_cast< SQChar >(std::tolower(*(str++))); + } + // Add the null terminator + buffer[i] = '\0'; + // Compare the lowercase string and return the result + return (std::strcmp(buffer, "true") == 0 || std::strcmp(buffer, "yes") == 0 || + std::strcmp(buffer, "on") == 0 || std::strcmp(buffer, "1") == 0) ? true : false; +} +// ------------------------------------------------------------------------------------------------ +void SqThrowF(CSStr fmt, ...) +{ + // Acquire a moderately sized buffer + Buffer b(128); + // Initialize the argument list + va_list args; + va_start (args, fmt); + // Attempt to run the specified format + if (b.WriteF(0, fmt, args) == 0) + { + // Attempt to write a generic message at least + b.At(b.WriteS(0, "Unknown error has occurred")) = '\0'; + } + // Release the argument list + va_end(args); + // Throw the exception with the resulted message + throw Sqrat::Exception(b.Get< SQChar >()); +} + +// ------------------------------------------------------------------------------------------------ +CSStr ToStrF(CSStr fmt, ...) +{ + // Prepare the arguments list + va_list args; + va_start(args, fmt); + // Attempt to run the specified format + int ret = vsnprintf(g_Buffer, sizeof(g_Buffer), fmt, args); + // See if the format function failed + if (ret < 0) + { + STHROWF("Failed to run the specified string format"); + } + // Finalized the arguments list + va_end(args); + // Return the resulted string + return g_Buffer; +} + +// ------------------------------------------------------------------------------------------------ +CSStr ToStringF(CSStr fmt, ...) +{ + // Acquire a moderately sized buffer + Buffer b(128); + // Prepare the arguments list + va_list args; + va_start (args, fmt); + // Attempt to run the specified format + if (b.WriteF(0, fmt, args) == 0) + { + // Make sure the string is null terminated + b.At(0) = 0; + } + // Finalized the arguments list + va_end(args); + // Return the resulted string + return b.Get< SQChar >(); +} + // ------------------------------------------------------------------------------------------------ const Color3 & GetRandomColor() { @@ -1190,13 +1235,17 @@ bool ConvNum< bool >::FromStr(CSStr s, Int32 /*base*/) void Register_Base(HSQUIRRELVM vm) { RootTable(vm) - .Func(_SC("EpsEq"), &EpsEq) - .Func(_SC("EpsLt"), &EpsLt) - .Func(_SC("EpsGt"), &EpsGt) - .Func(_SC("EpsLtEq"), &EpsLtEq) - .Func(_SC("EpsGtEq"), &EpsGtEq) - .Func(_SC("ClampI"), &Clamp) - .Func(_SC("ClampF"), &Clamp) + .Func(_SC("EpsEq"), &EpsEq< SQFloat >) + .Func(_SC("EpsLt"), &EpsLt< SQFloat >) + .Func(_SC("EpsGt"), &EpsGt< SQFloat >) + .Func(_SC("EpsLtEq"), &EpsLtEq< SQFloat >) + .Func(_SC("EpsGtEq"), &EpsGtEq< SQFloat >) + .Func(_SC("ClampI"), &Clamp< SQInteger >) + .Func(_SC("ClampF"), &Clamp< SQFloat >) + .Func(_SC("ClampMinI"), &ClampMin< SQInteger >) + .Func(_SC("ClampMinF"), &ClampMin< SQFloat >) + .Func(_SC("ClampMaxI"), &ClampMax< SQInteger >) + .Func(_SC("ClampMaxF"), &ClampMax< SQFloat >) .Func(_SC("NextPow2"), &NextPow2) .Func(_SC("SToB"), &SToB) .Func(_SC("GetColor"), &GetColor); diff --git a/source/Base/Shared.hpp b/source/Base/Shared.hpp index d90ad206..181d33d3 100644 --- a/source/Base/Shared.hpp +++ b/source/Base/Shared.hpp @@ -15,9 +15,6 @@ // ------------------------------------------------------------------------------------------------ namespace SqMod { -// ------------------------------------------------------------------------------------------------ -extern const SQChar * g_EmptyStr; - /* ------------------------------------------------------------------------------------------------ * Proxies to communicate with the server. */ @@ -25,6 +22,176 @@ extern PluginFuncs* _Func; extern PluginCallbacks* _Clbk; extern PluginInfo* _Info; +/* ------------------------------------------------------------------------------------------------ + * Forward declarations of the logging functions to avoid including the logger everywhere. + * Primary logging functions. +*/ +extern void LogDbg(CCStr fmt, ...); +extern void LogUsr(CCStr fmt, ...); +extern void LogScs(CCStr fmt, ...); +extern void LogInf(CCStr fmt, ...); +extern void LogWrn(CCStr fmt, ...); +extern void LogErr(CCStr fmt, ...); +extern void LogFtl(CCStr fmt, ...); + +/* ------------------------------------------------------------------------------------------------ + * Forward declarations of the logging functions to avoid including the logger everywhere. + * Secondary logging functions. +*/ +extern void LogSDbg(CCStr fmt, ...); +extern void LogSUsr(CCStr fmt, ...); +extern void LogSScs(CCStr fmt, ...); +extern void LogSInf(CCStr fmt, ...); +extern void LogSWrn(CCStr fmt, ...); +extern void LogSErr(CCStr fmt, ...); +extern void LogSFtl(CCStr fmt, ...); + +/* ------------------------------------------------------------------------------------------------ + * Forward declarations of the logging functions to avoid including the logger everywhere. + * Primary conditional logging functions. +*/ +extern bool cLogDbg(bool exp, CCStr fmt, ...); +extern bool cLogUsr(bool exp, CCStr fmt, ...); +extern bool cLogScs(bool exp, CCStr fmt, ...); +extern bool cLogInf(bool exp, CCStr fmt, ...); +extern bool cLogWrn(bool exp, CCStr fmt, ...); +extern bool cLogErr(bool exp, CCStr fmt, ...); +extern bool cLogFtl(bool exp, CCStr fmt, ...); + +/* ------------------------------------------------------------------------------------------------ + * Forward declarations of the logging functions to avoid including the logger everywhere. + * Secondary conditional logging functions. +*/ +extern bool cLogSDbg(bool exp, CCStr fmt, ...); +extern bool cLogSUsr(bool exp, CCStr fmt, ...); +extern bool cLogSScs(bool exp, CCStr fmt, ...); +extern bool cLogSInf(bool exp, CCStr fmt, ...); +extern bool cLogSWrn(bool exp, CCStr fmt, ...); +extern bool cLogSErr(bool exp, CCStr fmt, ...); +extern bool cLogSFtl(bool exp, CCStr fmt, ...); + +/* ------------------------------------------------------------------------------------------------ + * Output a message only if the _DEBUG was defined. +*/ +extern void OutputDebug(const char * msg, ...); + +/* ------------------------------------------------------------------------------------------------ + * Output a formatted user message to the console. +*/ +extern void OutputMessage(const char * msg, ...); + +/* ------------------------------------------------------------------------------------------------ + * Output a formatted error message to the console. +*/ +extern void OutputError(const char * msg, ...); + +/* ------------------------------------------------------------------------------------------------ + * Get a persistent AABB instance with the given values. +*/ +extern const AABB & GetAABB(); +extern const AABB & GetAABB(Float32 sv); +extern const AABB & GetAABB(Float32 xv, Float32 yv, Float32 zv); +extern const AABB & GetAABB(Float32 xmin, Float32 ymin, Float32 zmin, Float32 xmax, Float32 ymax, Float32 zmax); +extern const AABB & GetAABB(const Vector3 & vmin, const Vector3 & vmax); +extern const AABB & GetAABB(const AABB & o); +extern const AABB & GetAABB(AABB && o); + +/* ------------------------------------------------------------------------------------------------ + * Get a persistent Circle instance with the given values. +*/ +extern const Circle & GetCircle(); +extern const Circle & GetCircle(Float32 rv); +extern const Circle & GetCircle(const Vector2 & pv, Float32 rv); +extern const Circle & GetCircle(Float32 xv, Float32 yv, Float32 rv); +extern const Circle & GetCircle(const Circle & o); +extern const Circle & GetCircle(Circle && o); + +/* ------------------------------------------------------------------------------------------------ + * Get a persistent Color3 instance with the given values. +*/ +extern const Color3 & GetColor3(); +extern const Color3 & GetColor3(Uint8 sv); +extern const Color3 & GetColor3(Uint8 rv, Uint8 gv, Uint8 bv); +extern const Color3 & GetColor3(const Color3 & o); +extern const Color3 & GetColor3(Color3 && o); + +/* ------------------------------------------------------------------------------------------------ + * Get a persistent Color4 instance with the given values. +*/ +extern const Color4 & GetColor4(); +extern const Color4 & GetColor4(Uint8 sv); +extern const Color4 & GetColor4(Uint8 rv, Uint8 gv, Uint8 bv); +extern const Color4 & GetColor4(Uint8 rv, Uint8 gv, Uint8 bv, Uint8 av); +extern const Color4 & GetColor4(const Color4 & o); +extern const Color4 & GetColor4(Color4 && o); + +/* ------------------------------------------------------------------------------------------------ + * Get a persistent Quaternion instance with the given values. +*/ +extern const Quaternion & GetQuaternion(); +extern const Quaternion & GetQuaternion(Float32 sv); +extern const Quaternion & GetQuaternion(Float32 xv, Float32 yv, Float32 zv); +extern const Quaternion & GetQuaternion(Float32 xv, Float32 yv, Float32 zv, Float32 wv); +extern const Quaternion & GetQuaternion(const Quaternion & o); +extern const Quaternion & GetQuaternion(Quaternion && o); + +/* ------------------------------------------------------------------------------------------------ + * Get a persistent Sphere instance with the given values. +*/ +extern const Sphere & GetSphere(); +extern const Sphere & GetSphere(Float32 rv); +extern const Sphere & GetSphere(const Vector3 & pv, Float32 rv); +extern const Sphere & GetSphere(Float32 xv, Float32 yv, Float32 zv, Float32 rv); +extern const Sphere & GetSphere(const Sphere & o); +extern const Sphere & GetSphere(Sphere && o); + +/* ------------------------------------------------------------------------------------------------ + * Get a persistent Vector2 instance with the given values. +*/ +extern const Vector2 & GetVector2(); +extern const Vector2 & GetVector2(Float32 sv); +extern const Vector2 & GetVector2(Float32 xv, Float32 yv); +extern const Vector2 & GetVector2(const Vector2 & o); +extern const Vector2 & GetVector2(Vector2 && o); + +/* ------------------------------------------------------------------------------------------------ + * Get a persistent Vector2i instance with the given values. +*/ +extern const Vector2i & GetVector2i(); +extern const Vector2i & GetVector2i(Int32 sv); +extern const Vector2i & GetVector2i(Int32 xv, Int32 yv); +extern const Vector2i & GetVector2i(const Vector2i & o); +extern const Vector2i & GetVector2i(Vector2i && o); + +/* ------------------------------------------------------------------------------------------------ + * Get a persistent Vector3 instance with the given values. +*/ +extern const Vector3 & GetVector3(); +extern const Vector3 & GetVector3(Float32 sv); +extern const Vector3 & GetVector3(Float32 xv, Float32 yv, Float32 zv); +extern const Vector3 & GetVector3(const Vector3 & o); +extern const Vector3 & GetVector3(Vector3 && o); + +/* ------------------------------------------------------------------------------------------------ + * Get a persistent Vector4 instance with the given values. +*/ +extern const Vector4 & GetVector4(); +extern const Vector4 & GetVector4(Float32 sv); +extern const Vector4 & GetVector4(Float32 xv, Float32 yv, Float32 zv); +extern const Vector4 & GetVector4(Float32 xv, Float32 yv, Float32 zv, Float32 wv); +extern const Vector4 & GetVector4(const Vector4 & o); +extern const Vector4 & GetVector4(Vector4 && o); + +/* ------------------------------------------------------------------------------------------------ + * Get a persistent LongInt instance with the given values. +*/ +const SLongInt & GetSLongInt(); +const SLongInt & GetSLongInt(Int64 n); +const SLongInt & GetSLongInt(CSStr s); +const ULongInt & GetULongInt(); +const ULongInt & GetULongInt(Uint64 n); +const ULongInt & GetULongInt(CSStr s); + /* ------------------------------------------------------------------------------------------------ * Retrieve the maximum value of a fundamental type. */ @@ -1000,6 +1167,34 @@ template< typename T > inline T Clamp(T val, T min, T max) return val; } +/* ------------------------------------------------------------------------------------------------ + * Force a value to be higher then than the imposed limit. +*/ +template< typename T > inline T ClampMin(T val, T min) +{ + // Is the specified value bellow the minimum? + if (val < min) + { + return min; + } + // Return the value as is + return val; +} + +/* ------------------------------------------------------------------------------------------------ + * Force a value to be smaller then than the imposed limit. +*/ +template< typename T > inline T ClampMax(T val, T max) +{ + // Is the specified value above the maximum? + if (val > max) + { + return max; + } + // Return the value as is + return val; +} + /* ------------------------------------------------------------------------------------------------ * Force a value to be within a certain range. */ @@ -1060,26 +1255,16 @@ inline Uint32 NextPow2(Uint32 num) return ++num; } -/* ------------------------------------------------------------------------------------------------ - * Output a message only if the _DEBUG was defined. -*/ -void OutputDebug(const char * msg, ...); - -/* ------------------------------------------------------------------------------------------------ - * Output a formatted user message to the console. -*/ -void OutputMessage(const char * msg, ...); - -/* ------------------------------------------------------------------------------------------------ - * Output a formatted error message to the console. -*/ -void OutputError(const char * msg, ...); - /* ------------------------------------------------------------------------------------------------ * Retrieve a reference to a null script object. */ Object & NullObject(); +/* ------------------------------------------------------------------------------------------------ + * Retrieve a reference to a null/empty script table. +*/ +Table & NullTable(); + /* ------------------------------------------------------------------------------------------------ * Retrieve a reference to a null/empty script array. */ @@ -1120,54 +1305,6 @@ const Color3 & GetRandomColor(); */ Color3 GetColor(CSStr name); -/* ------------------------------------------------------------------------------------------------ - * Forward declarations of the logging functions to avoid including the logger everywhere. - * Primary logging functions. -*/ -void LogDbg(CCStr fmt, ...); -void LogUsr(CCStr fmt, ...); -void LogScs(CCStr fmt, ...); -void LogInf(CCStr fmt, ...); -void LogWrn(CCStr fmt, ...); -void LogErr(CCStr fmt, ...); -void LogFtl(CCStr fmt, ...); - -/* ------------------------------------------------------------------------------------------------ - * Forward declarations of the logging functions to avoid including the logger everywhere. - * Secondary logging functions. -*/ -void LogSDbg(CCStr fmt, ...); -void LogSUsr(CCStr fmt, ...); -void LogSScs(CCStr fmt, ...); -void LogSInf(CCStr fmt, ...); -void LogSWrn(CCStr fmt, ...); -void LogSErr(CCStr fmt, ...); -void LogSFtl(CCStr fmt, ...); - -/* ------------------------------------------------------------------------------------------------ - * Forward declarations of the logging functions to avoid including the logger everywhere. - * Primary conditional logging functions. -*/ -bool cLogDbg(bool cond, CCStr fmt, ...); -bool cLogUsr(bool cond, CCStr fmt, ...); -bool cLogScs(bool cond, CCStr fmt, ...); -bool cLogInf(bool cond, CCStr fmt, ...); -bool cLogWrn(bool cond, CCStr fmt, ...); -bool cLogErr(bool cond, CCStr fmt, ...); -bool cLogFtl(bool cond, CCStr fmt, ...); - -/* ------------------------------------------------------------------------------------------------ - * Forward declarations of the logging functions to avoid including the logger everywhere. - * Secondary conditional logging functions. -*/ -bool cLogSDbg(bool cond, CCStr fmt, ...); -bool cLogSUsr(bool cond, CCStr fmt, ...); -bool cLogSScs(bool cond, CCStr fmt, ...); -bool cLogSInf(bool cond, CCStr fmt, ...); -bool cLogSWrn(bool cond, CCStr fmt, ...); -bool cLogSErr(bool cond, CCStr fmt, ...); -bool cLogSFtl(bool cond, CCStr fmt, ...); - /* ------------------------------------------------------------------------------------------------ * Helper class allows the use of functions with ctype style as predicate for algorithms. */ @@ -1234,6 +1371,52 @@ public: } }; +/* ------------------------------------------------------------------------------------------------ + * Utility implementing RAII to toggle a bit mask on and off at all costs. +*/ +template < typename T > struct BitGuard +{ +private: + + /* ------------------------------------------------------------------------------------------------ + * The lock to be toggled. + */ + T & m_Lock; + + /* ------------------------------------------------------------------------------------------------ + * The mask to be applied. + */ + T m_Mask; + +public: + + /* ------------------------------------------------------------------------------------------------ + * Base constructor. + */ + BitGuard(T & lock, T mask) + : m_Lock(lock), m_Mask(mask) + { + // Apply the specified mask + m_Lock |= m_Mask; + } + + /* ------------------------------------------------------------------------------------------------ + * Destructor. + */ + ~BitGuard() + { + // In case one of the bits was turned off in the meantime + m_Lock |= m_Mask; + // Now turn off all the bits in the mask + m_Lock ^= m_Mask; + } +}; + +// ------------------------------------------------------------------------------------------------ +typedef BitGuard< Uint8 > BitGuardU8; +typedef BitGuard< Uint16 > BitGuardU16; +typedef BitGuard< Uint32 > BitGuardU32; + } // Namespace:: SqMod #endif // _BASE_SHARED_HPP_ diff --git a/source/Base/Sphere.cpp b/source/Base/Sphere.cpp index 08027d07..e11b2c8c 100644 --- a/source/Base/Sphere.cpp +++ b/source/Base/Sphere.cpp @@ -20,7 +20,7 @@ SQChar Sphere::Delim = ','; // ------------------------------------------------------------------------------------------------ SQInteger Sphere::Typename(HSQUIRRELVM vm) { - static SQChar name[] = _SC("Sphere"); + static const SQChar name[] = _SC("Sphere"); sq_pushstring(vm, name, sizeof(name)); return 1; } @@ -98,7 +98,7 @@ Sphere & Sphere::operator /= (const Sphere & s) Sphere & Sphere::operator %= (const Sphere & s) { pos %= s.pos; - rad = fmod(rad, s.rad); + rad = std::fmod(rad, s.rad); return *this; } @@ -130,7 +130,7 @@ Sphere & Sphere::operator /= (Value r) Sphere & Sphere::operator %= (Value r) { - rad = fmod(rad, r); + rad = std::fmod(rad, r); return *this; } @@ -220,7 +220,7 @@ Sphere Sphere::operator / (const Sphere & s) const Sphere Sphere::operator % (const Sphere & s) const { - return Sphere(pos % s.pos, fmod(rad, s.rad)); + return Sphere(pos % s.pos, std::fmod(rad, s.rad)); } // ------------------------------------------------------------------------------------------------ @@ -246,7 +246,7 @@ Sphere Sphere::operator / (Value r) const Sphere Sphere::operator % (Value r) const { - return Sphere(fmod(rad, r)); + return Sphere(std::fmod(rad, r)); } // ------------------------------------------------------------------------------------------------ @@ -278,7 +278,7 @@ Sphere Sphere::operator % (const Vector3 & p) const // ------------------------------------------------------------------------------------------------ Sphere Sphere::operator + () const { - return Sphere(pos.Abs(), fabs(rad)); + return Sphere(pos.Abs(), std::fabs(rad)); } Sphere Sphere::operator - () const @@ -321,11 +321,17 @@ bool Sphere::operator >= (const Sphere & s) const Int32 Sphere::Cmp(const Sphere & o) const { if (*this == o) + { return 0; + } else if (*this > o) + { return 1; + } else + { return -1; + } } // ------------------------------------------------------------------------------------------------ @@ -372,7 +378,7 @@ void Sphere::Set(Value nx, Value ny, Value nz, Value nr) // ------------------------------------------------------------------------------------------------ void Sphere::Set(CSStr values, SQChar delim) { - Set(GetSphere(values, delim)); + Set(Sphere::Get(values, delim)); } // ------------------------------------------------------------------------------------------------ @@ -385,17 +391,25 @@ void Sphere::Generate() void Sphere::Generate(Value min, Value max, bool r) { if (EpsLt(max, min)) + { STHROWF("max value is lower than min value"); + } else if (r) + { rad = GetRandomFloat32(min, max); + } else + { pos.Generate(min, max); + } } void Sphere::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax) { if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin) || EpsLt(zmax, zmin)) + { STHROWF("max value is lower than min value"); + } pos.Generate(xmin, xmax, ymin, ymax, zmin, zmax); } @@ -403,7 +417,9 @@ void Sphere::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin void Sphere::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax, Value rmin, Value rmax) { if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin) || EpsLt(zmax, zmin) || EpsLt(rmax, rmin)) + { STHROWF("max value is lower than min value"); + } pos.Generate(xmin, xmax, ymin, ymax, zmin, zmax); rad = GetRandomFloat32(rmin, rmax); @@ -412,17 +428,17 @@ void Sphere::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin // ------------------------------------------------------------------------------------------------ Sphere Sphere::Abs() const { - return Sphere(pos.Abs(), fabs(rad)); + return Sphere(pos.Abs(), std::fabs(rad)); } // ------------------------------------------------------------------------------------------------ -const Sphere & GetSphere(CSStr str) +const Sphere & Sphere::Get(CSStr str) { - return GetSphere(str, Sphere::Delim); + return Sphere::Get(str, Sphere::Delim); } // ------------------------------------------------------------------------------------------------ -const Sphere & GetSphere(CSStr str, SQChar delim) +const Sphere & Sphere::Get(CSStr str, SQChar delim) { // The format specifications that will be used to scan the string static SQChar fs[] = _SC(" %f , %f , %f , %f "); @@ -439,104 +455,140 @@ const Sphere & GetSphere(CSStr str, SQChar delim) fs[9] = delim; fs[14] = delim; // Attempt to extract the component values from the specified string - sscanf(str, fs, &sphere.pos.x, &sphere.pos.y, &sphere.pos.z, &sphere.rad); + std::sscanf(str, fs, &sphere.pos.x, &sphere.pos.y, &sphere.pos.z, &sphere.rad); // Return the resulted value return sphere; } +// ------------------------------------------------------------------------------------------------ +const Sphere & GetSphere() +{ + static Sphere sphere; + sphere.Clear(); + return sphere; +} + +const Sphere & GetSphere(Float32 rv) +{ + static Sphere sphere; + sphere.Set(rv); + return sphere; +} + +const Sphere & GetSphere(const Vector3 & pv, Float32 rv) +{ + static Sphere sphere; + sphere.Set(pv, rv); + return sphere; +} + +const Sphere & GetSphere(Float32 xv, Float32 yv, Float32 zv, Float32 rv) +{ + static Sphere sphere; + sphere.Set(xv, yv, zv, rv); + return sphere; +} + +const Sphere & GetSphere(const Sphere & o) +{ + static Sphere sphere; + sphere.Set(o); + return sphere; +} + // ================================================================================================ void Register_Sphere(HSQUIRRELVM vm) { typedef Sphere::Value Val; RootTable(vm).Bind(_SC("Sphere"), Class< Sphere >(vm, _SC("Sphere")) - /* Constructors */ + // Constructors .Ctor() .Ctor< Val >() .Ctor< const Vector3 &, Val >() .Ctor< Val, Val, Val, Val >() - /* Static Members */ + // Static Members .SetStaticValue(_SC("Delim"), &Sphere::Delim) - /* Member Variables */ - .Var(_SC("pos"), &Sphere::pos) - .Var(_SC("rad"), &Sphere::rad) - /* Properties */ - .Prop(_SC("abs"), &Sphere::Abs) - /* Core Metamethods */ + // Member Variables + .Var(_SC("Pos"), &Sphere::pos) + .Var(_SC("Rad"), &Sphere::rad) + // Properties + .Prop(_SC("Abs"), &Sphere::Abs) + // Core Metamethods .Func(_SC("_tostring"), &Sphere::ToString) .SquirrelFunc(_SC("_typename"), &Sphere::Typename) .Func(_SC("_cmp"), &Sphere::Cmp) - /* Metamethods */ - .Func(_SC("_add"), &Sphere::operator +) - .Func(_SC("_sub"), &Sphere::operator -) - .Func(_SC("_mul"), &Sphere::operator *) - .Func(_SC("_div"), &Sphere::operator /) - .Func(_SC("_modulo"), &Sphere::operator %) - .Func(_SC("_unm"), &Sphere::operator -) - /* Setters */ - .Overload(_SC("Set"), &Sphere::Set) - .Overload(_SC("Set"), &Sphere::Set) - .Overload(_SC("Set"), &Sphere::Set) - .Overload(_SC("SetRad"), &Sphere::Set) - .Overload(_SC("SetVec3"), &Sphere::Set) - .Overload(_SC("SetVec3"), &Sphere::Set) - .Overload(_SC("SetStr"), &Sphere::Set) - /* Utility Methods */ + // Metamethods + .Func< Sphere (Sphere::*)(const Sphere &) const >(_SC("_add"), &Sphere::operator +) + .Func< Sphere (Sphere::*)(const Sphere &) const >(_SC("_sub"), &Sphere::operator -) + .Func< Sphere (Sphere::*)(const Sphere &) const >(_SC("_mul"), &Sphere::operator *) + .Func< Sphere (Sphere::*)(const Sphere &) const >(_SC("_div"), &Sphere::operator /) + .Func< Sphere (Sphere::*)(const Sphere &) const >(_SC("_modulo"), &Sphere::operator %) + .Func< Sphere (Sphere::*)(void) const >(_SC("_unm"), &Sphere::operator -) + // Setters + .Overload< void (Sphere::*)(const Sphere &) >(_SC("Set"), &Sphere::Set) + .Overload< void (Sphere::*)(const Vector3 &, Val) >(_SC("Set"), &Sphere::Set) + .Overload< void (Sphere::*)(Val, Val, Val, Val) >(_SC("Set"), &Sphere::Set) + .Overload< void (Sphere::*)(Val) >(_SC("SetRad"), &Sphere::Set) + .Overload< void (Sphere::*)(const Vector3 &) >(_SC("SetVec3"), &Sphere::Set) + .Overload< void (Sphere::*)(Val, Val, Val) >(_SC("SetVec3"), &Sphere::Set) + .Overload< void (Sphere::*)(CSStr, SQChar) >(_SC("SetStr"), &Sphere::Set) + // Utility Methods .Func(_SC("Clear"), &Sphere::Clear) - /* Operator Exposure */ - .Func(_SC("opAddAssign"), &Sphere::operator +=) - .Func(_SC("opSubAssign"), &Sphere::operator -=) - .Func(_SC("opMulAssign"), &Sphere::operator *=) - .Func(_SC("opDivAssign"), &Sphere::operator /=) - .Func(_SC("opModAssign"), &Sphere::operator %=) - - .Func(_SC("opAddAssignR"), &Sphere::operator +=) - .Func(_SC("opSubAssignR"), &Sphere::operator -=) - .Func(_SC("opMulAssignR"), &Sphere::operator *=) - .Func(_SC("opDivAssignR"), &Sphere::operator /=) - .Func(_SC("opModAssignR"), &Sphere::operator %=) - - .Func(_SC("opAddAssignP"), &Sphere::operator +=) - .Func(_SC("opSubAssignP"), &Sphere::operator -=) - .Func(_SC("opMulAssignP"), &Sphere::operator *=) - .Func(_SC("opDivAssignP"), &Sphere::operator /=) - .Func(_SC("opModAssignP"), &Sphere::operator %=) - - .Func(_SC("opPreInc"), &Sphere::operator ++) - .Func(_SC("opPreDec"), &Sphere::operator --) - .Func(_SC("opPostInc"), &Sphere::operator ++) - .Func(_SC("opPostDec"), &Sphere::operator --) - - .Func(_SC("opAdd"), &Sphere::operator +) - .Func(_SC("opSub"), &Sphere::operator -) - .Func(_SC("opMul"), &Sphere::operator *) - .Func(_SC("opDiv"), &Sphere::operator /) - .Func(_SC("opMod"), &Sphere::operator %) - - .Func(_SC("opAddR"), &Sphere::operator +) - .Func(_SC("opSubR"), &Sphere::operator -) - .Func(_SC("opMulR"), &Sphere::operator *) - .Func(_SC("opDivR"), &Sphere::operator /) - .Func(_SC("opModR"), &Sphere::operator %) - - .Func(_SC("opAddP"), &Sphere::operator +) - .Func(_SC("opSubP"), &Sphere::operator -) - .Func(_SC("opMulP"), &Sphere::operator *) - .Func(_SC("opDivP"), &Sphere::operator /) - .Func(_SC("opModP"), &Sphere::operator %) - - .Func(_SC("opUnPlus"), &Sphere::operator +) - .Func(_SC("opUnMinus"), &Sphere::operator -) - - .Func(_SC("opEqual"), &Sphere::operator ==) - .Func(_SC("opNotEqual"), &Sphere::operator !=) - .Func(_SC("opLessThan"), &Sphere::operator <) - .Func(_SC("opGreaterThan"), &Sphere::operator >) - .Func(_SC("opLessEqual"), &Sphere::operator <=) - .Func(_SC("opGreaterEqual"), &Sphere::operator >=) // Static Overloads - .StaticOverload< const Sphere & (*)(CSStr) >(_SC("FromStr"), &GetSphere) - .StaticOverload< const Sphere & (*)(CSStr, SQChar) >(_SC("FromStr"), &GetSphere) + .StaticOverload< const Sphere & (*)(CSStr) >(_SC("FromStr"), &Sphere::Get) + .StaticOverload< const Sphere & (*)(CSStr, SQChar) >(_SC("FromStr"), &Sphere::Get) + // Operator Exposure + .Func< Sphere & (Sphere::*)(const Sphere &) >(_SC("opAddAssign"), &Sphere::operator +=) + .Func< Sphere & (Sphere::*)(const Sphere &) >(_SC("opSubAssign"), &Sphere::operator -=) + .Func< Sphere & (Sphere::*)(const Sphere &) >(_SC("opMulAssign"), &Sphere::operator *=) + .Func< Sphere & (Sphere::*)(const Sphere &) >(_SC("opDivAssign"), &Sphere::operator /=) + .Func< Sphere & (Sphere::*)(const Sphere &) >(_SC("opModAssign"), &Sphere::operator %=) + + .Func< Sphere & (Sphere::*)(Sphere::Value) >(_SC("opAddAssignR"), &Sphere::operator +=) + .Func< Sphere & (Sphere::*)(Sphere::Value) >(_SC("opSubAssignR"), &Sphere::operator -=) + .Func< Sphere & (Sphere::*)(Sphere::Value) >(_SC("opMulAssignR"), &Sphere::operator *=) + .Func< Sphere & (Sphere::*)(Sphere::Value) >(_SC("opDivAssignR"), &Sphere::operator /=) + .Func< Sphere & (Sphere::*)(Sphere::Value) >(_SC("opModAssignR"), &Sphere::operator %=) + + .Func< Sphere & (Sphere::*)(const Vector3 &) >(_SC("opAddAssignP"), &Sphere::operator +=) + .Func< Sphere & (Sphere::*)(const Vector3 &) >(_SC("opSubAssignP"), &Sphere::operator -=) + .Func< Sphere & (Sphere::*)(const Vector3 &) >(_SC("opMulAssignP"), &Sphere::operator *=) + .Func< Sphere & (Sphere::*)(const Vector3 &) >(_SC("opDivAssignP"), &Sphere::operator /=) + .Func< Sphere & (Sphere::*)(const Vector3 &) >(_SC("opModAssignP"), &Sphere::operator %=) + + .Func< Sphere & (Sphere::*)(void) >(_SC("opPreInc"), &Sphere::operator ++) + .Func< Sphere & (Sphere::*)(void) >(_SC("opPreDec"), &Sphere::operator --) + .Func< Sphere (Sphere::*)(int) >(_SC("opPostInc"), &Sphere::operator ++) + .Func< Sphere (Sphere::*)(int) >(_SC("opPostDec"), &Sphere::operator --) + + .Func< Sphere (Sphere::*)(const Sphere &) const >(_SC("opAdd"), &Sphere::operator +) + .Func< Sphere (Sphere::*)(const Sphere &) const >(_SC("opSub"), &Sphere::operator -) + .Func< Sphere (Sphere::*)(const Sphere &) const >(_SC("opMul"), &Sphere::operator *) + .Func< Sphere (Sphere::*)(const Sphere &) const >(_SC("opDiv"), &Sphere::operator /) + .Func< Sphere (Sphere::*)(const Sphere &) const >(_SC("opMod"), &Sphere::operator %) + + .Func< Sphere (Sphere::*)(Sphere::Value) const >(_SC("opAddR"), &Sphere::operator +) + .Func< Sphere (Sphere::*)(Sphere::Value) const >(_SC("opSubR"), &Sphere::operator -) + .Func< Sphere (Sphere::*)(Sphere::Value) const >(_SC("opMulR"), &Sphere::operator *) + .Func< Sphere (Sphere::*)(Sphere::Value) const >(_SC("opDivR"), &Sphere::operator /) + .Func< Sphere (Sphere::*)(Sphere::Value) const >(_SC("opModR"), &Sphere::operator %) + + .Func< Sphere (Sphere::*)(const Vector3 &) const >(_SC("opAddP"), &Sphere::operator +) + .Func< Sphere (Sphere::*)(const Vector3 &) const >(_SC("opSubP"), &Sphere::operator -) + .Func< Sphere (Sphere::*)(const Vector3 &) const >(_SC("opMulP"), &Sphere::operator *) + .Func< Sphere (Sphere::*)(const Vector3 &) const >(_SC("opDivP"), &Sphere::operator /) + .Func< Sphere (Sphere::*)(const Vector3 &) const >(_SC("opModP"), &Sphere::operator %) + + .Func< Sphere (Sphere::*)(void) const >(_SC("opUnPlus"), &Sphere::operator +) + .Func< Sphere (Sphere::*)(void) const >(_SC("opUnMinus"), &Sphere::operator -) + + .Func< bool (Sphere::*)(const Sphere &) const >(_SC("opEqual"), &Sphere::operator ==) + .Func< bool (Sphere::*)(const Sphere &) const >(_SC("opNotEqual"), &Sphere::operator !=) + .Func< bool (Sphere::*)(const Sphere &) const >(_SC("opLessThan"), &Sphere::operator <) + .Func< bool (Sphere::*)(const Sphere &) const >(_SC("opGreaterThan"), &Sphere::operator >) + .Func< bool (Sphere::*)(const Sphere &) const >(_SC("opLessEqual"), &Sphere::operator <=) + .Func< bool (Sphere::*)(const Sphere &) const >(_SC("opGreaterEqual"), &Sphere::operator >=) ); } diff --git a/source/Base/Sphere.hpp b/source/Base/Sphere.hpp index b09c9637..76d38cad 100644 --- a/source/Base/Sphere.hpp +++ b/source/Base/Sphere.hpp @@ -8,16 +8,6 @@ // ------------------------------------------------------------------------------------------------ namespace SqMod { -/* ------------------------------------------------------------------------------------------------ - * Extract the values for components of the Sphere type from a string. -*/ -const Sphere & GetSphere(CSStr str); - -/* ------------------------------------------------------------------------------------------------ - * Extract the values for components of the Sphere type from a string. -*/ -const Sphere & GetSphere(CSStr str, SQChar delim); - /* ------------------------------------------------------------------------------------------------ * Class used to represent a three-dimensional sphere. */ @@ -393,6 +383,17 @@ struct Sphere * Retrieve a new instance of this type with absolute component values. */ Sphere Abs() const; + + /* -------------------------------------------------------------------------------------------- + * Extract the values for components of the Sphere type from a string. + */ + static const Sphere & Get(CSStr str); + + /* -------------------------------------------------------------------------------------------- + * Extract the values for components of the Sphere type from a string. + */ + static const Sphere & Get(CSStr str, SQChar delim); + }; } // Namespace:: SqMod diff --git a/source/Base/Vector2.cpp b/source/Base/Vector2.cpp index d0a02f8e..154c7080 100644 --- a/source/Base/Vector2.cpp +++ b/source/Base/Vector2.cpp @@ -21,7 +21,7 @@ SQChar Vector2::Delim = ','; // ------------------------------------------------------------------------------------------------ SQInteger Vector2::Typename(HSQUIRRELVM vm) { - static SQChar name[] = _SC("Vector2"); + static const SQChar name[] = _SC("Vector2"); sq_pushstring(vm, name, sizeof(name)); return 1; } @@ -57,14 +57,14 @@ Vector2 & Vector2::operator = (Value s) Vector2 & Vector2::operator = (CSStr values) { - Set(GetVector2(values, Delim)); + Set(Vector2::Get(values, Delim)); return *this; } Vector2 & Vector2::operator = (const Vector2i & v) { - x = static_cast(v.x); - y = static_cast(v.y); + x = ConvTo< Value >::From(v.x); + y = ConvTo< Value >::From(v.y); return *this; } @@ -99,8 +99,8 @@ Vector2 & Vector2::operator /= (const Vector2 & v) Vector2 & Vector2::operator %= (const Vector2 & v) { - x = fmod(x, v.x); - y = fmod(y, v.y); + x = std::fmod(x, v.x); + y = std::fmod(y, v.y); return *this; } @@ -135,8 +135,8 @@ Vector2 & Vector2::operator /= (Value s) Vector2 & Vector2::operator %= (Value s) { - x = fmod(x, s); - y = fmod(y, s); + x = std::fmod(x, s); + y = std::fmod(y, s); return *this; } @@ -195,7 +195,7 @@ Vector2 Vector2::operator / (const Vector2 & v) const Vector2 Vector2::operator % (const Vector2 & v) const { - return Vector2(fmod(x, v.x), fmod(y, v.y)); + return Vector2(std::fmod(x, v.x), std::fmod(y, v.y)); } // ------------------------------------------------------------------------------------------------ @@ -221,13 +221,13 @@ Vector2 Vector2::operator / (Value s) const Vector2 Vector2::operator % (Value s) const { - return Vector2(fmod(x, s), fmod(y, s)); + return Vector2(std::fmod(x, s), std::fmod(y, s)); } // ------------------------------------------------------------------------------------------------ Vector2 Vector2::operator + () const { - return Vector2(fabs(x), fabs(y)); + return Vector2(std::fabs(x), std::fabs(y)); } Vector2 Vector2::operator - () const @@ -270,11 +270,17 @@ bool Vector2::operator >= (const Vector2 & v) const Int32 Vector2::Cmp(const Vector2 & o) const { if (*this == o) + { return 0; + } else if (*this > o) + { return 1; + } else + { return -1; + } } // ------------------------------------------------------------------------------------------------ @@ -305,14 +311,14 @@ void Vector2::Set(const Vector2 & v) void Vector2::Set(const Vector2i & v) { - x = static_cast(v.x); - y = static_cast(v.y); + x = ConvTo< Value >::From(v.x); + y = ConvTo< Value >::From(v.y); } // ------------------------------------------------------------------------------------------------ void Vector2::Set(CSStr values, SQChar delim) { - Set(GetVector2(values, delim)); + Set(Vector2::Get(values, delim)); } // ------------------------------------------------------------------------------------------------ @@ -325,7 +331,9 @@ void Vector2::Generate() void Vector2::Generate(Value min, Value max) { if (EpsLt(max, min)) + { STHROWF("max value is lower than min value"); + } x = GetRandomFloat32(min, max); y = GetRandomFloat32(min, max); @@ -334,7 +342,9 @@ void Vector2::Generate(Value min, Value max) void Vector2::Generate(Value xmin, Value xmax, Value ymin, Value ymax) { if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin)) + { STHROWF("max value is lower than min value"); + } x = GetRandomFloat32(ymin, ymax); y = GetRandomFloat32(xmin, xmax); @@ -343,17 +353,17 @@ void Vector2::Generate(Value xmin, Value xmax, Value ymin, Value ymax) // ------------------------------------------------------------------------------------------------ Vector2 Vector2::Abs() const { - return Vector2(fabs(x), fabs(y)); + return Vector2(std::fabs(x), std::fabs(y)); } // ------------------------------------------------------------------------------------------------ -const Vector2 & GetVector2(CSStr str) +const Vector2 & Vector2::Get(CSStr str) { - return GetVector2(str, Vector2::Delim); + return Vector2::Get(str, Vector2::Delim); } // ------------------------------------------------------------------------------------------------ -const Vector2 & GetVector2(CSStr str, SQChar delim) +const Vector2 & Vector2::Get(CSStr str, SQChar delim) { // The format specifications that will be used to scan the string static SQChar fs[] = _SC(" %f , %f "); @@ -368,93 +378,122 @@ const Vector2 & GetVector2(CSStr str, SQChar delim) // Assign the specified delimiter fs[4] = delim; // Attempt to extract the component values from the specified string - sscanf(str, fs, &vec.x, &vec.y); + std::sscanf(str, fs, &vec.x, &vec.y); // Return the resulted value return vec; } +// ------------------------------------------------------------------------------------------------ +const Vector2 & GetVector2() +{ + static Vector2 vec; + vec.Clear(); + return vec; +} + +const Vector2 & GetVector2(Float32 sv) +{ + static Vector2 vec; + vec.Set(sv); + return vec; +} + +const Vector2 & GetVector2(Float32 xv, Float32 yv) +{ + static Vector2 vec; + vec.Set(xv, yv); + return vec; +} + +const Vector2 & GetVector2(const Vector2 & o) +{ + static Vector2 vec; + vec.Set(o); + return vec; +} + // ================================================================================================ void Register_Vector2(HSQUIRRELVM vm) { typedef Vector2::Value Val; RootTable(vm).Bind(_SC("Vector2"), Class< Vector2 >(vm, _SC("Vector2")) - /* Constructors */ + // Constructors .Ctor() .Ctor< Val >() .Ctor< Val, Val >() - /* Static Members */ + // Static Members .SetStaticValue(_SC("Delim"), &Vector2::Delim) - /* Member Variables */ - .Var(_SC("x"), &Vector2::x) - .Var(_SC("y"), &Vector2::y) - /* Properties */ - .Prop(_SC("abs"), &Vector2::Abs) - /* Core Metamethods */ + // Member Variables + .Var(_SC("X"), &Vector2::x) + .Var(_SC("Y"), &Vector2::y) + // Properties + .Prop(_SC("Abs"), &Vector2::Abs) + // Core Metamethods .Func(_SC("_tostring"), &Vector2::ToString) .SquirrelFunc(_SC("_typename"), &Vector2::Typename) .Func(_SC("_cmp"), &Vector2::Cmp) - /* Metamethods */ - .Func(_SC("_add"), &Vector2::operator +) - .Func(_SC("_sub"), &Vector2::operator -) - .Func(_SC("_mul"), &Vector2::operator *) - .Func(_SC("_div"), &Vector2::operator /) - .Func(_SC("_modulo"), &Vector2::operator %) - .Func(_SC("_unm"), &Vector2::operator -) - /* Setters */ - .Overload(_SC("Set"), &Vector2::Set) - .Overload(_SC("Set"), &Vector2::Set) - .Overload(_SC("SetVec2"), &Vector2::Set) - .Overload(_SC("SetVec2i"), &Vector2::Set) - .Overload(_SC("SetStr"), &Vector2::Set) - /* Random Generators */ - .Overload(_SC("Generate"), &Vector2::Generate) - .Overload(_SC("Generate"), &Vector2::Generate) - .Overload(_SC("Generate"), &Vector2::Generate) - /* Utility Methods */ + // Metamethods + .Func< Vector2 (Vector2::*)(const Vector2 &) const >(_SC("_add"), &Vector2::operator +) + .Func< Vector2 (Vector2::*)(const Vector2 &) const >(_SC("_sub"), &Vector2::operator -) + .Func< Vector2 (Vector2::*)(const Vector2 &) const >(_SC("_mul"), &Vector2::operator *) + .Func< Vector2 (Vector2::*)(const Vector2 &) const >(_SC("_div"), &Vector2::operator /) + .Func< Vector2 (Vector2::*)(const Vector2 &) const >(_SC("_modulo"), &Vector2::operator %) + .Func< Vector2 (Vector2::*)(void) const >(_SC("_unm"), &Vector2::operator -) + // Setters + .Overload< void (Vector2::*)(Val) >(_SC("Set"), &Vector2::Set) + .Overload< void (Vector2::*)(Val, Val) >(_SC("Set"), &Vector2::Set) + .Overload< void (Vector2::*)(const Vector2 &) >(_SC("SetVec2"), &Vector2::Set) + .Overload< void (Vector2::*)(const Vector2i &) >(_SC("SetVec2i"), &Vector2::Set) + .Overload< void (Vector2::*)(CSStr, SQChar) >(_SC("SetStr"), &Vector2::Set) + // Random Generators + .Overload< void (Vector2::*)(void) >(_SC("Generate"), &Vector2::Generate) + .Overload< void (Vector2::*)(Val, Val) >(_SC("Generate"), &Vector2::Generate) + .Overload< void (Vector2::*)(Val, Val, Val, Val) >(_SC("Generate"), &Vector2::Generate) + // Utility Methods .Func(_SC("Clear"), &Vector2::Clear) - /* Operator Exposure */ - .Func(_SC("opAddAssign"), &Vector2::operator +=) - .Func(_SC("opSubAssign"), &Vector2::operator -=) - .Func(_SC("opMulAssign"), &Vector2::operator *=) - .Func(_SC("opDivAssign"), &Vector2::operator /=) - .Func(_SC("opModAssign"), &Vector2::operator %=) - - .Func(_SC("opAddAssignS"), &Vector2::operator +=) - .Func(_SC("opSubAssignS"), &Vector2::operator -=) - .Func(_SC("opMulAssignS"), &Vector2::operator *=) - .Func(_SC("opDivAssignS"), &Vector2::operator /=) - .Func(_SC("opModAssignS"), &Vector2::operator %=) - - .Func(_SC("opPreInc"), &Vector2::operator ++) - .Func(_SC("opPreDec"), &Vector2::operator --) - .Func(_SC("opPostInc"), &Vector2::operator ++) - .Func(_SC("opPostDec"), &Vector2::operator --) - - .Func(_SC("opAdd"), &Vector2::operator +) - .Func(_SC("opSub"), &Vector2::operator -) - .Func(_SC("opMul"), &Vector2::operator *) - .Func(_SC("opDiv"), &Vector2::operator /) - .Func(_SC("opMod"), &Vector2::operator %) - - .Func(_SC("opAddS"), &Vector2::operator +) - .Func(_SC("opSubS"), &Vector2::operator -) - .Func(_SC("opMulS"), &Vector2::operator *) - .Func(_SC("opDivS"), &Vector2::operator /) - .Func(_SC("opModS"), &Vector2::operator %) - - .Func(_SC("opUnPlus"), &Vector2::operator +) - .Func(_SC("opUnMinus"), &Vector2::operator -) - - .Func(_SC("opEqual"), &Vector2::operator ==) - .Func(_SC("opNotEqual"), &Vector2::operator !=) - .Func(_SC("opLessThan"), &Vector2::operator <) - .Func(_SC("opGreaterThan"), &Vector2::operator >) - .Func(_SC("opLessEqual"), &Vector2::operator <=) - .Func(_SC("opGreaterEqual"), &Vector2::operator >=) // Static Overloads - .StaticOverload< const Vector2 & (*)(CSStr) >(_SC("FromStr"), &GetVector2) - .StaticOverload< const Vector2 & (*)(CSStr, SQChar) >(_SC("FromStr"), &GetVector2) + .StaticOverload< const Vector2 & (*)(CSStr) >(_SC("FromStr"), &Vector2::Get) + .StaticOverload< const Vector2 & (*)(CSStr, SQChar) >(_SC("FromStr"), &Vector2::Get) + // Operator Exposure + .Func< Vector2 & (Vector2::*)(const Vector2 &) >(_SC("opAddAssign"), &Vector2::operator +=) + .Func< Vector2 & (Vector2::*)(const Vector2 &) >(_SC("opSubAssign"), &Vector2::operator -=) + .Func< Vector2 & (Vector2::*)(const Vector2 &) >(_SC("opMulAssign"), &Vector2::operator *=) + .Func< Vector2 & (Vector2::*)(const Vector2 &) >(_SC("opDivAssign"), &Vector2::operator /=) + .Func< Vector2 & (Vector2::*)(const Vector2 &) >(_SC("opModAssign"), &Vector2::operator %=) + + .Func< Vector2 & (Vector2::*)(Vector2::Value) >(_SC("opAddAssignS"), &Vector2::operator +=) + .Func< Vector2 & (Vector2::*)(Vector2::Value) >(_SC("opSubAssignS"), &Vector2::operator -=) + .Func< Vector2 & (Vector2::*)(Vector2::Value) >(_SC("opMulAssignS"), &Vector2::operator *=) + .Func< Vector2 & (Vector2::*)(Vector2::Value) >(_SC("opDivAssignS"), &Vector2::operator /=) + .Func< Vector2 & (Vector2::*)(Vector2::Value) >(_SC("opModAssignS"), &Vector2::operator %=) + + .Func< Vector2 & (Vector2::*)(void) >(_SC("opPreInc"), &Vector2::operator ++) + .Func< Vector2 & (Vector2::*)(void) >(_SC("opPreDec"), &Vector2::operator --) + .Func< Vector2 (Vector2::*)(int) >(_SC("opPostInc"), &Vector2::operator ++) + .Func< Vector2 (Vector2::*)(int) >(_SC("opPostDec"), &Vector2::operator --) + + .Func< Vector2 (Vector2::*)(const Vector2 &) const >(_SC("opAdd"), &Vector2::operator +) + .Func< Vector2 (Vector2::*)(const Vector2 &) const >(_SC("opSub"), &Vector2::operator -) + .Func< Vector2 (Vector2::*)(const Vector2 &) const >(_SC("opMul"), &Vector2::operator *) + .Func< Vector2 (Vector2::*)(const Vector2 &) const >(_SC("opDiv"), &Vector2::operator /) + .Func< Vector2 (Vector2::*)(const Vector2 &) const >(_SC("opMod"), &Vector2::operator %) + + .Func< Vector2 (Vector2::*)(Vector2::Value) const >(_SC("opAddS"), &Vector2::operator +) + .Func< Vector2 (Vector2::*)(Vector2::Value) const >(_SC("opSubS"), &Vector2::operator -) + .Func< Vector2 (Vector2::*)(Vector2::Value) const >(_SC("opMulS"), &Vector2::operator *) + .Func< Vector2 (Vector2::*)(Vector2::Value) const >(_SC("opDivS"), &Vector2::operator /) + .Func< Vector2 (Vector2::*)(Vector2::Value) const >(_SC("opModS"), &Vector2::operator %) + + .Func< Vector2 (Vector2::*)(void) const >(_SC("opUnPlus"), &Vector2::operator +) + .Func< Vector2 (Vector2::*)(void) const >(_SC("opUnMinus"), &Vector2::operator -) + + .Func< bool (Vector2::*)(const Vector2 &) const >(_SC("opEqual"), &Vector2::operator ==) + .Func< bool (Vector2::*)(const Vector2 &) const >(_SC("opNotEqual"), &Vector2::operator !=) + .Func< bool (Vector2::*)(const Vector2 &) const >(_SC("opLessThan"), &Vector2::operator <) + .Func< bool (Vector2::*)(const Vector2 &) const >(_SC("opGreaterThan"), &Vector2::operator >) + .Func< bool (Vector2::*)(const Vector2 &) const >(_SC("opLessEqual"), &Vector2::operator <=) + .Func< bool (Vector2::*)(const Vector2 &) const >(_SC("opGreaterEqual"), &Vector2::operator >=) ); } diff --git a/source/Base/Vector2.hpp b/source/Base/Vector2.hpp index 244f604c..5e82c8b0 100644 --- a/source/Base/Vector2.hpp +++ b/source/Base/Vector2.hpp @@ -7,16 +7,6 @@ // ------------------------------------------------------------------------------------------------ namespace SqMod { -/* ------------------------------------------------------------------------------------------------ - * Extract the values for components of the Vector2 type from a string. -*/ -const Vector2 & GetVector2(CSStr str); - -/* ------------------------------------------------------------------------------------------------ - * Extract the values for components of the Vector2 type from a string. -*/ -const Vector2 & GetVector2(CSStr str, SQChar delim); - /* ------------------------------------------------------------------------------------------------ * Class used to represent a two-dimensional vector. */ @@ -326,6 +316,17 @@ struct Vector2 * Retrieve a new instance of this type with absolute component values. */ Vector2 Abs() const; + + /* -------------------------------------------------------------------------------------------- + * Extract the values for components of the Vector2 type from a string. + */ + static const Vector2 & Get(CSStr str); + + /* -------------------------------------------------------------------------------------------- + * Extract the values for components of the Vector2 type from a string. + */ + static const Vector2 & Get(CSStr str, SQChar delim); + }; } // Namespace:: SqMod diff --git a/source/Base/Vector2i.cpp b/source/Base/Vector2i.cpp index 712dbfbd..89c63949 100644 --- a/source/Base/Vector2i.cpp +++ b/source/Base/Vector2i.cpp @@ -21,7 +21,7 @@ SQChar Vector2i::Delim = ','; // ------------------------------------------------------------------------------------------------ SQInteger Vector2i::Typename(HSQUIRRELVM vm) { - static SQChar name[] = _SC("Vector2i"); + static const SQChar name[] = _SC("Vector2i"); sq_pushstring(vm, name, sizeof(name)); return 1; } @@ -57,14 +57,14 @@ Vector2i & Vector2i::operator = (Value s) Vector2i & Vector2i::operator = (CSStr values) { - Set(GetVector2i(values, Delim)); + Set(Vector2i::Get(values, Delim)); return *this; } Vector2i & Vector2i::operator = (const Vector2 & v) { - x = Value(v.x); - y = Value(v.y); + x = ConvTo< Value >::From(v.x); + y = ConvTo< Value >::From(v.y); return *this; } @@ -347,7 +347,7 @@ Vector2i Vector2i::operator >> (Value s) const // ------------------------------------------------------------------------------------------------ Vector2i Vector2i::operator + () const { - return Vector2i(abs(x), abs(y)); + return Vector2i(std::abs(x), std::abs(y)); } Vector2i Vector2i::operator - () const @@ -396,11 +396,17 @@ bool Vector2i::operator >= (const Vector2i & v) const Int32 Vector2i::Cmp(const Vector2i & o) const { if (*this == o) + { return 0; + } else if (*this > o) + { return 1; + } else + { return -1; + } } // ------------------------------------------------------------------------------------------------ @@ -431,14 +437,14 @@ void Vector2i::Set(const Vector2i & v) void Vector2i::Set(const Vector2 & v) { - x = Value(v.x); - y = Value(v.y); + x = ConvTo< Value >::From(v.x); + y = ConvTo< Value >::From(v.y); } // ------------------------------------------------------------------------------------------------ void Vector2i::Set(CSStr values, SQChar delim) { - Set(GetVector2i(values, delim)); + Set(Vector2i::Get(values, delim)); } // ------------------------------------------------------------------------------------------------ @@ -451,7 +457,9 @@ void Vector2i::Generate() void Vector2i::Generate(Value min, Value max) { if (max < min) + { STHROWF("max value is lower than min value"); + } x = GetRandomInt32(min, max); y = GetRandomInt32(min, max); @@ -460,7 +468,9 @@ void Vector2i::Generate(Value min, Value max) void Vector2i::Generate(Value xmin, Value xmax, Value ymin, Value ymax) { if (xmax < xmin || ymax < ymin) + { STHROWF("max value is lower than min value"); + } x = GetRandomInt32(ymin, ymax); y = GetRandomInt32(xmin, xmax); @@ -469,17 +479,17 @@ void Vector2i::Generate(Value xmin, Value xmax, Value ymin, Value ymax) // ------------------------------------------------------------------------------------------------ Vector2i Vector2i::Abs() const { - return Vector2i(abs(x), abs(y)); + return Vector2i(std::abs(x), std::abs(y)); } // ------------------------------------------------------------------------------------------------ -const Vector2i & GetVector2i(CSStr str) +const Vector2i & Vector2i::Get(CSStr str) { - return GetVector2i(str, Vector2i::Delim); + return Vector2i::Get(str, Vector2i::Delim); } // ------------------------------------------------------------------------------------------------ -const Vector2i & GetVector2i(CSStr str, SQChar delim) +const Vector2i & Vector2i::Get(CSStr str, SQChar delim) { // The format specifications that will be used to scan the string static SQChar fs[] = _SC(" %d , %d "); @@ -494,114 +504,143 @@ const Vector2i & GetVector2i(CSStr str, SQChar delim) // Assign the specified delimiter fs[4] = delim; // Attempt to extract the component values from the specified string - sscanf(str, &fs[0], &vec.x, &vec.y); + std::sscanf(str, &fs[0], &vec.x, &vec.y); // Return the resulted value return vec; } +// ------------------------------------------------------------------------------------------------ +const Vector2i & GetVector2i() +{ + static Vector2i vec; + vec.Clear(); + return vec; +} + +const Vector2i & GetVector2i(Int32 sv) +{ + static Vector2i vec; + vec.Set(sv); + return vec; +} + +const Vector2i & GetVector2i(Int32 xv, Int32 yv) +{ + static Vector2i vec; + vec.Set(xv, yv); + return vec; +} + +const Vector2i & GetVector2i(const Vector2i & o) +{ + static Vector2i vec; + vec.Set(o); + return vec; +} + // ================================================================================================ void Register_Vector2i(HSQUIRRELVM vm) { typedef Vector2i::Value Val; RootTable(vm).Bind(_SC("Vector2i"), Class< Vector2i >(vm, _SC("Vector2i")) - /* Constructors */ + // Constructors .Ctor() .Ctor< Val >() .Ctor< Val, Val >() - /* Static Members */ + // Static Members .SetStaticValue(_SC("Delim"), &Vector2i::Delim) - /* Member Variables */ - .Var(_SC("x"), &Vector2i::x) - .Var(_SC("y"), &Vector2i::y) - /* Properties */ - .Prop(_SC("abs"), &Vector2i::Abs) - /* Core Metamethods */ + // Member Variables + .Var(_SC("X"), &Vector2i::x) + .Var(_SC("Y"), &Vector2i::y) + // Properties + .Prop(_SC("Abs"), &Vector2i::Abs) + // Core Metamethods .Func(_SC("_tostring"), &Vector2i::ToString) .SquirrelFunc(_SC("_typename"), &Vector2i::Typename) .Func(_SC("_cmp"), &Vector2i::Cmp) - /* Metamethods */ - .Func(_SC("_add"), &Vector2i::operator +) - .Func(_SC("_sub"), &Vector2i::operator -) - .Func(_SC("_mul"), &Vector2i::operator *) - .Func(_SC("_div"), &Vector2i::operator /) - .Func(_SC("_modulo"), &Vector2i::operator %) - .Func(_SC("_unm"), &Vector2i::operator -) - /* Setters */ - .Overload(_SC("Set"), &Vector2i::Set) - .Overload(_SC("Set"), &Vector2i::Set) - .Overload(_SC("SetVec2i"), &Vector2i::Set) - .Overload(_SC("SetVec2"), &Vector2i::Set) - .Overload(_SC("SetStr"), &Vector2i::Set) - /* Random Generators */ - .Overload(_SC("Generate"), &Vector2i::Generate) - .Overload(_SC("Generate"), &Vector2i::Generate) - .Overload(_SC("Generate"), &Vector2i::Generate) - /* Utility Methods */ + // Metamethods + .Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("_add"), &Vector2i::operator +) + .Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("_sub"), &Vector2i::operator -) + .Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("_mul"), &Vector2i::operator *) + .Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("_div"), &Vector2i::operator /) + .Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("_modulo"), &Vector2i::operator %) + .Func< Vector2i (Vector2i::*)(void) const >(_SC("_unm"), &Vector2i::operator -) + // Setters + .Overload< void (Vector2i::*)(Val) >(_SC("Set"), &Vector2i::Set) + .Overload< void (Vector2i::*)(Val, Val) >(_SC("Set"), &Vector2i::Set) + .Overload< void (Vector2i::*)(const Vector2i &) >(_SC("SetVec2i"), &Vector2i::Set) + .Overload< void (Vector2i::*)(const Vector2 &) >(_SC("SetVec2"), &Vector2i::Set) + .Overload< void (Vector2i::*)(CSStr, SQChar) >(_SC("SetStr"), &Vector2i::Set) + // Random Generators + .Overload< void (Vector2i::*)(void) >(_SC("Generate"), &Vector2i::Generate) + .Overload< void (Vector2i::*)(Val, Val) >(_SC("Generate"), &Vector2i::Generate) + .Overload< void (Vector2i::*)(Val, Val, Val, Val) >(_SC("Generate"), &Vector2i::Generate) + // Utility Methods .Func(_SC("Clear"), &Vector2i::Clear) - /* Operator Exposure */ - .Func(_SC("opAddAssign"), &Vector2i::operator +=) - .Func(_SC("opSubAssign"), &Vector2i::operator -=) - .Func(_SC("opMulAssign"), &Vector2i::operator *=) - .Func(_SC("opDivAssign"), &Vector2i::operator /=) - .Func(_SC("opModAssign"), &Vector2i::operator %=) - .Func(_SC("opAndAssign"), &Vector2i::operator &=) - .Func(_SC("opOrAssign"), &Vector2i::operator |=) - .Func(_SC("opXorAssign"), &Vector2i::operator ^=) - .Func(_SC("opShlAssign"), &Vector2i::operator <<=) - .Func(_SC("opShrAssign"), &Vector2i::operator >>=) - - .Func(_SC("opAddAssignS"), &Vector2i::operator +=) - .Func(_SC("opSubAssignS"), &Vector2i::operator -=) - .Func(_SC("opMulAssignS"), &Vector2i::operator *=) - .Func(_SC("opDivAssignS"), &Vector2i::operator /=) - .Func(_SC("opModAssignS"), &Vector2i::operator %=) - .Func(_SC("opAndAssignS"), &Vector2i::operator &=) - .Func(_SC("opOrAssignS"), &Vector2i::operator |=) - .Func(_SC("opXorAssignS"), &Vector2i::operator ^=) - .Func(_SC("opShlAssignS"), &Vector2i::operator <<=) - .Func(_SC("opShrAssignS"), &Vector2i::operator >>=) - - .Func(_SC("opPreInc"), &Vector2i::operator ++) - .Func(_SC("opPreDec"), &Vector2i::operator --) - .Func(_SC("opPostInc"), &Vector2i::operator ++) - .Func(_SC("opPostDec"), &Vector2i::operator --) - - .Func(_SC("opAdd"), &Vector2i::operator +) - .Func(_SC("opSub"), &Vector2i::operator -) - .Func(_SC("opMul"), &Vector2i::operator *) - .Func(_SC("opDiv"), &Vector2i::operator /) - .Func(_SC("opMod"), &Vector2i::operator %) - .Func(_SC("opAnd"), &Vector2i::operator &) - .Func(_SC("opOr"), &Vector2i::operator |) - .Func(_SC("opShl"), &Vector2i::operator ^) - .Func(_SC("opShl"), &Vector2i::operator <<) - .Func(_SC("opShr"), &Vector2i::operator >>) - - .Func(_SC("opAddS"), &Vector2i::operator +) - .Func(_SC("opSubS"), &Vector2i::operator -) - .Func(_SC("opMulS"), &Vector2i::operator *) - .Func(_SC("opDivS"), &Vector2i::operator /) - .Func(_SC("opModS"), &Vector2i::operator %) - .Func(_SC("opAndS"), &Vector2i::operator &) - .Func(_SC("opOrS"), &Vector2i::operator |) - .Func(_SC("opShlS"), &Vector2i::operator ^) - .Func(_SC("opShlS"), &Vector2i::operator <<) - .Func(_SC("opShrS"), &Vector2i::operator >>) - - .Func(_SC("opUnPlus"), &Vector2i::operator +) - .Func(_SC("opUnMinus"), &Vector2i::operator -) - .Func(_SC("opCom"), &Vector2i::operator ~) - - .Func(_SC("opEqual"), &Vector2i::operator ==) - .Func(_SC("opNotEqual"), &Vector2i::operator !=) - .Func(_SC("opLessThan"), &Vector2i::operator <) - .Func(_SC("opGreaterThan"), &Vector2i::operator >) - .Func(_SC("opLessEqual"), &Vector2i::operator <=) - .Func(_SC("opGreaterEqual"), &Vector2i::operator >=) // Static Overloads - .StaticOverload< const Vector2i & (*)(CSStr) >(_SC("FromStr"), &GetVector2i) - .StaticOverload< const Vector2i & (*)(CSStr, SQChar) >(_SC("FromStr"), &GetVector2i) + .StaticOverload< const Vector2i & (*)(CSStr) >(_SC("FromStr"), &Vector2i::Get) + .StaticOverload< const Vector2i & (*)(CSStr, SQChar) >(_SC("FromStr"), &Vector2i::Get) + // Operator Exposure + .Func< Vector2i & (Vector2i::*)(const Vector2i &) >(_SC("opAddAssign"), &Vector2i::operator +=) + .Func< Vector2i & (Vector2i::*)(const Vector2i &) >(_SC("opSubAssign"), &Vector2i::operator -=) + .Func< Vector2i & (Vector2i::*)(const Vector2i &) >(_SC("opMulAssign"), &Vector2i::operator *=) + .Func< Vector2i & (Vector2i::*)(const Vector2i &) >(_SC("opDivAssign"), &Vector2i::operator /=) + .Func< Vector2i & (Vector2i::*)(const Vector2i &) >(_SC("opModAssign"), &Vector2i::operator %=) + .Func< Vector2i & (Vector2i::*)(const Vector2i &) >(_SC("opAndAssign"), &Vector2i::operator &=) + .Func< Vector2i & (Vector2i::*)(const Vector2i &) >(_SC("opOrAssign"), &Vector2i::operator |=) + .Func< Vector2i & (Vector2i::*)(const Vector2i &) >(_SC("opXorAssign"), &Vector2i::operator ^=) + .Func< Vector2i & (Vector2i::*)(const Vector2i &) >(_SC("opShlAssign"), &Vector2i::operator <<=) + .Func< Vector2i & (Vector2i::*)(const Vector2i &) >(_SC("opShrAssign"), &Vector2i::operator >>=) + + .Func< Vector2i & (Vector2i::*)(Vector2i::Value) >(_SC("opAddAssignS"), &Vector2i::operator +=) + .Func< Vector2i & (Vector2i::*)(Vector2i::Value) >(_SC("opSubAssignS"), &Vector2i::operator -=) + .Func< Vector2i & (Vector2i::*)(Vector2i::Value) >(_SC("opMulAssignS"), &Vector2i::operator *=) + .Func< Vector2i & (Vector2i::*)(Vector2i::Value) >(_SC("opDivAssignS"), &Vector2i::operator /=) + .Func< Vector2i & (Vector2i::*)(Vector2i::Value) >(_SC("opModAssignS"), &Vector2i::operator %=) + .Func< Vector2i & (Vector2i::*)(Vector2i::Value) >(_SC("opAndAssignS"), &Vector2i::operator &=) + .Func< Vector2i & (Vector2i::*)(Vector2i::Value) >(_SC("opOrAssignS"), &Vector2i::operator |=) + .Func< Vector2i & (Vector2i::*)(Vector2i::Value) >(_SC("opXorAssignS"), &Vector2i::operator ^=) + .Func< Vector2i & (Vector2i::*)(Vector2i::Value) >(_SC("opShlAssignS"), &Vector2i::operator <<=) + .Func< Vector2i & (Vector2i::*)(Vector2i::Value) >(_SC("opShrAssignS"), &Vector2i::operator >>=) + + .Func< Vector2i & (Vector2i::*)(void) >(_SC("opPreInc"), &Vector2i::operator ++) + .Func< Vector2i & (Vector2i::*)(void) >(_SC("opPreDec"), &Vector2i::operator --) + .Func< Vector2i (Vector2i::*)(int) >(_SC("opPostInc"), &Vector2i::operator ++) + .Func< Vector2i (Vector2i::*)(int) >(_SC("opPostDec"), &Vector2i::operator --) + + .Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("opAdd"), &Vector2i::operator +) + .Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("opSub"), &Vector2i::operator -) + .Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("opMul"), &Vector2i::operator *) + .Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("opDiv"), &Vector2i::operator /) + .Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("opMod"), &Vector2i::operator %) + .Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("opAnd"), &Vector2i::operator &) + .Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("opOr"), &Vector2i::operator |) + .Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("opShl"), &Vector2i::operator ^) + .Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("opShl"), &Vector2i::operator <<) + .Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("opShr"), &Vector2i::operator >>) + + .Func< Vector2i (Vector2i::*)(Vector2i::Value) const >(_SC("opAddS"), &Vector2i::operator +) + .Func< Vector2i (Vector2i::*)(Vector2i::Value) const >(_SC("opSubS"), &Vector2i::operator -) + .Func< Vector2i (Vector2i::*)(Vector2i::Value) const >(_SC("opMulS"), &Vector2i::operator *) + .Func< Vector2i (Vector2i::*)(Vector2i::Value) const >(_SC("opDivS"), &Vector2i::operator /) + .Func< Vector2i (Vector2i::*)(Vector2i::Value) const >(_SC("opModS"), &Vector2i::operator %) + .Func< Vector2i (Vector2i::*)(Vector2i::Value) const >(_SC("opAndS"), &Vector2i::operator &) + .Func< Vector2i (Vector2i::*)(Vector2i::Value) const >(_SC("opOrS"), &Vector2i::operator |) + .Func< Vector2i (Vector2i::*)(Vector2i::Value) const >(_SC("opShlS"), &Vector2i::operator ^) + .Func< Vector2i (Vector2i::*)(Vector2i::Value) const >(_SC("opShlS"), &Vector2i::operator <<) + .Func< Vector2i (Vector2i::*)(Vector2i::Value) const >(_SC("opShrS"), &Vector2i::operator >>) + + .Func< Vector2i (Vector2i::*)(void) const >(_SC("opUnPlus"), &Vector2i::operator +) + .Func< Vector2i (Vector2i::*)(void) const >(_SC("opUnMinus"), &Vector2i::operator -) + .Func< Vector2i (Vector2i::*)(void) const >(_SC("opCom"), &Vector2i::operator ~) + + .Func< bool (Vector2i::*)(const Vector2i &) const >(_SC("opEqual"), &Vector2i::operator ==) + .Func< bool (Vector2i::*)(const Vector2i &) const >(_SC("opNotEqual"), &Vector2i::operator !=) + .Func< bool (Vector2i::*)(const Vector2i &) const >(_SC("opLessThan"), &Vector2i::operator <) + .Func< bool (Vector2i::*)(const Vector2i &) const >(_SC("opGreaterThan"), &Vector2i::operator >) + .Func< bool (Vector2i::*)(const Vector2i &) const >(_SC("opLessEqual"), &Vector2i::operator <=) + .Func< bool (Vector2i::*)(const Vector2i &) const >(_SC("opGreaterEqual"), &Vector2i::operator >=) ); } diff --git a/source/Base/Vector2i.hpp b/source/Base/Vector2i.hpp index 123af191..a91a35ad 100644 --- a/source/Base/Vector2i.hpp +++ b/source/Base/Vector2i.hpp @@ -7,16 +7,6 @@ // ------------------------------------------------------------------------------------------------ namespace SqMod { -/* ------------------------------------------------------------------------------------------------ - * Extract the values for components of the Vector2i type from a string. -*/ -const Vector2i & GetVector2i(CSStr str); - -/* ------------------------------------------------------------------------------------------------ - * Extract the values for components of the Vector2i type from a string. -*/ -const Vector2i & GetVector2i(CSStr str, SQChar delim); - /* ------------------------------------------------------------------------------------------------ * Class used to represent a two-dimensional vector using integral values. */ @@ -431,6 +421,17 @@ struct Vector2i * Retrieve a new instance of this type with absolute component values. */ Vector2i Abs() const; + + /* -------------------------------------------------------------------------------------------- + * Extract the values for components of the Vector2i type from a string. + */ + static const Vector2i & Get(CSStr str); + + /* -------------------------------------------------------------------------------------------- + * Extract the values for components of the Vector2i type from a string. + */ + static const Vector2i & Get(CSStr str, SQChar delim); + }; } // Namespace:: SqMod diff --git a/source/Base/Vector3.cpp b/source/Base/Vector3.cpp index 19bb0208..6c782c08 100644 --- a/source/Base/Vector3.cpp +++ b/source/Base/Vector3.cpp @@ -22,7 +22,7 @@ SQChar Vector3::Delim = ','; // ------------------------------------------------------------------------------------------------ SQInteger Vector3::Typename(HSQUIRRELVM vm) { - static SQChar name[] = _SC("Vector3"); + static const SQChar name[] = _SC("Vector3"); sq_pushstring(vm, name, sizeof(name)); return 1; } @@ -108,9 +108,9 @@ Vector3 & Vector3::operator /= (const Vector3 & v) Vector3 & Vector3::operator %= (const Vector3 & v) { - x = fmod(x, v.x); - y = fmod(y, v.y); - z = fmod(z, v.z); + x = std::fmod(x, v.x); + y = std::fmod(y, v.y); + z = std::fmod(z, v.z); return *this; } @@ -149,9 +149,9 @@ Vector3 & Vector3::operator /= (Value s) Vector3 & Vector3::operator %= (Value s) { - x = fmod(x, s); - y = fmod(y, s); - z = fmod(z, s); + x = std::fmod(x, s); + y = std::fmod(y, s); + z = std::fmod(z, s); return *this; } @@ -214,7 +214,7 @@ Vector3 Vector3::operator / (const Vector3 & v) const Vector3 Vector3::operator % (const Vector3 & v) const { - return Vector3(fmod(x, v.x), fmod(y, v.y), fmod(z, v.z)); + return Vector3(std::fmod(x, v.x), std::fmod(y, v.y), std::fmod(z, v.z)); } // ------------------------------------------------------------------------------------------------ @@ -240,13 +240,13 @@ Vector3 Vector3::operator / (Value s) const Vector3 Vector3::operator % (Value s) const { - return Vector3(fmod(x, s), fmod(y, s), fmod(z, s)); + return Vector3(std::fmod(x, s), std::fmod(y, s), std::fmod(z, s)); } // ------------------------------------------------------------------------------------------------ Vector3 Vector3::operator + () const { - return Vector3(fabs(x), fabs(y), fabs(z)); + return Vector3(std::fabs(x), std::fabs(y), std::fabs(z)); } Vector3 Vector3::operator - () const @@ -289,11 +289,17 @@ bool Vector3::operator >= (const Vector3 & v) const Int32 Vector3::Cmp(const Vector3 & o) const { if (*this == o) + { return 0; + } else if (*this > o) + { return 1; + } else + { return -1; + } } // ------------------------------------------------------------------------------------------------ @@ -342,7 +348,7 @@ void Vector3::Set(const Quaternion & q) // ------------------------------------------------------------------------------------------------ void Vector3::Set(CSStr values, SQChar delim) { - Set(GetVector3(values, delim)); + Set(Vector3::Get(values, delim)); } // ------------------------------------------------------------------------------------------------ @@ -356,7 +362,9 @@ void Vector3::Generate() void Vector3::Generate(Value min, Value max) { if (EpsLt(max, min)) + { STHROWF("max value is lower than min value"); + } x = GetRandomFloat32(min, max); y = GetRandomFloat32(min, max); @@ -366,7 +374,9 @@ void Vector3::Generate(Value min, Value max) void Vector3::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax) { if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin) || EpsLt(zmax, zmin)) + { STHROWF("max value is lower than min value"); + } x = GetRandomFloat32(xmin, xmax); y = GetRandomFloat32(ymin, ymax); @@ -376,17 +386,17 @@ void Vector3::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmi // ------------------------------------------------------------------------------------------------ Vector3 Vector3::Abs() const { - return Vector3(fabs(x), fabs(y), fabs(z)); + return Vector3(std::fabs(x), std::fabs(y), std::fabs(z)); } // ------------------------------------------------------------------------------------------------ -const Vector3 & GetVector3(CSStr str) +const Vector3 & Vector3::Get(CSStr str) { - return GetVector3(str, Vector3::Delim); + return Vector3::Get(str, Vector3::Delim); } // ------------------------------------------------------------------------------------------------ -const Vector3 & GetVector3(CSStr str, SQChar delim) +const Vector3 & Vector3::Get(CSStr str, SQChar delim) { // The format specifications that will be used to scan the string static SQChar fs[] = _SC(" %f , %f , %f "); @@ -402,95 +412,124 @@ const Vector3 & GetVector3(CSStr str, SQChar delim) fs[4] = delim; fs[9] = delim; // Attempt to extract the component values from the specified string - sscanf(str, &fs[0], &vec.x, &vec.y, &vec.z); + std::sscanf(str, &fs[0], &vec.x, &vec.y, &vec.z); // Return the resulted value return vec; } +// ------------------------------------------------------------------------------------------------ +const Vector3 & GetVector3() +{ + static Vector3 vec; + vec.Clear(); + return vec; +} + +const Vector3 & GetVector3(Float32 sv) +{ + static Vector3 vec; + vec.Set(sv); + return vec; +} + +const Vector3 & GetVector3(Float32 xv, Float32 yv, Float32 zv) +{ + static Vector3 vec; + vec.Set(xv, yv, zv); + return vec; +} + +const Vector3 & GetVector3(const Vector3 & o) +{ + static Vector3 vec; + vec.Set(o); + return vec; +} + // ================================================================================================ void Register_Vector3(HSQUIRRELVM vm) { typedef Vector3::Value Val; RootTable(vm).Bind(_SC("Vector3"), Class< Vector3 >(vm, _SC("Vector3")) - /* Constructors */ + // Constructors .Ctor() .Ctor< Val >() .Ctor< Val, Val, Val >() - /* Static Members */ + // Static Members .SetStaticValue(_SC("Delim"), &Vector3::Delim) - /* Member Variables */ - .Var(_SC("x"), &Vector3::x) - .Var(_SC("y"), &Vector3::y) - .Var(_SC("z"), &Vector3::z) - /* Properties */ - .Prop(_SC("abs"), &Vector3::Abs) - /* Core Metamethods */ + // Member Variables + .Var(_SC("X"), &Vector3::x) + .Var(_SC("Y"), &Vector3::y) + .Var(_SC("Z"), &Vector3::z) + // Properties + .Prop(_SC("Abs"), &Vector3::Abs) + // Core Metamethods .Func(_SC("_tostring"), &Vector3::ToString) .SquirrelFunc(_SC("_typename"), &Vector3::Typename) .Func(_SC("_cmp"), &Vector3::Cmp) - /* Metamethods */ - .Func(_SC("_add"), &Vector3::operator +) - .Func(_SC("_sub"), &Vector3::operator -) - .Func(_SC("_mul"), &Vector3::operator *) - .Func(_SC("_div"), &Vector3::operator /) - .Func(_SC("_modulo"), &Vector3::operator %) - .Func(_SC("_unm"), &Vector3::operator -) - /* Setters */ - .Overload(_SC("Set"), &Vector3::Set) - .Overload(_SC("Set"), &Vector3::Set) - .Overload(_SC("SetVec3"), &Vector3::Set) - .Overload(_SC("SetVec4"), &Vector3::Set) - .Overload(_SC("SetQuat"), &Vector3::Set) - .Overload(_SC("SetStr"), &Vector3::Set) - /* Random Generators */ - .Overload(_SC("Generate"), &Vector3::Generate) - .Overload(_SC("Generate"), &Vector3::Generate) - .Overload(_SC("Generate"), &Vector3::Generate) - /* Utility Methods */ + // Metamethods + .Func< Vector3 (Vector3::*)(const Vector3 &) const >(_SC("_add"), &Vector3::operator +) + .Func< Vector3 (Vector3::*)(const Vector3 &) const >(_SC("_sub"), &Vector3::operator -) + .Func< Vector3 (Vector3::*)(const Vector3 &) const >(_SC("_mul"), &Vector3::operator *) + .Func< Vector3 (Vector3::*)(const Vector3 &) const >(_SC("_div"), &Vector3::operator /) + .Func< Vector3 (Vector3::*)(const Vector3 &) const >(_SC("_modulo"), &Vector3::operator %) + .Func< Vector3 (Vector3::*)(void) const >(_SC("_unm"), &Vector3::operator -) + // Setters + .Overload< void (Vector3::*)(Val) >(_SC("Set"), &Vector3::Set) + .Overload< void (Vector3::*)(Val, Val, Val) >(_SC("Set"), &Vector3::Set) + .Overload< void (Vector3::*)(const Vector3 &) >(_SC("SetVec3"), &Vector3::Set) + .Overload< void (Vector3::*)(const Vector4 &) >(_SC("SetVec4"), &Vector3::Set) + .Overload< void (Vector3::*)(const Quaternion &) >(_SC("SetQuat"), &Vector3::Set) + .Overload< void (Vector3::*)(CSStr, SQChar) >(_SC("SetStr"), &Vector3::Set) + // Random Generators + .Overload< void (Vector3::*)(void) >(_SC("Generate"), &Vector3::Generate) + .Overload< void (Vector3::*)(Val, Val) >(_SC("Generate"), &Vector3::Generate) + .Overload< void (Vector3::*)(Val, Val, Val, Val, Val, Val) >(_SC("Generate"), &Vector3::Generate) + // Utility Methods .Func(_SC("Clear"), &Vector3::Clear) - /* Operator Exposure */ - .Func(_SC("opAddAssign"), &Vector3::operator +=) - .Func(_SC("opSubAssign"), &Vector3::operator -=) - .Func(_SC("opMulAssign"), &Vector3::operator *=) - .Func(_SC("opDivAssign"), &Vector3::operator /=) - .Func(_SC("opModAssign"), &Vector3::operator %=) - - .Func(_SC("opAddAssignS"), &Vector3::operator +=) - .Func(_SC("opSubAssignS"), &Vector3::operator -=) - .Func(_SC("opMulAssignS"), &Vector3::operator *=) - .Func(_SC("opDivAssignS"), &Vector3::operator /=) - .Func(_SC("opModAssignS"), &Vector3::operator %=) - - .Func(_SC("opPreInc"), &Vector3::operator ++) - .Func(_SC("opPreDec"), &Vector3::operator --) - .Func(_SC("opPostInc"), &Vector3::operator ++) - .Func(_SC("opPostDec"), &Vector3::operator --) - - .Func(_SC("opAdd"), &Vector3::operator +) - .Func(_SC("opSub"), &Vector3::operator -) - .Func(_SC("opMul"), &Vector3::operator *) - .Func(_SC("opDiv"), &Vector3::operator /) - .Func(_SC("opMod"), &Vector3::operator %) - - .Func(_SC("opAddS"), &Vector3::operator +) - .Func(_SC("opSubS"), &Vector3::operator -) - .Func(_SC("opMulS"), &Vector3::operator *) - .Func(_SC("opDivS"), &Vector3::operator /) - .Func(_SC("opModS"), &Vector3::operator %) - - .Func(_SC("opUnPlus"), &Vector3::operator +) - .Func(_SC("opUnMinus"), &Vector3::operator -) - - .Func(_SC("opEqual"), &Vector3::operator ==) - .Func(_SC("opNotEqual"), &Vector3::operator !=) - .Func(_SC("opLessThan"), &Vector3::operator <) - .Func(_SC("opGreaterThan"), &Vector3::operator >) - .Func(_SC("opLessEqual"), &Vector3::operator <=) - .Func(_SC("opGreaterEqual"), &Vector3::operator >=) // Static Overloads - .StaticOverload< const Vector3 & (*)(CSStr) >(_SC("FromStr"), &GetVector3) - .StaticOverload< const Vector3 & (*)(CSStr, SQChar) >(_SC("FromStr"), &GetVector3) + .StaticOverload< const Vector3 & (*)(CSStr) >(_SC("FromStr"), &Vector3::Get) + .StaticOverload< const Vector3 & (*)(CSStr, SQChar) >(_SC("FromStr"), &Vector3::Get) + // Operator Exposure + .Func< Vector3 & (Vector3::*)(const Vector3 &) >(_SC("opAddAssign"), &Vector3::operator +=) + .Func< Vector3 & (Vector3::*)(const Vector3 &) >(_SC("opSubAssign"), &Vector3::operator -=) + .Func< Vector3 & (Vector3::*)(const Vector3 &) >(_SC("opMulAssign"), &Vector3::operator *=) + .Func< Vector3 & (Vector3::*)(const Vector3 &) >(_SC("opDivAssign"), &Vector3::operator /=) + .Func< Vector3 & (Vector3::*)(const Vector3 &) >(_SC("opModAssign"), &Vector3::operator %=) + + .Func< Vector3 & (Vector3::*)(Vector3::Value) >(_SC("opAddAssignS"), &Vector3::operator +=) + .Func< Vector3 & (Vector3::*)(Vector3::Value) >(_SC("opSubAssignS"), &Vector3::operator -=) + .Func< Vector3 & (Vector3::*)(Vector3::Value) >(_SC("opMulAssignS"), &Vector3::operator *=) + .Func< Vector3 & (Vector3::*)(Vector3::Value) >(_SC("opDivAssignS"), &Vector3::operator /=) + .Func< Vector3 & (Vector3::*)(Vector3::Value) >(_SC("opModAssignS"), &Vector3::operator %=) + + .Func< Vector3 & (Vector3::*)(void) >(_SC("opPreInc"), &Vector3::operator ++) + .Func< Vector3 & (Vector3::*)(void) >(_SC("opPreDec"), &Vector3::operator --) + .Func< Vector3 (Vector3::*)(int) >(_SC("opPostInc"), &Vector3::operator ++) + .Func< Vector3 (Vector3::*)(int) >(_SC("opPostDec"), &Vector3::operator --) + + .Func< Vector3 (Vector3::*)(const Vector3 &) const >(_SC("opAdd"), &Vector3::operator +) + .Func< Vector3 (Vector3::*)(const Vector3 &) const >(_SC("opSub"), &Vector3::operator -) + .Func< Vector3 (Vector3::*)(const Vector3 &) const >(_SC("opMul"), &Vector3::operator *) + .Func< Vector3 (Vector3::*)(const Vector3 &) const >(_SC("opDiv"), &Vector3::operator /) + .Func< Vector3 (Vector3::*)(const Vector3 &) const >(_SC("opMod"), &Vector3::operator %) + + .Func< Vector3 (Vector3::*)(Vector3::Value) const >(_SC("opAddS"), &Vector3::operator +) + .Func< Vector3 (Vector3::*)(Vector3::Value) const >(_SC("opSubS"), &Vector3::operator -) + .Func< Vector3 (Vector3::*)(Vector3::Value) const >(_SC("opMulS"), &Vector3::operator *) + .Func< Vector3 (Vector3::*)(Vector3::Value) const >(_SC("opDivS"), &Vector3::operator /) + .Func< Vector3 (Vector3::*)(Vector3::Value) const >(_SC("opModS"), &Vector3::operator %) + + .Func< Vector3 (Vector3::*)(void) const >(_SC("opUnPlus"), &Vector3::operator +) + .Func< Vector3 (Vector3::*)(void) const >(_SC("opUnMinus"), &Vector3::operator -) + + .Func< bool (Vector3::*)(const Vector3 &) const >(_SC("opEqual"), &Vector3::operator ==) + .Func< bool (Vector3::*)(const Vector3 &) const >(_SC("opNotEqual"), &Vector3::operator !=) + .Func< bool (Vector3::*)(const Vector3 &) const >(_SC("opLessThan"), &Vector3::operator <) + .Func< bool (Vector3::*)(const Vector3 &) const >(_SC("opGreaterThan"), &Vector3::operator >) + .Func< bool (Vector3::*)(const Vector3 &) const >(_SC("opLessEqual"), &Vector3::operator <=) + .Func< bool (Vector3::*)(const Vector3 &) const >(_SC("opGreaterEqual"), &Vector3::operator >=) ); } diff --git a/source/Base/Vector3.hpp b/source/Base/Vector3.hpp index 1f89b159..386ad378 100644 --- a/source/Base/Vector3.hpp +++ b/source/Base/Vector3.hpp @@ -7,16 +7,6 @@ // ------------------------------------------------------------------------------------------------ namespace SqMod { -/* ------------------------------------------------------------------------------------------------ - * Extract the values for components of the Vector3 type from a string. -*/ -const Vector3 & GetVector3(CSStr str); - -/* ------------------------------------------------------------------------------------------------ - * Extract the values for components of the Vector3 type from a string. -*/ -const Vector3 & GetVector3(CSStr str, SQChar delim); - /* ------------------------------------------------------------------------------------------------ * Class used to represent a three-dimensional vector. */ @@ -331,6 +321,17 @@ struct Vector3 * Retrieve a new instance of this type with absolute component values. */ Vector3 Abs() const; + + /* -------------------------------------------------------------------------------------------- + * Extract the values for components of the Vector3 type from a string. + */ + static const Vector3 & Get(CSStr str); + + /* -------------------------------------------------------------------------------------------- + * Extract the values for components of the Vector3 type from a string. + */ + static const Vector3 & Get(CSStr str, SQChar delim); + }; } // Namespace:: SqMod diff --git a/source/Base/Vector4.cpp b/source/Base/Vector4.cpp index 28771d9f..9002a9d4 100644 --- a/source/Base/Vector4.cpp +++ b/source/Base/Vector4.cpp @@ -22,7 +22,7 @@ SQChar Vector4::Delim = ','; // ------------------------------------------------------------------------------------------------ SQInteger Vector4::Typename(HSQUIRRELVM vm) { - static SQChar name[] = _SC("Vector4"); + static const SQChar name[] = _SC("Vector4"); sq_pushstring(vm, name, sizeof(name)); return 1; } @@ -122,10 +122,10 @@ Vector4 & Vector4::operator /= (const Vector4 & v) Vector4 & Vector4::operator %= (const Vector4 & v) { - x = fmod(x, v.x); - y = fmod(y, v.y); - z = fmod(z, v.z); - w = fmod(w, v.w); + x = std::fmod(x, v.x); + y = std::fmod(y, v.y); + z = std::fmod(z, v.z); + w = std::fmod(w, v.w); return *this; } @@ -168,10 +168,10 @@ Vector4 & Vector4::operator /= (Value s) Vector4 & Vector4::operator %= (Value s) { - x = fmod(x, s); - y = fmod(y, s); - z = fmod(z, s); - w = fmod(w, s); + x = std::fmod(x, s); + y = std::fmod(y, s); + z = std::fmod(z, s); + w = std::fmod(w, s); return *this; } @@ -238,7 +238,7 @@ Vector4 Vector4::operator / (const Vector4 & v) const Vector4 Vector4::operator % (const Vector4 & v) const { - return Vector4(fmod(x, v.x), fmod(y, v.y), fmod(z, v.z), fmod(w, v.w)); + return Vector4(std::fmod(x, v.x), std::fmod(y, v.y), std::fmod(z, v.z), std::fmod(w, v.w)); } // ------------------------------------------------------------------------------------------------ @@ -264,13 +264,13 @@ Vector4 Vector4::operator / (Value s) const Vector4 Vector4::operator % (Value s) const { - return Vector4(fmod(x, s), fmod(y, s), fmod(z, s), fmod(w, s)); + return Vector4(std::fmod(x, s), std::fmod(y, s), std::fmod(z, s), std::fmod(w, s)); } // ------------------------------------------------------------------------------------------------ Vector4 Vector4::operator + () const { - return Vector4(fabs(x), fabs(y), fabs(z), fabs(w)); + return Vector4(std::fabs(x), std::fabs(y), std::fabs(z), std::fabs(w)); } Vector4 Vector4::operator - () const @@ -313,11 +313,17 @@ bool Vector4::operator >= (const Vector4 & v) const Int32 Vector4::Cmp(const Vector4 & o) const { if (*this == o) + { return 0; + } else if (*this > o) + { return 1; + } else + { return -1; + } } // ------------------------------------------------------------------------------------------------ @@ -378,7 +384,7 @@ void Vector4::Set(const Quaternion & q) // ------------------------------------------------------------------------------------------------ void Vector4::Set(CSStr values, SQChar delim) { - Set(GetVector4(values, delim)); + Set(Vector4::Get(values, delim)); } // ------------------------------------------------------------------------------------------------ @@ -393,7 +399,9 @@ void Vector4::Generate() void Vector4::Generate(Value min, Value max) { if (max < min) + { STHROWF("max value is lower than min value"); + } x = GetRandomFloat32(min, max); y = GetRandomFloat32(min, max); @@ -404,7 +412,9 @@ void Vector4::Generate(Value min, Value max) void Vector4::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax, Value wmin, Value wmax) { if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin) || EpsLt(zmax, zmin) || EpsLt(wmax, wmin)) + { STHROWF("max value is lower than min value"); + } x = GetRandomFloat32(xmin, xmax); y = GetRandomFloat32(ymin, ymax); @@ -415,17 +425,17 @@ void Vector4::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmi // ------------------------------------------------------------------------------------------------ Vector4 Vector4::Abs() const { - return Vector4(fabs(x), fabs(y), fabs(z), fabs(w)); + return Vector4(std::fabs(x), std::fabs(y), std::fabs(z), std::fabs(w)); } // ------------------------------------------------------------------------------------------------ -const Vector4 & GetVector4(CSStr str) +const Vector4 & Vector4::Get(CSStr str) { - return GetVector4(str, Vector4::Delim); + return Vector4::Get(str, Vector4::Delim); } // ------------------------------------------------------------------------------------------------ -const Vector4 & GetVector4(CSStr str, SQChar delim) +const Vector4 & Vector4::Get(CSStr str, SQChar delim) { // The format specifications that will be used to scan the string static SQChar fs[] = _SC(" %f , %f , %f , %f "); @@ -442,98 +452,134 @@ const Vector4 & GetVector4(CSStr str, SQChar delim) fs[9] = delim; fs[14] = delim; // Attempt to extract the component values from the specified string - sscanf(str, &fs[0], &vec.x, &vec.y, &vec.z, &vec.w); + std::sscanf(str, &fs[0], &vec.x, &vec.y, &vec.z, &vec.w); // Return the resulted value return vec; } +// ------------------------------------------------------------------------------------------------ +const Vector4 & GetVector4() +{ + static Vector4 vec; + vec.Clear(); + return vec; +} + +const Vector4 & GetVector4(Float32 sv) +{ + static Vector4 vec; + vec.Set(sv); + return vec; +} + +const Vector4 & GetVector4(Float32 xv, Float32 yv, Float32 zv) +{ + static Vector4 vec; + vec.Set(xv, yv, zv); + return vec; +} + +const Vector4 & GetVector4(Float32 xv, Float32 yv, Float32 zv, Float32 wv) +{ + static Vector4 vec; + vec.Set(xv, yv, zv, wv); + return vec; +} + +const Vector4 & GetVector4(const Vector4 & o) +{ + static Vector4 vec; + vec.Set(o); + return vec; +} + // ================================================================================================ void Register_Vector4(HSQUIRRELVM vm) { typedef Vector4::Value Val; RootTable(vm).Bind(_SC("Vector4"), Class< Vector4 >(vm, _SC("Vector4")) - /* Constructors */ + // Constructors .Ctor() .Ctor< Val >() .Ctor< Val, Val, Val >() .Ctor< Val, Val, Val, Val >() - /* Static Members */ + // Static Members .SetStaticValue(_SC("Delim"), &Vector4::Delim) - /* Member Variables */ + // Member Variables .Var(_SC("x"), &Vector4::x) .Var(_SC("y"), &Vector4::y) .Var(_SC("z"), &Vector4::z) .Var(_SC("w"), &Vector4::w) - /* Properties */ - .Prop(_SC("abs"), &Vector4::Abs) - /* Core Metamethods */ + // Properties + .Prop(_SC("Abs"), &Vector4::Abs) + // Core Metamethods .Func(_SC("_tostring"), &Vector4::ToString) .SquirrelFunc(_SC("_typename"), &Vector4::Typename) .Func(_SC("_cmp"), &Vector4::Cmp) - /* Metamethods */ - .Func(_SC("_add"), &Vector4::operator +) - .Func(_SC("_sub"), &Vector4::operator -) - .Func(_SC("_mul"), &Vector4::operator *) - .Func(_SC("_div"), &Vector4::operator /) - .Func(_SC("_modulo"), &Vector4::operator %) - .Func(_SC("_unm"), &Vector4::operator -) - /* Setters */ - .Overload(_SC("Set"), &Vector4::Set) - .Overload(_SC("Set"), &Vector4::Set) - .Overload(_SC("Set"), &Vector4::Set) - .Overload(_SC("SetVec4"), &Vector4::Set) - .Overload(_SC("SetVec3"), &Vector4::Set) - .Overload(_SC("SetQuat"), &Vector4::Set) - .Overload(_SC("SetStr"), &Vector4::Set) - /* Random Generators */ - .Overload(_SC("Generate"), &Vector4::Generate) - .Overload(_SC("Generate"), &Vector4::Generate) - .Overload(_SC("Generate"), &Vector4::Generate) - /* Utility Methods */ + // Metamethods + .Func< Vector4 (Vector4::*)(const Vector4 &) const >(_SC("_add"), &Vector4::operator +) + .Func< Vector4 (Vector4::*)(const Vector4 &) const >(_SC("_sub"), &Vector4::operator -) + .Func< Vector4 (Vector4::*)(const Vector4 &) const >(_SC("_mul"), &Vector4::operator *) + .Func< Vector4 (Vector4::*)(const Vector4 &) const >(_SC("_div"), &Vector4::operator /) + .Func< Vector4 (Vector4::*)(const Vector4 &) const >(_SC("_modulo"), &Vector4::operator %) + .Func< Vector4 (Vector4::*)(void) const >(_SC("_unm"), &Vector4::operator -) + // Setters + .Overload< void (Vector4::*)(Val) >(_SC("Set"), &Vector4::Set) + .Overload< void (Vector4::*)(Val, Val, Val) >(_SC("Set"), &Vector4::Set) + .Overload< void (Vector4::*)(Val, Val, Val, Val) >(_SC("Set"), &Vector4::Set) + .Overload< void (Vector4::*)(const Vector4 &) >(_SC("SetVec4"), &Vector4::Set) + .Overload< void (Vector4::*)(const Vector3 &) >(_SC("SetVec3"), &Vector4::Set) + .Overload< void (Vector4::*)(const Quaternion &) >(_SC("SetQuat"), &Vector4::Set) + .Overload< void (Vector4::*)(CSStr, SQChar) >(_SC("SetStr"), &Vector4::Set) + // Random Generators + .Overload< void (Vector4::*)(void) >(_SC("Generate"), &Vector4::Generate) + .Overload< void (Vector4::*)(Val, Val) >(_SC("Generate"), &Vector4::Generate) + .Overload< void (Vector4::*)(Val, Val, Val, Val, Val, Val, Val, Val) >(_SC("Generate"), &Vector4::Generate) + // Utility Methods .Func(_SC("Clear"), &Vector4::Clear) - /* Operator Exposure */ - .Func(_SC("opAddAssign"), &Vector4::operator +=) - .Func(_SC("opSubAssign"), &Vector4::operator -=) - .Func(_SC("opMulAssign"), &Vector4::operator *=) - .Func(_SC("opDivAssign"), &Vector4::operator /=) - .Func(_SC("opModAssign"), &Vector4::operator %=) - - .Func(_SC("opAddAssignS"), &Vector4::operator +=) - .Func(_SC("opSubAssignS"), &Vector4::operator -=) - .Func(_SC("opMulAssignS"), &Vector4::operator *=) - .Func(_SC("opDivAssignS"), &Vector4::operator /=) - .Func(_SC("opModAssignS"), &Vector4::operator %=) - - .Func(_SC("opPreInc"), &Vector4::operator ++) - .Func(_SC("opPreDec"), &Vector4::operator --) - .Func(_SC("opPostInc"), &Vector4::operator ++) - .Func(_SC("opPostDec"), &Vector4::operator --) - - .Func(_SC("opAdd"), &Vector4::operator +) - .Func(_SC("opSub"), &Vector4::operator -) - .Func(_SC("opMul"), &Vector4::operator *) - .Func(_SC("opDiv"), &Vector4::operator /) - .Func(_SC("opMod"), &Vector4::operator %) - - .Func(_SC("opAddS"), &Vector4::operator +) - .Func(_SC("opSubS"), &Vector4::operator -) - .Func(_SC("opMulS"), &Vector4::operator *) - .Func(_SC("opDivS"), &Vector4::operator /) - .Func(_SC("opModS"), &Vector4::operator %) - - .Func(_SC("opUnPlus"), &Vector4::operator +) - .Func(_SC("opUnMinus"), &Vector4::operator -) - - .Func(_SC("opEqual"), &Vector4::operator ==) - .Func(_SC("opNotEqual"), &Vector4::operator !=) - .Func(_SC("opLessThan"), &Vector4::operator <) - .Func(_SC("opGreaterThan"), &Vector4::operator >) - .Func(_SC("opLessEqual"), &Vector4::operator <=) - .Func(_SC("opGreaterEqual"), &Vector4::operator >=) // Static Overloads - .StaticOverload< const Vector4 & (*)(CSStr) >(_SC("FromStr"), &GetVector4) - .StaticOverload< const Vector4 & (*)(CSStr, SQChar) >(_SC("FromStr"), &GetVector4) + .StaticOverload< const Vector4 & (*)(CSStr) >(_SC("FromStr"), &Vector4::Get) + .StaticOverload< const Vector4 & (*)(CSStr, SQChar) >(_SC("FromStr"), &Vector4::Get) + // Operator Exposure + .Func< Vector4 & (Vector4::*)(const Vector4 &) >(_SC("opAddAssign"), &Vector4::operator +=) + .Func< Vector4 & (Vector4::*)(const Vector4 &) >(_SC("opSubAssign"), &Vector4::operator -=) + .Func< Vector4 & (Vector4::*)(const Vector4 &) >(_SC("opMulAssign"), &Vector4::operator *=) + .Func< Vector4 & (Vector4::*)(const Vector4 &) >(_SC("opDivAssign"), &Vector4::operator /=) + .Func< Vector4 & (Vector4::*)(const Vector4 &) >(_SC("opModAssign"), &Vector4::operator %=) + + .Func< Vector4 & (Vector4::*)(Vector4::Value) >(_SC("opAddAssignS"), &Vector4::operator +=) + .Func< Vector4 & (Vector4::*)(Vector4::Value) >(_SC("opSubAssignS"), &Vector4::operator -=) + .Func< Vector4 & (Vector4::*)(Vector4::Value) >(_SC("opMulAssignS"), &Vector4::operator *=) + .Func< Vector4 & (Vector4::*)(Vector4::Value) >(_SC("opDivAssignS"), &Vector4::operator /=) + .Func< Vector4 & (Vector4::*)(Vector4::Value) >(_SC("opModAssignS"), &Vector4::operator %=) + + .Func< Vector4 & (Vector4::*)(void) >(_SC("opPreInc"), &Vector4::operator ++) + .Func< Vector4 & (Vector4::*)(void) >(_SC("opPreDec"), &Vector4::operator --) + .Func< Vector4 (Vector4::*)(int) >(_SC("opPostInc"), &Vector4::operator ++) + .Func< Vector4 (Vector4::*)(int) >(_SC("opPostDec"), &Vector4::operator --) + + .Func< Vector4 (Vector4::*)(const Vector4 &) const >(_SC("opAdd"), &Vector4::operator +) + .Func< Vector4 (Vector4::*)(const Vector4 &) const >(_SC("opSub"), &Vector4::operator -) + .Func< Vector4 (Vector4::*)(const Vector4 &) const >(_SC("opMul"), &Vector4::operator *) + .Func< Vector4 (Vector4::*)(const Vector4 &) const >(_SC("opDiv"), &Vector4::operator /) + .Func< Vector4 (Vector4::*)(const Vector4 &) const >(_SC("opMod"), &Vector4::operator %) + + .Func< Vector4 (Vector4::*)(Vector4::Value) const >(_SC("opAddS"), &Vector4::operator +) + .Func< Vector4 (Vector4::*)(Vector4::Value) const >(_SC("opSubS"), &Vector4::operator -) + .Func< Vector4 (Vector4::*)(Vector4::Value) const >(_SC("opMulS"), &Vector4::operator *) + .Func< Vector4 (Vector4::*)(Vector4::Value) const >(_SC("opDivS"), &Vector4::operator /) + .Func< Vector4 (Vector4::*)(Vector4::Value) const >(_SC("opModS"), &Vector4::operator %) + + .Func< Vector4 (Vector4::*)(void) const >(_SC("opUnPlus"), &Vector4::operator +) + .Func< Vector4 (Vector4::*)(void) const >(_SC("opUnMinus"), &Vector4::operator -) + + .Func< bool (Vector4::*)(const Vector4 &) const >(_SC("opEqual"), &Vector4::operator ==) + .Func< bool (Vector4::*)(const Vector4 &) const >(_SC("opNotEqual"), &Vector4::operator !=) + .Func< bool (Vector4::*)(const Vector4 &) const >(_SC("opLessThan"), &Vector4::operator <) + .Func< bool (Vector4::*)(const Vector4 &) const >(_SC("opGreaterThan"), &Vector4::operator >) + .Func< bool (Vector4::*)(const Vector4 &) const >(_SC("opLessEqual"), &Vector4::operator <=) + .Func< bool (Vector4::*)(const Vector4 &) const >(_SC("opGreaterEqual"), &Vector4::operator >=) ); } diff --git a/source/Base/Vector4.hpp b/source/Base/Vector4.hpp index d86c8ea7..3b40485c 100644 --- a/source/Base/Vector4.hpp +++ b/source/Base/Vector4.hpp @@ -7,16 +7,6 @@ // ------------------------------------------------------------------------------------------------ namespace SqMod { -/* ------------------------------------------------------------------------------------------------ - * Extract the values for components of the Vector4 type from a string. -*/ -const Vector4 & GetVector4(CSStr str); - -/* ------------------------------------------------------------------------------------------------ - * Extract the values for components of the Vector4 type from a string. -*/ -const Vector4 & GetVector4(CSStr str, SQChar delim); - /* ------------------------------------------------------------------------------------------------ * Class used to represent a four-dimensional vector. */ @@ -341,6 +331,17 @@ struct Vector4 * Retrieve a new instance of this type with absolute component values. */ Vector4 Abs() const; + + /* -------------------------------------------------------------------------------------------- + * Extract the values for components of the Vector4 type from a string. + */ + static const Vector4 & Get(CSStr str); + + /* -------------------------------------------------------------------------------------------- + * Extract the values for components of the Vector4 type from a string. + */ + static const Vector4 & Get(CSStr str, SQChar delim); + }; } // Namespace:: SqMod diff --git a/source/Command.cpp b/source/Command.cpp index 957fe474..e369ed49 100644 --- a/source/Command.cpp +++ b/source/Command.cpp @@ -5,9 +5,9 @@ #include "Entity/Player.hpp" // ------------------------------------------------------------------------------------------------ -#include -#include -#include +#include +#include +#include #include #include @@ -15,12 +15,12 @@ namespace SqMod { // ------------------------------------------------------------------------------------------------ -SQMOD_MANAGEDPTR_TYPE(CmdManager) _Cmd = SQMOD_MANAGEDPTR_MAKE(CmdManager, nullptr); +CmdManager CmdManager::s_Inst; // ------------------------------------------------------------------------------------------------ SQInteger CmdListener::Typename(HSQUIRRELVM vm) { - static SQChar name[] = _SC("SqCmdListener"); + static const SQChar name[] = _SC("SqCmdListener"); sq_pushstring(vm, name, sizeof(name)); return 1; } @@ -37,7 +37,7 @@ static void ValidateName(CSStr name) while (*name != '\0') { // Does it contain spaces? - if (isspace(*name) != 0) + if (std::isspace(*name) != 0) { STHROWF("Command names cannot contain spaces"); } @@ -63,36 +63,29 @@ CSStr CmdArgSpecToStr(Uint8 spec) } } +/* ------------------------------------------------------------------------------------------------ + * Forward the call to initialize the command manager. +*/ +void InitializeCmdManager() +{ + CmdManager::Get().Initialize(); +} + +/* ------------------------------------------------------------------------------------------------ + * Forward the call to terminate the command manager. +*/ +void TerminateCmdManager() +{ + CmdManager::Get().Deinitialize(); +} + // ------------------------------------------------------------------------------------------------ CmdManager::Guard::~Guard() { // Release the command instance - _Cmd->m_Instance = nullptr; + CmdManager::Get().m_Instance = nullptr; // Release the reference to the script object - _Cmd->m_Object.Release(); -} - -// ------------------------------------------------------------------------------------------------ -CmdManager::CmdManager() - : m_Buffer(512) - , m_Commands() - , m_Invoker(SQMOD_UNKNOWN) - , m_Command(64, '\0') - , m_Argument(512, '\0') - , m_Instance(nullptr) - , m_Object() - , m_Argv() - , m_Argc(0) - , m_OnError() - , m_OnAuth() -{ - /* ... */ -} - -// ------------------------------------------------------------------------------------------------ -CmdManager::~CmdManager() -{ - /* ... */ + CmdManager::Get().m_Object.Release(); } // ------------------------------------------------------------------------------------------------ @@ -205,6 +198,59 @@ bool CmdManager::Attached(const CmdListener * ptr) const return false; } +// ------------------------------------------------------------------------------------------------ +CmdManager::CmdManager() + : m_Buffer(512) + , m_Commands() + , m_Invoker(SQMOD_UNKNOWN) + , m_Command(64, '\0') + , m_Argument(512, '\0') + , m_Instance(nullptr) + , m_Object() + , m_Argv() + , m_Argc(0) + , m_OnFail() + , m_OnAuth() +{ + /* ... */ +} + +// ------------------------------------------------------------------------------------------------ +CmdManager::~CmdManager() +{ + /* ... */ +} + +// ------------------------------------------------------------------------------------------------ +void CmdManager::Initialize() +{ + +} + +// ------------------------------------------------------------------------------------------------ +void CmdManager::Deinitialize() +{ + // Release the script resources from command instances + for (const auto & cmd : m_Commands) + { + if (cmd.mPtr) + { + // Release the local command callbacks + cmd.mPtr->m_OnExec.ReleaseGently(); + cmd.mPtr->m_OnAuth.ReleaseGently(); + cmd.mPtr->m_OnPost.ReleaseGently(); + cmd.mPtr->m_OnFail.ReleaseGently(); + } + } + // Clear the command list and release all references + m_Commands.clear(); + // Release the script resources from this class + m_Argv.clear(); + // Release the global callbacks + m_OnFail.ReleaseGently(); + m_OnAuth.ReleaseGently(); +} + // ------------------------------------------------------------------------------------------------ void CmdManager::Sort() { @@ -232,30 +278,6 @@ const Object & CmdManager::FindByName(const String & name) return NullObject(); } -// ------------------------------------------------------------------------------------------------ -void CmdManager::Terminate() -{ - // Release the script resources from command instances - for (const auto & cmd : m_Commands) - { - if (cmd.mPtr) - { - // Release the local command callbacks - cmd.mPtr->m_OnExec.ReleaseGently(); - cmd.mPtr->m_OnAuth.ReleaseGently(); - cmd.mPtr->m_OnPost.ReleaseGently(); - cmd.mPtr->m_OnFail.ReleaseGently(); - } - } - // Clear the command list and release all references - m_Commands.clear(); - // Release the script resources from this class - m_Argv.clear(); - // Release the global callbacks - m_OnError.ReleaseGently(); - m_OnAuth.ReleaseGently(); -} - // ------------------------------------------------------------------------------------------------ Int32 CmdManager::Run(Int32 invoker, CCStr command) { @@ -270,7 +292,10 @@ Int32 CmdManager::Run(Int32 invoker, CCStr command) // Save the invoker identifier m_Invoker = invoker; // Skip white-space until the command name - while (isspace(*command)) ++command; + while (std::isspace(*command)) + { + ++command; + } // Anything left to process? if (*command == '\0') { @@ -282,14 +307,20 @@ Int32 CmdManager::Run(Int32 invoker, CCStr command) // Where the name ends and argument begins CCStr split = command; // Find where the command name ends - while (!isspace(*split) && *split != '\0') ++split; + while (*split != '\0' && !std::isspace(*split)) + { + ++split; + } // Are there any arguments specified? - if (split != nullptr) + if (split != '\0') { // Save the command name m_Command.assign(command, (split - command)); // Skip white space after command name - while (isspace(*split)) ++split; + while (std::isspace(*split)) + { + ++split; + } // Save the command argument m_Argument.assign(split); } @@ -299,13 +330,20 @@ Int32 CmdManager::Run(Int32 invoker, CCStr command) // Save the command name m_Command.assign(command); // Leave argument empty - m_Argument.assign(""); + m_Argument.assign(_SC("")); } // Do we have a valid command name? try { ValidateName(m_Command.c_str()); } + catch (const Sqrat::Exception & e) + { + // Tell the script callback to deal with the error + SqError(CMDERR_INVALID_COMMAND, ToStrF("%s", e.Message().c_str()), invoker); + // Execution failed! + return -1; + } catch (...) { // Tell the script callback to deal with the error @@ -408,7 +446,7 @@ Int32 CmdManager::Exec() // Result of the command execution SQInteger result = -1; // Clear any data from the buffer to make room for the error message - m_Buffer.At(0) = 0; + m_Buffer.At(0) = '\0'; // Whether the command execution failed bool failed = false; // Do we have to call the command with an associative container? @@ -433,7 +471,7 @@ Int32 CmdManager::Exec() // Attempt to execute the command with the specified arguments try { - result = m_Instance->Execute(_Core->GetPlayer(m_Invoker).mObj, args); + result = m_Instance->Execute(Core::Get().GetPlayer(m_Invoker).mObj, args); } catch (const Sqrat::Exception & e) { @@ -442,6 +480,13 @@ Int32 CmdManager::Exec() // Specify that the command execution failed failed = true; } + catch (const std::exception & e) + { + // Let's store the exception message + m_Buffer.WriteF(0, "Application exception occurred [%s]", e.what()); + // Specify that the command execution failed + failed = true; + } } else { @@ -455,7 +500,7 @@ Int32 CmdManager::Exec() // Attempt to execute the command with the specified arguments try { - result = m_Instance->Execute(_Core->GetPlayer(m_Invoker).mObj, args); + result = m_Instance->Execute(Core::Get().GetPlayer(m_Invoker).mObj, args); } catch (const Sqrat::Exception & e) { @@ -464,6 +509,13 @@ Int32 CmdManager::Exec() // Specify that the command execution failed failed = true; } + catch (const std::exception & e) + { + // Let's store the exception message + m_Buffer.WriteF(0, "Application exception occurred [%s]", e.what()); + // Specify that the command execution failed + failed = true; + } } // Was there a runtime exception during the execution? if (failed) @@ -476,13 +528,18 @@ Int32 CmdManager::Exec() // Then attempt to relay the result to that function try { - m_Instance->m_OnFail.Execute(_Core->GetPlayer(m_Invoker).mObj, result); + m_Instance->m_OnFail.Execute(Core::Get().GetPlayer(m_Invoker).mObj, result); } catch (const Sqrat::Exception & e) { // Tell the script callback to deal with the error SqError(CMDERR_UNRESOLVED_FAILURE, _SC("Unable to resolve command failure"), e.Message()); } + catch (const std::exception & e) + { + // Tell the script callback to deal with the error + SqError(CMDERR_UNRESOLVED_FAILURE, _SC("Unable to resolve command failure"), e.what()); + } } // Result is invalid at this point result = -1; @@ -498,13 +555,18 @@ Int32 CmdManager::Exec() // Then attempt to relay the result to that function try { - m_Instance->m_OnFail.Execute(_Core->GetPlayer(m_Invoker).mObj, result); + m_Instance->m_OnFail.Execute(Core::Get().GetPlayer(m_Invoker).mObj, result); } catch (const Sqrat::Exception & e) { // Tell the script callback to deal with the error SqError(CMDERR_UNRESOLVED_FAILURE, _SC("Unable to resolve command failure"), e.Message()); } + catch (const std::exception & e) + { + // Tell the script callback to deal with the error + SqError(CMDERR_UNRESOLVED_FAILURE, _SC("Unable to resolve command failure"), e.what()); + } } } // Is there a callback that must be executed after a successful execution? @@ -513,16 +575,21 @@ Int32 CmdManager::Exec() // Then attempt to relay the result to that function try { - m_Instance->m_OnPost.Execute(_Core->GetPlayer(m_Invoker).mObj, result); + m_Instance->m_OnPost.Execute(Core::Get().GetPlayer(m_Invoker).mObj, result); } catch (const Sqrat::Exception & e) { // Tell the script callback to deal with the error SqError(CMDERR_POST_PROCESSING_FAILED, _SC("Unable to complete command post processing"), e.Message()); } + catch (const std::exception & e) + { + // Tell the script callback to deal with the error + SqError(CMDERR_POST_PROCESSING_FAILED, _SC("Unable to complete command post processing"), e.what()); + } } // Return the result - return static_cast< Int32 >(result); + return ConvTo< Int32 >::From(result); } // ------------------------------------------------------------------------------------------------ @@ -536,11 +603,11 @@ bool CmdManager::Parse() // Obtain the flags of the currently processed argument Uint8 arg_flags = m_Instance->m_ArgSpec[m_Argc]; // Adjust the internal buffer if necessary (mostly never) - m_Buffer.Adjust< SQChar >(m_Argument.size()); + m_Buffer.Adjust(m_Argument.size()); // The iterator to the currently processed character - String::iterator itr = m_Argument.begin(); + String::const_iterator itr = m_Argument.cbegin(); // Previous and currently processed character - SQChar prev = 0, elem = 0; + String::value_type prev = 0, elem = 0; // Maximum arguments allowed to be processed const Uint8 max_arg = m_Instance->m_MaxArgc; // Process loop result @@ -550,37 +617,31 @@ bool CmdManager::Parse() { // Extract the current characters before advancing prev = elem, elem = *itr; - // See if there's anything left to parse - if (elem == '\0') - { - break; - } - // Early check to prevent parsing extraneous arguments - else if (m_Argc >= max_arg) + // See if we have anything left to parse or we have what we need already + if (elem == '\0' || m_Argc >= max_arg) { - // Tell the script callback to deal with the error - SqError(CMDERR_EXTRANEOUS_ARGS, _SC("Extraneous command arguments"), max_arg); - // Parsing aborted - good = false; - // Stop parsing - break; + break; // We only parse what we need or what we have! } // Is this a greedy argument? else if (arg_flags & CMDARG_GREEDY) { + // Remember the current stack size + const StackGuard sg; // Skip white-space characters - while (itr != m_Argument.end() && isspace(*itr)) ++itr; + itr = std::find_if(itr, m_Argument.cend(), IsNotCType(std::isspace)); // Anything left to copy to the argument? if (itr != m_Argument.end()) + { // Transform it into a script object - sq_pushstring(DefaultVM::Get(), &(*itr), std::distance(itr, m_Argument.end())); + sq_pushstring(DefaultVM::Get(), &(*itr), std::distance(itr, m_Argument.cend())); + } // Just push an empty string else + { sq_pushstring(DefaultVM::Get(), _SC(""), 0); + } // Get the object from the stack and add it to the argument list along with it's type m_Argv.emplace_back(CMDARG_STRING, Var< Object >(DefaultVM::Get(), -1).value); - // Pop the created object from the stack - sq_pop(DefaultVM::Get(), 1); // Include this argument into the count ++m_Argc; // Nothing left to parse @@ -591,9 +652,9 @@ bool CmdManager::Parse() { // Obtain the beginning and ending of the internal buffer SStr str = m_Buffer.Begin< SQChar >(); - CSStr end = (m_Buffer.End< SQChar >()-1); // + null terminator + SStr end = (m_Buffer.End< SQChar >() - 1); // + null terminator // Save the closing quote type - SQChar close = elem; + const SQChar close = elem; // Skip the opening quote ++itr; // Attempt to consume the string argument @@ -602,7 +663,7 @@ bool CmdManager::Parse() // Extract the current characters before advancing prev = elem, elem = *itr; // See if there's anything left to parse - if (elem == 0) + if (elem == '\0') { // Tell the script callback to deal with the error SqError(CMDERR_SYNTAX_ERROR, _SC("String argument not closed properly"), m_Argc); @@ -618,13 +679,15 @@ bool CmdManager::Parse() if (prev != '\\') { // Terminate the string value in the internal buffer - *str = 0; + *str = '\0'; // Stop parsing break; } // Overwrite last character when replicating else + { --str; + } } // See if the internal buffer needs to scale else if (str >= end) @@ -637,157 +700,194 @@ bool CmdManager::Parse() break; } // Simply replicate the character to the internal buffer - *(str++) = elem; + *str = elem; // Advance to the next character - ++itr; + ++str, ++itr; } // See if the argument was valid if (!good) - // Propagate failure - break; - // Do we have to make the string lowercase? - else if (arg_flags & CMDARG_LOWER) { - for (SStr chr = m_Buffer.Begin< SQChar >(); chr <= str; ++chr) - *chr = static_cast< SQChar >(tolower(*chr)); + break; // Propagate the failure! + } + // Swap the beginning and ending of the extracted string + end = str, str = m_Buffer.Begin(); + // Make sure the string is null terminated + *end = '\0'; + // Do we have to make the string lowercase? + if (arg_flags & CMDARG_LOWER) + { + for (CStr chr = str; chr < end; ++chr) + { + *chr = static_cast< SQChar >(std::tolower(*chr)); + } } // Do we have to make the string uppercase? else if (arg_flags & CMDARG_UPPER) { - for (SStr chr = m_Buffer.Begin< SQChar >(); chr <= str; ++chr) - *chr = static_cast< SQChar >(toupper(*chr)); + for (CStr chr = str; chr < end; ++chr) + { + *chr = static_cast< SQChar >(std::toupper(*chr)); + } + } + // Remember the current stack size + const StackGuard sg; + // Was the specified string empty? + if (str >= end) + { + // Just push an empty string + sq_pushstring(DefaultVM::Get(), _SC(""), 0); + } + // Add it to the argument list along with it's type + else + { + // Transform it into a script object + sq_pushstring(DefaultVM::Get(), str, end - str - 1); } - // Transform it into a script object - sq_pushstring(DefaultVM::Get(), m_Buffer.Get< SQChar >(), str - m_Buffer.Begin< SQChar >()); // Get the object from the stack and add it to the argument list along with it's type m_Argv.emplace_back(CMDARG_STRING, Var< Object >(DefaultVM::Get(), -1).value); - // Pop the created object from the stack - sq_pop(DefaultVM::Get(), 1); // Advance to the next argument and obtain its flags arg_flags = m_Instance->m_ArgSpec[++m_Argc]; } // Ignore white-space characters until another valid character is found - else if (!isspace(elem) && (isspace(prev) || prev == 0)) + else if (!std::isspace(elem) && (std::isspace(prev) || prev == '\0')) { // Find the first space character that marks the end of the argument - String::iterator pos = std::find(String::iterator(itr), m_Argument.end(), ' '); - // Copy all characters within range into the internal buffer - const Uint32 sz = m_Buffer.Write(0, &(*itr), std::distance(itr, pos)); + String::const_iterator pos = std::find_if(itr, m_Argument.cend(), IsCType(std::isspace)); + // Obtain both ends of the argument string + CCStr str = &(*itr), end = &(*pos); + // Compute the argument string size + const Uint32 sz = std::distance(itr, pos); // Update the main iterator position itr = pos; - // Update the current character + // Update the currently processed character elem = *itr; - // Make sure the argument string is null terminated - m_Buffer.At< SQChar >(sz) = 0; // Used to exclude all other checks when a valid type was identified bool identified = false; - // Attempt to treat the value as an integer number - if (!identified) + // Attempt to treat the value as an integer number if possible + if (!identified && (arg_flags & CMDARG_INTEGER)) { // Let's us know if the whole argument was part of the resulted value CStr next = nullptr; // Attempt to extract the integer value from the string - LongI value = strtol(m_Buffer.Data(), &next, 10); + const Int64 value = std::strtoll(str, &next, 10); // See if this whole string was indeed an integer - if (next == &m_Buffer.At< SQChar >(sz)) + if (next == end) { + // Remember the current stack size + const StackGuard sg; // Transform it into a script object - sq_pushinteger(DefaultVM::Get(), static_cast< SQInteger >(value)); + sq_pushinteger(DefaultVM::Get(), ConvTo< SQInteger >::From(value)); // Get the object from the stack and add it to the argument list along with it's type m_Argv.emplace_back(CMDARG_INTEGER, Var< Object >(DefaultVM::Get(), -1).value); - // Pop the created object from the stack - sq_pop(DefaultVM::Get(), 1); - // We identified the correct value - identified = true; + // We've identified the correct value type + identified = false; } } - // Attempt to treat the value as an floating point number - if (!identified) + // Attempt to treat the value as an floating point number if possible + if (!identified && (arg_flags & CMDARG_FLOAT)) { // Let's us know if the whole argument was part of the resulted value CStr next = nullptr; - // Attempt to extract the floating point value from the string + // Attempt to extract the integer value from the string #ifdef SQUSEDOUBLE - Float64 value = strtod(m_Buffer.Data(), &next); + const Float64 value = std::strtod(str, &next); #else - Float32 value = strtof(m_Buffer.Data(), &next); + const Float32 value = std::strtof(str, &next); #endif // SQUSEDOUBLE - // See if this whole string was indeed an floating point - if (next == &m_Buffer.At< SQChar >(sz)) + // See if this whole string was indeed an integer + if (next == end) { + // Remember the current stack size + const StackGuard sg; // Transform it into a script object - sq_pushfloat(DefaultVM::Get(), static_cast< SQFloat >(value)); + sq_pushfloat(DefaultVM::Get(), ConvTo< SQFloat >::From(value)); // Get the object from the stack and add it to the argument list along with it's type m_Argv.emplace_back(CMDARG_FLOAT, Var< Object >(DefaultVM::Get(), -1).value); - // Pop the created object from the stack - sq_pop(DefaultVM::Get(), 1); - // We identified the correct value - identified = true; + // We've identified the correct value type + identified = false; } + } // Attempt to treat the value as a boolean if possible - if (!identified && sz <= 6) + if (!identified && (arg_flags & CMDARG_BOOLEAN) && sz <= 5) { // Allocate memory for enough data to form a boolean value - SQChar lc[6]; + CharT lc[6]; // Fill the temporary buffer with data from the internal buffer - snprintf (lc, 6, "%.5s", m_Buffer.Data()); + std::snprintf(lc, 6, "%.5s", str); // Convert all characters to lowercase for (Uint32 i = 0; i < 5; ++i) - lc[i] = tolower(lc[i]); + { + lc[i] = std::tolower(lc[i]); + } + // Remember the current stack size + const StackGuard sg; // Is this a boolean true value? - if (strcmp(m_Buffer.Data(), "true") == 0 || strcmp(m_Buffer.Data(), "on") == 0) + if (std::strcmp(lc, "true") == 0 || std::strcmp(lc, "on") == 0) { // Transform it into a script object sq_pushbool(DefaultVM::Get(), true); - // Get the object from the stack and add it to the argument list along with it's type - m_Argv.emplace_back(CMDARG_BOOLEAN, Var< Object >(DefaultVM::Get(), -1).value); - // Pop the created object from the stack - sq_pop(DefaultVM::Get(), 1); - // We identified the correct value + // We've identified the correct value type identified = true; } // Is this a boolean false value? - else if (strcmp(m_Buffer.Data(), "false") == 0 || strcmp(m_Buffer.Data(), "off") == 0) + else if (std::strcmp(lc, "false") == 0 || std::strcmp(lc, "off") == 0) { // Transform it into a script object sq_pushbool(DefaultVM::Get(), false); + // We've identified the correct value type + identified = true; + } + // Could the value inside the string be interpreted as a boolean? + if (identified) + { // Get the object from the stack and add it to the argument list along with it's type m_Argv.emplace_back(CMDARG_BOOLEAN, Var< Object >(DefaultVM::Get(), -1).value); - // Pop the created object from the stack - sq_pop(DefaultVM::Get(), 1); - // We identified the correct value - identified = true; } } // If everything else failed then simply treat the value as a string if (!identified) { + // Remember the current stack size + const StackGuard sg; // Do we have to make the string lowercase? if (arg_flags & CMDARG_LOWER) { - for (Uint32 n = 0; n < sz; ++n) - m_Buffer.At< SQChar >(n) = static_cast< SQChar >(tolower(m_Buffer.At< SQChar >(n))); + // Convert all characters from the argument string into the buffer + for (CStr chr = m_Buffer.Data(); str < end; ++str, ++chr) + { + *chr = static_cast< CharT >(std::tolower(*str)); + } + // Transform it into a script object + sq_pushstring(DefaultVM::Get(), m_Buffer.Get< SQChar >(), sz); } // Do we have to make the string uppercase? else if (arg_flags & CMDARG_UPPER) { - for (Uint32 n = 0; n < sz; ++n) - m_Buffer.At< SQChar >(n) = static_cast< SQChar >(toupper(m_Buffer.At< SQChar >(n))); + // Convert all characters from the argument string into the buffer + for (CStr chr = m_Buffer.Data(); str < end; ++str, ++chr) + { + *chr = static_cast< CharT >(std::toupper(*str)); + } + // Transform it into a script object + sq_pushstring(DefaultVM::Get(), m_Buffer.Get< SQChar >(), sz); + } + else + { + // Transform it into a script object + sq_pushstring(DefaultVM::Get(), str, sz); } - // Transform it into a script object - sq_pushstring(DefaultVM::Get(), m_Buffer.Get< SQChar >(), sz); // Get the object from the stack and add it to the argument list along with it's type m_Argv.emplace_back(CMDARG_STRING, Var< Object >(DefaultVM::Get(), -1).value); - // Pop the created object from the stack - sq_pop(DefaultVM::Get(), 1); } // Advance to the next argument and obtain its flags arg_flags = m_Instance->m_ArgSpec[++m_Argc]; } // Is there anything left to parse? if (itr >= m_Argument.end()) + { break; + } // Advance to the next character ++itr; } @@ -887,7 +987,7 @@ CmdListener::CmdListener(CSStr name, CSStr spec, Array & tags, Uint8 min, Uint8 CmdListener::~CmdListener() { // Detach this command (shouldn't be necessary!) - _Cmd->Detach(this); + CmdManager::Get().Detach(this); // Release callbacks m_OnExec.ReleaseGently(); m_OnAuth.ReleaseGently(); @@ -899,11 +999,17 @@ CmdListener::~CmdListener() Int32 CmdListener::Cmp(const CmdListener & o) const { if (m_Name == o.m_Name) + { return 0; + } else if (m_Name.size() > o.m_Name.size()) + { return 1; + } else + { return -1; + } } // ------------------------------------------------------------------------------------------------ @@ -921,19 +1027,19 @@ void CmdListener::Attach() STHROWF("Invalid or empty command name"); } // Are we already attached? - else if (_Cmd->Attached(this)) + else if (CmdManager::Get().Attached(this)) { STHROWF("Command is already attached"); } // Attempt to attach this command - _Cmd->Attach(m_Name, this, false); + CmdManager::Get().Attach(m_Name, this, false); } // ------------------------------------------------------------------------------------------------ void CmdListener::Detach() { // Detach this command - _Cmd->Detach(this); + CmdManager::Get().Detach(this); } // ------------------------------------------------------------------------------------------------ @@ -956,14 +1062,14 @@ void CmdListener::SetName(CSStr name) // Validate the specified name ValidateName(name); // Is this command already attached to a name? - if (_Cmd->Attached(this)) + if (CmdManager::Get().Attached(this)) { // Detach from the current name if necessary - _Cmd->Detach(this); + CmdManager::Get().Detach(this); // Now it's safe to assign the new name m_Name.assign(name); // We know the new name is valid - _Cmd->Attach(m_Name, this, false); + CmdManager::Get().Attach(m_Name, this, false); } else { @@ -1029,7 +1135,7 @@ void CmdListener::SetArgTags(Array & tags) // ------------------------------------------------------------------------------------------------ bool CmdListener::Attached() const { - return _Cmd->Attached(this); + return CmdManager::Get().Attached(this); } // ------------------------------------------------------------------------------------------------ @@ -1401,22 +1507,22 @@ bool CmdListener::AuthCheckID(Int32 id) if (!m_OnAuth.IsNull()) { // Ask the specified authority inspector if this execution should be allowed - SharedPtr< bool > ret = m_OnAuth.Evaluate< bool, Object & >(_Core->GetPlayer(id).mObj); + SharedPtr< bool > ret = m_OnAuth.Evaluate< bool, Object & >(Core::Get().GetPlayer(id).mObj); // See what the custom authority inspector said or default to disallow allow = (!ret ? false : *ret); } // Was there a global authority inspector specified? - else if (!_Cmd->GetOnAuth().IsNull()) + else if (!CmdManager::Get().GetOnAuth().IsNull()) { // Ask the specified authority inspector if this execution should be allowed - SharedPtr< bool > ret = _Cmd->GetOnAuth().Evaluate< bool, Object & >(_Core->GetPlayer(id).mObj); + SharedPtr< bool > ret = CmdManager::Get().GetOnAuth().Evaluate< bool, Object & >(Core::Get().GetPlayer(id).mObj); // See what the custom authority inspector said or default to disallow allow = (!ret ? false : *ret); } // Can we use the default authority system? else if (m_Authority >= 0) { - allow = (_Core->GetPlayer(id).mAuthority >= m_Authority); + allow = (Core::Get().GetPlayer(id).mAuthority >= m_Authority); } // Return result return allow; @@ -1571,29 +1677,21 @@ void CmdListener::ProcSpec(CSStr str) /* ------------------------------------------------------------------------------------------------ * Forward the call to run a command. */ -Int32 RunCommand(Int32 invoker, CSStr command) +static Int32 Cmd_Run(Int32 invoker, CSStr command) { - return _Cmd->Run(invoker, command); -} - -/* ------------------------------------------------------------------------------------------------ - * Forward the call to terminate the command system. -*/ -void TerminateCommand() -{ - _Cmd->Terminate(); + return CmdManager::Get().Run(invoker, command); } // ------------------------------------------------------------------------------------------------ static void Cmd_Sort() { - _Cmd->Sort(); + CmdManager::Get().Sort(); } // ------------------------------------------------------------------------------------------------ static Uint32 Cmd_Count() { - return _Cmd->Count(); + return CmdManager::Get().Count(); } // ------------------------------------------------------------------------------------------------ @@ -1602,87 +1700,87 @@ static const Object & Cmd_FindByName(CSStr name) // Validate the specified name ValidateName(name); // Now perform the requested search - return _Cmd->FindByName(name); + return CmdManager::Get().FindByName(name); } // ------------------------------------------------------------------------------------------------ -static Function & Cmd_GetOnError() +static Function & Cmd_GetOnFail() { - return _Cmd->GetOnError(); + return CmdManager::Get().GetOnFail(); } // ------------------------------------------------------------------------------------------------ -static void Cmd_SetOnError(Object & env, Function & func) +static void Cmd_SetOnFail(Object & env, Function & func) { - _Cmd->SetOnError(env, func); + CmdManager::Get().SetOnFail(env, func); } // ------------------------------------------------------------------------------------------------ static Function & Cmd_GetOnAuth() { - return _Cmd->GetOnAuth(); + return CmdManager::Get().GetOnAuth(); } // ------------------------------------------------------------------------------------------------ static void Cmd_SetOnAuth(Object & env, Function & func) { - _Cmd->SetOnAuth(env, func); + CmdManager::Get().SetOnAuth(env, func); } // ------------------------------------------------------------------------------------------------ static Object & Cmd_GetInvoker() { - return _Core->GetPlayer(_Cmd->GetInvoker()).mObj; + return Core::Get().GetPlayer(CmdManager::Get().GetInvoker()).mObj; } // ------------------------------------------------------------------------------------------------ static Int32 Cmd_GetInvokerID() { - return _Cmd->GetInvoker(); + return CmdManager::Get().GetInvoker(); } // ------------------------------------------------------------------------------------------------ static const Object & Cmd_GetObject() { - return _Cmd->GetObject(); + return CmdManager::Get().GetObject(); } // ------------------------------------------------------------------------------------------------ static const String & Cmd_GetCommand() { - return _Cmd->GetCommand(); + return CmdManager::Get().GetCommand(); } // ------------------------------------------------------------------------------------------------ static const String & Cmd_GetArgument() { - return _Cmd->GetArgument(); + return CmdManager::Get().GetArgument(); } // ------------------------------------------------------------------------------------------------ Object & Cmd_Create(CSStr name) { - return _Cmd->Create(name); + return CmdManager::Get().Create(name); } Object & Cmd_Create(CSStr name, CSStr spec) { - return _Cmd->Create(name, spec); + return CmdManager::Get().Create(name, spec); } Object & Cmd_Create(CSStr name, CSStr spec, Array & tags) { - return _Cmd->Create(name, spec, tags); + return CmdManager::Get().Create(name, spec, tags); } Object & Cmd_Create(CSStr name, CSStr spec, Uint8 min, Uint8 max) { - return _Cmd->Create(name,spec, min, max); + return CmdManager::Get().Create(name,spec, min, max); } Object & Cmd_Create(CSStr name, CSStr spec, Array & tags, Uint8 min, Uint8 max) { - return _Cmd->Create(name, spec, tags, min, max); + return CmdManager::Get().Create(name, spec, tags, min, max); } // ================================================================================================ @@ -1691,11 +1789,11 @@ void Register_Command(HSQUIRRELVM vm) Table cmdns(vm); cmdns.Bind(_SC("Listener"), Class< CmdListener, NoConstructor< CmdListener > >(vm, _SC("SqCmdListener")) - /* Metamethods */ + // Metamethods .Func(_SC("_cmp"), &CmdListener::Cmp) .SquirrelFunc(_SC("_typename"), &CmdListener::Typename) .Func(_SC("_tostring"), &CmdListener::ToString) - /* Properties */ + // Member Properties .Prop(_SC("Attached"), &CmdListener::Attached) .Prop(_SC("Name"), &CmdListener::GetName, &CmdListener::SetName) .Prop(_SC("Spec"), &CmdListener::GetSpec, &CmdListener::SetSpec) @@ -1713,7 +1811,7 @@ void Register_Command(HSQUIRRELVM vm) .Prop(_SC("OnAuth"), &CmdListener::GetOnAuth) .Prop(_SC("OnPost"), &CmdListener::GetOnPost) .Prop(_SC("OnFail"), &CmdListener::GetOnFail) - /* Functions */ + // Member Methods .Func(_SC("Attach"), &CmdListener::Attach) .Func(_SC("Detach"), &CmdListener::Detach) .Func(_SC("BindExec"), &CmdListener::SetOnExec) @@ -1728,12 +1826,13 @@ void Register_Command(HSQUIRRELVM vm) .Func(_SC("AuthCheckID"), &CmdListener::AuthCheckID) ); + cmdns.Func(_SC("Run"), &Cmd_Run); cmdns.Func(_SC("Sort"), &Cmd_Sort); cmdns.Func(_SC("Count"), &Cmd_Count); cmdns.Func(_SC("FindByName"), &Cmd_FindByName); - cmdns.Func(_SC("GetOnError"), &Cmd_GetOnError); - cmdns.Func(_SC("SetOnError"), &Cmd_SetOnError); - cmdns.Func(_SC("BindError"), &Cmd_SetOnError); + cmdns.Func(_SC("GetOnFail"), &Cmd_GetOnFail); + cmdns.Func(_SC("SetOnFail"), &Cmd_SetOnFail); + cmdns.Func(_SC("BindFail"), &Cmd_SetOnFail); cmdns.Func(_SC("GetOnAuth"), &Cmd_GetOnAuth); cmdns.Func(_SC("SetOnAuth"), &Cmd_SetOnAuth); cmdns.Func(_SC("BindAuth"), &Cmd_SetOnAuth); diff --git a/source/Command.hpp b/source/Command.hpp index 4d745fea..cdc30b8a 100644 --- a/source/Command.hpp +++ b/source/Command.hpp @@ -15,14 +15,6 @@ namespace SqMod { // ------------------------------------------------------------------------------------------------ class CmdListener; -/* ------------------------------------------------------------------------------------------------ - * Converts a command specifier to a string. -*/ -CSStr CmdArgSpecToStr(Uint8 spec); - -// ------------------------------------------------------------------------------------------------ -extern SQMOD_MANAGEDPTR_TYPE(CmdManager) _Cmd; - /* ------------------------------------------------------------------------------------------------ * Manages command instances and processes executed commands. */ @@ -33,6 +25,50 @@ class CmdManager private: + // -------------------------------------------------------------------------------------------- + static CmdManager s_Inst; // Command manager instance. + +private: + + /* -------------------------------------------------------------------------------------------- + * Helper class implementing RAII to release the command object and instance. + */ + struct Guard + { + /* ---------------------------------------------------------------------------------------- + * Default constructor. + */ + Guard() = default; + + /* ---------------------------------------------------------------------------------------- + * Copy constructor. + */ + Guard(const Guard & o) = delete; + + /* ---------------------------------------------------------------------------------------- + * Move constructor. + */ + Guard(Guard && o) = delete; + + /* ---------------------------------------------------------------------------------------- + * Destructor. + */ + ~Guard(); + + /* ---------------------------------------------------------------------------------------- + * Copy assignment operator. + */ + Guard & operator = (const Guard & o) = delete; + + /* ---------------------------------------------------------------------------------------- + * Move assignment operator. + */ + Guard & operator = (Guard && o) = delete; + }; + + // -------------------------------------------------------------------------------------------- + friend class Guard; // Allow the guard to access the member it's supposed to release. + /* -------------------------------------------------------------------------------------------- * Structure that represents a unique command in the pool. */ @@ -95,59 +131,28 @@ private: typedef std::pair< Uint8, Object > CmdArg; typedef std::vector< CmdArg > CmdArgs; - /* -------------------------------------------------------------------------------------------- - * Helper class implementing RAII to release the command object and instance. - */ - struct Guard - { - /* ---------------------------------------------------------------------------------------- - * Default constructor. - */ - Guard() = default; - - /* ---------------------------------------------------------------------------------------- - * Copy constructor. - */ - Guard(const Guard & o) = delete; - - /* ---------------------------------------------------------------------------------------- - * Move constructor. - */ - Guard(Guard && o) = delete; - - /* ---------------------------------------------------------------------------------------- - * Destructor. - */ - ~Guard(); - - /* ---------------------------------------------------------------------------------------- - * Copy assignment operator. - */ - Guard & operator = (const Guard & o) = delete; - - /* ---------------------------------------------------------------------------------------- - * Move assignment operator. - */ - Guard & operator = (Guard && o) = delete; - }; +private: // -------------------------------------------------------------------------------------------- - friend class Guard; + Buffer m_Buffer; // Shared buffer used to extract arguments. + CmdList m_Commands; // List of available command instances. - /* -------------------------------------------------------------------------------------------- - * Default constructor. - */ - CmdManager(); + // -------------------------------------------------------------------------------------------- + Int32 m_Invoker; // The identifier of the last player that invoked a command. + String m_Command; // The extracted command name. + String m_Argument; // The extracted command argument. + CmdListener* m_Instance; // Pointer to the currently executed command. + Object m_Object; // Script object of the currently exectued command. - /* -------------------------------------------------------------------------------------------- - * Copy constructor. (disabled) - */ - CmdManager(const CmdManager &); + // -------------------------------------------------------------------------------------------- + CmdArgs m_Argv; // Extracted command arguments. + Uint32 m_Argc; // Extracted arguments count. - /* -------------------------------------------------------------------------------------------- - * Copy assignment operator. (disabled) - */ - CmdManager & operator = (const CmdManager &); + // -------------------------------------------------------------------------------------------- + Function m_OnFail; // Callback when something failed while running a command. + Function m_OnAuth; // Callback if an invoker failed to authenticate properly. + +protected: /* -------------------------------------------------------------------------------------------- * Attach a command listener to a certain name. @@ -174,7 +179,42 @@ private: */ bool Attached(const CmdListener * ptr) const; -public: + /* -------------------------------------------------------------------------------------------- + * Forward error message to the error callback. + */ + template < typename T > void SqError(Int32 type, CSStr msg, T data) + { + // Is there a callback that deals with errors? + if (m_OnFail.IsNull()) + return; + // Attempt to forward the error to that callback + try + { + m_OnFail.Execute< Int32, CSStr, T >(type, msg, data); + } + catch (const Sqrat::Exception & e) + { + // We can only log this incident and in the future maybe also include the location + LogErr("Command error callback failed [%s]", e.Message().c_str()); + } + } + +private: + + /* -------------------------------------------------------------------------------------------- + * Default constructor. + */ + CmdManager(); + + /* -------------------------------------------------------------------------------------------- + * Copy constructor. (disabled) + */ + CmdManager(const CmdManager & o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Move constructor. (disabled) + */ + CmdManager(CmdManager && o) = delete; /* -------------------------------------------------------------------------------------------- * Destructor. @@ -182,18 +222,35 @@ public: ~CmdManager(); /* -------------------------------------------------------------------------------------------- - * Singleton retriever. + * Copy assignment operator. (disabled) */ - static CmdManager * Get() - { - if (!_Cmd) - { - _Cmd = SQMOD_MANAGEDPTR_MAKE(CmdManager, new CmdManager()); - } + CmdManager & operator = (const CmdManager & o) = delete; - return SQMOD_MANAGEDPTR_GET(_Cmd); + /* -------------------------------------------------------------------------------------------- + * Move assignment operator. (disabled) + */ + CmdManager & operator = (CmdManager && o) = delete; + +public: + + /* -------------------------------------------------------------------------------------------- + * Retrieve the command manager instance. + */ + static CmdManager & Get() + { + return s_Inst; } + /* -------------------------------------------------------------------------------------------- + * Initialize the command manager instance. + */ + void Initialize(); + + /* -------------------------------------------------------------------------------------------- + * Terminate the command manager instance. + */ + void Deinitialize(); + /* -------------------------------------------------------------------------------------------- * Sort the command list in an ascending order. */ @@ -212,25 +269,20 @@ public: */ const Object & FindByName(const String & name); - /* -------------------------------------------------------------------------------------------- - * Terminate current session. - */ - void Terminate(); - /* -------------------------------------------------------------------------------------------- * Retrieve the error callback. */ - Function & GetOnError() + Function & GetOnFail() { - return m_OnError; + return m_OnFail; } /* -------------------------------------------------------------------------------------------- * Modify the error callback. */ - void SetOnError(Object & env, Function & func) + void SetOnFail(Object & env, Function & func) { - m_OnError = Function(env.GetVM(), env, func.GetFunc()); + m_OnFail = Function(env.GetVM(), env, func.GetFunc()); } /* -------------------------------------------------------------------------------------------- @@ -296,28 +348,6 @@ public: protected: - // -------------------------------------------------------------------------------------------- - - /* -------------------------------------------------------------------------------------------- - * Forward error message to the error callback. - */ - template < typename T > void SqError(Int32 type, CSStr msg, T data) - { - // Is there a callback that deals with errors? - if (m_OnError.IsNull()) - return; - // Attempt to forward the error to that callback - try - { - m_OnError.Execute< Int32, CSStr, T >(type, msg, data); - } - catch (const Sqrat::Exception & e) - { - // We can only log this incident and in the future maybe also include the location - LogErr("Command error callback failed [%s]", e.Message().c_str()); - } - } - /* -------------------------------------------------------------------------------------------- * Attempt to execute the specified command. */ @@ -328,27 +358,6 @@ protected: */ bool Parse(); -private: - - // -------------------------------------------------------------------------------------------- - Buffer m_Buffer; // Internal buffer used for parsing commands. - CmdList m_Commands; // List of created commands. - - // -------------------------------------------------------------------------------------------- - Int32 m_Invoker; // Current command invoker. - String m_Command; // Current command name. - String m_Argument; // Current command argument. - CmdListener* m_Instance; // Current command instance. - Object m_Object; // Current command script object. - - // -------------------------------------------------------------------------------------------- - CmdArgs m_Argv; // Extracted command arguments. - Uint32 m_Argc; // Extracted arguments count. - - // -------------------------------------------------------------------------------------------- - Function m_OnError; // Error handler. - Function m_OnAuth; // Authentication handler. - public: /* -------------------------------------------------------------------------------------------- @@ -663,6 +672,11 @@ private: bool m_Associate; }; +/* ------------------------------------------------------------------------------------------------ + * Converts a command specifier to a string. +*/ +CSStr CmdArgSpecToStr(Uint8 spec); + } // Namespace:: SqMod #endif // _COMMAND_HPP_ diff --git a/source/Constants.cpp b/source/Constants.cpp index 7b1b1abf..21727e52 100644 --- a/source/Constants.cpp +++ b/source/Constants.cpp @@ -26,8 +26,8 @@ void Register_Constants(HSQUIRRELVM vm) .Const(_SC("MaxByte"), std::numeric_limits< Uint8 >::max()) .Const(_SC("MinShort"), std::numeric_limits< Int16 >::min()) .Const(_SC("MaxShort"), std::numeric_limits< Int16 >::max()) - .Const(_SC("MinUshort"), std::numeric_limits< Uint16 >::min()) - .Const(_SC("MaxUshort"), std::numeric_limits< Uint16 >::max()) + .Const(_SC("MinWord"), std::numeric_limits< Uint16 >::min()) + .Const(_SC("MaxWord"), std::numeric_limits< Uint16 >::max()) .Const(_SC("MinInt"), std::numeric_limits< SQInteger >::min()) .Const(_SC("MaxInt"), std::numeric_limits< SQInteger >::max()) .Const(_SC("MinInteger"), std::numeric_limits< SQInteger >::min()) @@ -70,75 +70,58 @@ void Register_Constants(HSQUIRRELVM vm) ConstTable(vm).Enum(_SC("SqEvent"), Enumeration(vm) .Const(_SC("Unknown"), EVT_UNKNOWN) + .Const(_SC("CustomEvent"), EVT_CUSTOMEVENT) .Const(_SC("BlipCreated"), EVT_BLIPCREATED) .Const(_SC("CheckpointCreated"), EVT_CHECKPOINTCREATED) - .Const(_SC("ForcefieldCreated"), EVT_FORCEFIELDCREATED) .Const(_SC("KeybindCreated"), EVT_KEYBINDCREATED) .Const(_SC("ObjectCreated"), EVT_OBJECTCREATED) .Const(_SC("PickupCreated"), EVT_PICKUPCREATED) .Const(_SC("PlayerCreated"), EVT_PLAYERCREATED) - .Const(_SC("SpriteCreated"), EVT_SPRITECREATED) - .Const(_SC("TextdrawCreated"), EVT_TEXTDRAWCREATED) .Const(_SC("VehicleCreated"), EVT_VEHICLECREATED) .Const(_SC("BlipDestroyed"), EVT_BLIPDESTROYED) .Const(_SC("CheckpointDestroyed"), EVT_CHECKPOINTDESTROYED) - .Const(_SC("ForcefieldDestroyed"), EVT_FORCEFIELDDESTROYED) .Const(_SC("KeybindDestroyed"), EVT_KEYBINDDESTROYED) .Const(_SC("ObjectDestroyed"), EVT_OBJECTDESTROYED) .Const(_SC("PickupDestroyed"), EVT_PICKUPDESTROYED) .Const(_SC("PlayerDestroyed"), EVT_PLAYERDESTROYED) - .Const(_SC("SpriteDestroyed"), EVT_SPRITEDESTROYED) - .Const(_SC("TextdrawDestroyed"), EVT_TEXTDRAWDESTROYED) .Const(_SC("VehicleDestroyed"), EVT_VEHICLEDESTROYED) .Const(_SC("BlipCustom"), EVT_BLIPCUSTOM) .Const(_SC("CheckpointCustom"), EVT_CHECKPOINTCUSTOM) - .Const(_SC("ForcefieldCustom"), EVT_FORCEFIELDCUSTOM) .Const(_SC("KeybindCustom"), EVT_KEYBINDCUSTOM) .Const(_SC("ObjectCustom"), EVT_OBJECTCUSTOM) .Const(_SC("PickupCustom"), EVT_PICKUPCUSTOM) .Const(_SC("PlayerCustom"), EVT_PLAYERCUSTOM) - .Const(_SC("SpriteCustom"), EVT_SPRITECUSTOM) - .Const(_SC("TextdrawCustom"), EVT_TEXTDRAWCUSTOM) .Const(_SC("VehicleCustom"), EVT_VEHICLECUSTOM) - .Const(_SC("PlayerAway"), EVT_PLAYERAWAY) - .Const(_SC("PlayerGameKeys"), EVT_PLAYERGAMEKEYS) - .Const(_SC("PlayerRename"), EVT_PLAYERRENAME) + .Const(_SC("ServerStartup"), EVT_SERVERSTARTUP) + .Const(_SC("ServerShutdown"), EVT_SERVERSHUTDOWN) + .Const(_SC("ServerFrame"), EVT_SERVERFRAME) + .Const(_SC("IncomingConnection"), EVT_INCOMINGCONNECTION) .Const(_SC("PlayerRequestClass"), EVT_PLAYERREQUESTCLASS) .Const(_SC("PlayerRequestSpawn"), EVT_PLAYERREQUESTSPAWN) .Const(_SC("PlayerSpawn"), EVT_PLAYERSPAWN) - .Const(_SC("PlayerStartTyping"), EVT_PLAYERSTARTTYPING) - .Const(_SC("PlayerStopTyping"), EVT_PLAYERSTOPTYPING) - .Const(_SC("PlayerChat"), EVT_PLAYERCHAT) - .Const(_SC("PlayerCommand"), EVT_PLAYERCOMMAND) - .Const(_SC("PlayerMessage"), EVT_PLAYERMESSAGE) - .Const(_SC("PlayerHealth"), EVT_PLAYERHEALTH) - .Const(_SC("PlayerArmour"), EVT_PLAYERARMOUR) - .Const(_SC("PlayerWeapon"), EVT_PLAYERWEAPON) - .Const(_SC("PlayerMove"), EVT_PLAYERMOVE) .Const(_SC("PlayerWasted"), EVT_PLAYERWASTED) .Const(_SC("PlayerKilled"), EVT_PLAYERKILLED) - .Const(_SC("PlayerTeamKill"), EVT_PLAYERTEAMKILL) - .Const(_SC("PlayerSpectate"), EVT_PLAYERSPECTATE) - .Const(_SC("PlayerCrashReport"), EVT_PLAYERCRASHREPORT) - .Const(_SC("PlayerBurning"), EVT_PLAYERBURNING) - .Const(_SC("PlayerCrouching"), EVT_PLAYERCROUCHING) + .Const(_SC("PlayerEmbarking"), EVT_PLAYEREMBARKING) + .Const(_SC("PlayerEmbarked"), EVT_PLAYEREMBARKED) + .Const(_SC("PlayerDisembark"), EVT_PLAYERDISEMBARK) + .Const(_SC("PlayerRename"), EVT_PLAYERRENAME) .Const(_SC("PlayerState"), EVT_PLAYERSTATE) - .Const(_SC("PlayerAction"), EVT_PLAYERACTION) .Const(_SC("StateNone"), EVT_STATENONE) .Const(_SC("StateNormal"), EVT_STATENORMAL) - .Const(_SC("StateShooting"), EVT_STATESHOOTING) + .Const(_SC("StateAim"), EVT_STATEAIM) .Const(_SC("StateDriver"), EVT_STATEDRIVER) .Const(_SC("StatePassenger"), EVT_STATEPASSENGER) .Const(_SC("StateEnterDriver"), EVT_STATEENTERDRIVER) .Const(_SC("StateEnterPassenger"), EVT_STATEENTERPASSENGER) - .Const(_SC("StateExitVehicle"), EVT_STATEEXITVEHICLE) + .Const(_SC("StateExit"), EVT_STATEEXIT) .Const(_SC("StateUnspawned"), EVT_STATEUNSPAWNED) + .Const(_SC("PlayerAction"), EVT_PLAYERACTION) .Const(_SC("ActionNone"), EVT_ACTIONNONE) .Const(_SC("ActionNormal"), EVT_ACTIONNORMAL) .Const(_SC("ActionAiming"), EVT_ACTIONAIMING) .Const(_SC("ActionShooting"), EVT_ACTIONSHOOTING) .Const(_SC("ActionJumping"), EVT_ACTIONJUMPING) - .Const(_SC("ActionLiedown"), EVT_ACTIONLIEDOWN) + .Const(_SC("ActionLieDown"), EVT_ACTIONLIEDOWN) .Const(_SC("ActionGettingUp"), EVT_ACTIONGETTINGUP) .Const(_SC("ActionJumpVehicle"), EVT_ACTIONJUMPVEHICLE) .Const(_SC("ActionDriving"), EVT_ACTIONDRIVING) @@ -146,32 +129,44 @@ void Register_Constants(HSQUIRRELVM vm) .Const(_SC("ActionWasted"), EVT_ACTIONWASTED) .Const(_SC("ActionEmbarking"), EVT_ACTIONEMBARKING) .Const(_SC("ActionDisembarking"), EVT_ACTIONDISEMBARKING) - .Const(_SC("VehicleRespawn"), EVT_VEHICLERESPAWN) + .Const(_SC("PlayerBurning"), EVT_PLAYERBURNING) + .Const(_SC("PlayerCrouching"), EVT_PLAYERCROUCHING) + .Const(_SC("PlayerGameKeys"), EVT_PLAYERGAMEKEYS) + .Const(_SC("PlayerStartTyping"), EVT_PLAYERSTARTTYPING) + .Const(_SC("PlayerStopTyping"), EVT_PLAYERSTOPTYPING) + .Const(_SC("PlayerAway"), EVT_PLAYERAWAY) + .Const(_SC("PlayerMessage"), EVT_PLAYERMESSAGE) + .Const(_SC("PlayerCommand"), EVT_PLAYERCOMMAND) + .Const(_SC("PlayerPrivateMessage"), EVT_PLAYERPRIVATEMESSAGE) + .Const(_SC("PlayerKeyPress"), EVT_PLAYERKEYPRESS) + .Const(_SC("PlayerKeyRelease"), EVT_PLAYERKEYRELEASE) + .Const(_SC("PlayerSpectate"), EVT_PLAYERSPECTATE) + .Const(_SC("PlayerCrashReport"), EVT_PLAYERCRASHREPORT) .Const(_SC("VehicleExplode"), EVT_VEHICLEEXPLODE) - .Const(_SC("VehicleHealth"), EVT_VEHICLEHEALTH) - .Const(_SC("VehicleMove"), EVT_VEHICLEMOVE) - .Const(_SC("PickupRespawn"), EVT_PICKUPRESPAWN) - .Const(_SC("KeybindKeyPress"), EVT_KEYBINDKEYPRESS) - .Const(_SC("KeybindKeyRelease"), EVT_KEYBINDKEYRELEASE) - .Const(_SC("VehicleEmbarking"), EVT_VEHICLEEMBARKING) - .Const(_SC("VehicleEmbarked"), EVT_VEHICLEEMBARKED) - .Const(_SC("VehicleDisembark"), EVT_VEHICLEDISEMBARK) + .Const(_SC("VehicleRespawn"), EVT_VEHICLERESPAWN) + .Const(_SC("ObjectShot"), EVT_OBJECTSHOT) + .Const(_SC("ObjectTouched"), EVT_OBJECTTOUCHED) .Const(_SC("PickupClaimed"), EVT_PICKUPCLAIMED) .Const(_SC("PickupCollected"), EVT_PICKUPCOLLECTED) - .Const(_SC("ObjectShot"), EVT_OBJECTSHOT) - .Const(_SC("ObjectBump"), EVT_OBJECTBUMP) + .Const(_SC("PickupRespawn"), EVT_PICKUPRESPAWN) .Const(_SC("CheckpointEntered"), EVT_CHECKPOINTENTERED) .Const(_SC("CheckpointExited"), EVT_CHECKPOINTEXITED) - .Const(_SC("ForcefieldEntered"), EVT_FORCEFIELDENTERED) - .Const(_SC("ForcefieldExited"), EVT_FORCEFIELDEXITED) - .Const(_SC("ServerFrame"), EVT_SERVERFRAME) - .Const(_SC("ServerStartup"), EVT_SERVERSTARTUP) - .Const(_SC("ServerShutdown"), EVT_SERVERSHUTDOWN) - .Const(_SC("InternalCommand"), EVT_INTERNALCOMMAND) - .Const(_SC("LoginAttempt"), EVT_LOGINATTEMPT) - .Const(_SC("CustomEvent"), EVT_CUSTOMEVENT) - .Const(_SC("WorldOption"), EVT_WORLDOPTION) - .Const(_SC("WorldToggle"), EVT_WORLDTOGGLE) + .Const(_SC("EntityPool"), EVT_ENTITYPOOL) + .Const(_SC("ClientScriptData"), EVT_CLIENTSCRIPTDATA) + .Const(_SC("PlayerUpdate"), EVT_PLAYERUPDATE) + .Const(_SC("VehicleUpdate"), EVT_VEHICLEUPDATE) + .Const(_SC("PlayerHealth"), EVT_PLAYERHEALTH) + .Const(_SC("PlayerArmour"), EVT_PLAYERARMOUR) + .Const(_SC("PlayerWeapon"), EVT_PLAYERWEAPON) + .Const(_SC("PlayerHeading"), EVT_PLAYERHEADING) + .Const(_SC("PlayerPosition"), EVT_PLAYERPOSITION) + .Const(_SC("PlayerOption"), EVT_PLAYEROPTION) + .Const(_SC("VehicleColour"), EVT_VEHICLECOLOUR) + .Const(_SC("VehicleHealth"), EVT_VEHICLEHEALTH) + .Const(_SC("VehiclePosition"), EVT_VEHICLEPOSITION) + .Const(_SC("VehicleRotation"), EVT_VEHICLEROTATION) + .Const(_SC("VehicleOption"), EVT_VEHICLEOPTION) + .Const(_SC("ServerOption"), EVT_SERVEROPTION) .Const(_SC("ScriptReload"), EVT_SCRIPTRELOAD) .Const(_SC("ScriptLoaded"), EVT_SCRIPTLOADED) .Const(_SC("Max"), EVT_MAX) @@ -195,71 +190,76 @@ void Register_Constants(HSQUIRRELVM vm) .Const(_SC("Cleanup"), SQMOD_DESTROY_CLEANUP) ); - ConstTable(vm).Enum(_SC("SqPoopUpdate"), Enumeration(vm) + ConstTable(vm).Enum(_SC("SqPoolUpdate"), Enumeration(vm) .Const(_SC("Unknown"), SQMOD_UNKNOWN) - .Const(_SC("Vehicle"), SQMOD_ENTITY_POOL_VEHICLE) - .Const(_SC("Object"), SQMOD_ENTITY_POOL_OBJECT) - .Const(_SC("Pickup"), SQMOD_ENTITY_POOL_PICKUP) - .Const(_SC("Radio"), SQMOD_ENTITY_POOL_RADIO) - .Const(_SC("Sprite"), SQMOD_ENTITY_POOL_SPRITE) - .Const(_SC("Textdraw"), SQMOD_ENTITY_POOL_TEXTDRAW) - .Const(_SC("Blip"), SQMOD_ENTITY_POOL_BLIP) - .Const(_SC("Max"), SQMOD_ENTITY_POOL_MAX) + .Const(_SC("Vehicle"), vcmpEntityPoolVehicle) + .Const(_SC("Object"), vcmpEntityPoolObject) + .Const(_SC("Pickup"), vcmpEntityPoolPickup) + .Const(_SC("Radio"), vcmpEntityPoolRadio) + .Const(_SC("Blip"), vcmpEntityPoolBlip) + .Const(_SC("Checkpoint"), vcmpEntityPoolCheckPoint) + .Const(_SC("Max"), vcmpEntityPoolCheckPoint) ); ConstTable(vm).Enum(_SC("SqVehicleUpd"), Enumeration(vm) .Const(_SC("Unknown"), SQMOD_UNKNOWN) - .Const(_SC("Driver"), SQMOD_VEHICLEUPD_DRIVER) - .Const(_SC("Other"), SQMOD_VEHICLEUPD_OTHER) - .Const(_SC("Max"), SQMOD_VEHICLEUPD_MAX) + .Const(_SC("DriverSync"), vcmpVehicleUpdateDriverSync) + .Const(_SC("OtherSync"), vcmpVehicleUpdateOtherSync) + .Const(_SC("Position"), vcmpVehicleUpdatePosition) + .Const(_SC("Health"), vcmpVehicleUpdateHealth) + .Const(_SC("Colour"), vcmpVehicleUpdateColour) + .Const(_SC("Rotation"), vcmpVehicleUpdateRotation) + .Const(_SC("Max"), vcmpVehicleUpdateRotation) ); ConstTable(vm).Enum(_SC("SqPlayerUpd"), Enumeration(vm) .Const(_SC("Unknown"), SQMOD_UNKNOWN) - .Const(_SC("OnFoot"), SQMOD_PLAYERUPD_ONFOOT) - .Const(_SC("Aim"), SQMOD_PLAYERUPD_AIM) - .Const(_SC("Driver"), SQMOD_PLAYERUPD_DRIVER) - .Const(_SC("Passenger"), SQMOD_PLAYERUPD_PASSENGER) - .Const(_SC("Max"), SQMOD_PLAYERUPD_MAX) + .Const(_SC("Normal"), vcmpPlayerUpdateNormal) + .Const(_SC("Aiming"), vcmpPlayerUpdateAiming) + .Const(_SC("Driver"), vcmpPlayerUpdateDriver) + .Const(_SC("Passenger"), vcmpPlayerUpdatePassenger) + .Const(_SC("Max"), vcmpPlayerUpdatePassenger) ); ConstTable(vm).Enum(_SC("SqPartReason"), Enumeration(vm) .Const(_SC("Unknown"), SQMOD_UNKNOWN) - .Const(_SC("Timeout"), SQMOD_PARTREASON_TIMEOUT) - .Const(_SC("Disconnected"), SQMOD_PARTREASON_DISCONNECTED) - .Const(_SC("KickedBanned"), SQMOD_PARTREASON_KICKEDBANNED) - .Const(_SC("Crashed"), SQMOD_PARTREASON_CRASHED) - .Const(_SC("Max"), SQMOD_PARTREASON_MAX) + .Const(_SC("Timeout"), vcmpDisconnectReasonTimeout) + .Const(_SC("Quit"), vcmpDisconnectReasonQuit) + .Const(_SC("Kick"), vcmpDisconnectReasonKick) + .Const(_SC("Crash"), vcmpDisconnectReasonCrash) + .Const(_SC("AntiCheat"), vcmpDisconnectReasonAntiCheat) + .Const(_SC("Max"), vcmpDisconnectReasonAntiCheat) ); ConstTable(vm).Enum(_SC("SqBodypart"), Enumeration(vm) .Const(_SC("Unknown"), SQMOD_UNKNOWN) - .Const(_SC("Body"), SQMOD_BODYPART_BODY) - .Const(_SC("Torso"), SQMOD_BODYPART_TORSO) - .Const(_SC("LeftArm"), SQMOD_BODYPART_LEFTARM) - .Const(_SC("LArm"), SQMOD_BODYPART_LEFTARM) - .Const(_SC("RightArm"), SQMOD_BODYPART_RIGHTARM) - .Const(_SC("RArm"), SQMOD_BODYPART_RIGHTARM) - .Const(_SC("LeftLeg"), SQMOD_BODYPART_LEFTLEG) - .Const(_SC("LLeg"), SQMOD_BODYPART_LEFTLEG) - .Const(_SC("RightLeg"), SQMOD_BODYPART_RIGHTLEG) - .Const(_SC("RLeg"), SQMOD_BODYPART_RIGHTLEG) - .Const(_SC("Head"), SQMOD_BODYPART_HEAD) - .Const(_SC("Max"), SQMOD_BODYPART_MAX) + .Const(_SC("Body"), vcmpBodyPartBody) + .Const(_SC("Torso"), vcmpBodyPartTorso) + .Const(_SC("LeftArm"), vcmpBodyPartLeftArm) + .Const(_SC("RightArm"), vcmpBodyPartRightArm) + .Const(_SC("LeftLeg"), vcmpBodyPartLeftLeg) + .Const(_SC("RightLeg"), vcmpBodyPartRightLeg) + .Const(_SC("Head"), vcmpBodyPartHead) + .Const(_SC("LArm"), vcmpBodyPartLeftArm) + .Const(_SC("RArm"), vcmpBodyPartRightArm) + .Const(_SC("LLeg"), vcmpBodyPartLeftLeg) + .Const(_SC("RLeg"), vcmpBodyPartRightLeg) + .Const(_SC("InVehicle"), vcmpBodyPartInVehicle) + .Const(_SC("Max"), vcmpBodyPartInVehicle) ); ConstTable(vm).Enum(_SC("SqPlayerState"), Enumeration(vm) .Const(_SC("Unknown"), SQMOD_UNKNOWN) - .Const(_SC("None"), SQMOD_PLAYER_STATE_NONE) - .Const(_SC("Normal"), SQMOD_PLAYER_STATE_NORMAL) - .Const(_SC("Shooting"), SQMOD_PLAYER_STATE_SHOOTING) - .Const(_SC("Driver"), SQMOD_PLAYER_STATE_DRIVER) - .Const(_SC("Passenger"), SQMOD_PLAYER_STATE_PASSENGER) - .Const(_SC("EnteringAsDriver"), SQMOD_PLAYER_STATE_ENTERING_AS_DRIVER) - .Const(_SC("EnteringAsPassenger"), SQMOD_PLAYER_STATE_ENTERING_AS_PASSENGER) - .Const(_SC("ExitingVehicle"), SQMOD_PLAYER_STATE_EXITING_VEHICLE) - .Const(_SC("Unspawned"), SQMOD_PLAYER_STATE_UNSPAWNED) - .Const(_SC("Max"), SQMOD_PLAYER_STATE_MAX) + .Const(_SC("None"), vcmpPlayerStateNone) + .Const(_SC("Normal"), vcmpPlayerStateNormal) + .Const(_SC("Aim"), vcmpPlayerStateAim) + .Const(_SC("Driver"), vcmpPlayerStateDriver) + .Const(_SC("Passenger"), vcmpPlayerStatePassenger) + .Const(_SC("EnterDriver"), vcmpPlayerStateEnterDriver) + .Const(_SC("EnterPassenger"), vcmpPlayerStateEnterPassenger) + .Const(_SC("Exit"), vcmpPlayerStateExit) + .Const(_SC("Unspawned"), vcmpPlayerStateUnspawned) + .Const(_SC("Max"), vcmpPlayerStateUnspawned) ); ConstTable(vm).Enum(_SC("SqPlayerAction"), Enumeration(vm) diff --git a/source/Core.cpp b/source/Core.cpp index 8fa9250c..9608af06 100644 --- a/source/Core.cpp +++ b/source/Core.cpp @@ -5,13 +5,10 @@ // ------------------------------------------------------------------------------------------------ #include "Entity/Blip.hpp" #include "Entity/Checkpoint.hpp" -#include "Entity/Forcefield.hpp" #include "Entity/Keybind.hpp" #include "Entity/Object.hpp" #include "Entity/Pickup.hpp" #include "Entity/Player.hpp" -#include "Entity/Sprite.hpp" -#include "Entity/Textdraw.hpp" #include "Entity/Vehicle.hpp" // ------------------------------------------------------------------------------------------------ @@ -23,10 +20,8 @@ #include // ------------------------------------------------------------------------------------------------ -#include -#include - -// ------------------------------------------------------------------------------------------------ +#include +#include #include #include #include @@ -35,52 +30,19 @@ namespace SqMod { // ------------------------------------------------------------------------------------------------ -extern void DisableReload(); extern bool RegisterAPI(HSQUIRRELVM vm); // ------------------------------------------------------------------------------------------------ -extern void ProcessRoutine(); -extern void TerminateRoutine(); +extern void InitializeRoutines(); +extern void TerminateRoutines(); +extern void InitializeCmdManager(); +extern void TerminateCmdManager(); // ------------------------------------------------------------------------------------------------ -extern Int32 RunCommand(Int32 invoker, CSStr command); -extern void TerminateCommand(); +extern Object & ReloadPayload(); // ------------------------------------------------------------------------------------------------ -SQMOD_MANAGEDPTR_TYPE(Core) _Core = SQMOD_MANAGEDPTR_MAKE(Core, nullptr); - -/* ------------------------------------------------------------------------------------------------ - * Utility class used to release the destroy lock if unable to complete the process. -*/ -struct EntLockGuard -{ -private: - - // -------------------------------------------------------------------------------------------- - Uint16 & m_Flags; // Reference to the guarded entity flags. - -public: - - /* -------------------------------------------------------------------------------------------- - * Base constructor. - */ - EntLockGuard(Uint16 & ref) - : m_Flags(ref) - { - m_Flags |= ENF_LOCKED; - } - - /* -------------------------------------------------------------------------------------------- - * Destructor. - */ - ~EntLockGuard() - { - if (m_Flags & ENF_LOCKED) - { - m_Flags ^= ENF_LOCKED; - } - } -}; +Core Core::s_Inst; // ------------------------------------------------------------------------------------------------ Core::Core() @@ -90,59 +52,37 @@ Core::Core() , m_Options() , m_Blips() , m_Checkpoints() - , m_Forcefields() , m_Keybinds() , m_Objects() , m_Pickups() , m_Players() - , m_Sprites() - , m_Textdraws() , m_Vehicles() + , m_CircularLocks(0) + , m_IncomingNameBuffer(nullptr) + , m_IncomingNameCapacity(0) { - + /* ... */ } // ------------------------------------------------------------------------------------------------ Core::~Core() { - // Don't release the callbacks abruptly in destructor - ResetFunc(); + if (m_VM) + { + Terminate(); + } } // ------------------------------------------------------------------------------------------------ -bool Core::Init() +bool Core::Initialize() { - if (cLogWrn(m_VM, "Already initialized")) + // Make sure the plug-in was not already initialized + if (m_VM != nullptr) { + OutputError("Plug-in was already initialized"); return true; } - LogDbg("Resizing the entity containers"); - // Make sure the entity containers have the proper size - m_Blips.resize(SQMOD_BLIP_POOL); - m_Checkpoints.resize(SQMOD_CHECKPOINT_POOL); - m_Forcefields.resize(SQMOD_FORCEFIELD_POOL); - m_Keybinds.resize(SQMOD_KEYBIND_POOL); - m_Objects.resize(SQMOD_OBJECT_POOL); - m_Pickups.resize(SQMOD_PICKUP_POOL); - m_Players.resize(SQMOD_PLAYER_POOL); - m_Sprites.resize(SQMOD_SPRITE_POOL); - m_Textdraws.resize(SQMOD_TEXTDRAW_POOL); - m_Vehicles.resize(SQMOD_VEHICLE_POOL); - - LogDbg("Initializing entity options to defaults"); - // Initialize player messaging options to default values - for (Players::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) - { - for (unsigned n = 0; n < SQMOD_PLAYER_MSG_PREFIXES; ++n) - { - itr->mPrefixes[n].clear(); - } - itr->mMessageColor = 0x6599FFFF; - itr->mAnnounceStyle = 1; - } - - LogDbg("Reading configuration file (sqmod.ini)"); CSimpleIniA conf(false, true, true); // Attempt to load the configurations from disk SI_Error ini_ret = conf.LoadFile("sqmod.ini"); @@ -152,58 +92,75 @@ bool Core::Init() switch (ini_ret) { case SI_FAIL: - LogFtl("Failed to load the configuration file. Probably invalid"); + OutputError("Failed to load the configuration file. Probably invalid"); break; case SI_NOMEM: - LogFtl("Run out of memory while loading the configuration file"); + OutputError("Run out of memory while loading the configuration file"); break; case SI_FILE: - LogFtl("Failed to load the configuration file. %s", strerror(errno)); + OutputError("Failed to load the configuration file. %s", std::strerror(errno)); break; default: - LogFtl("Failed to load the configuration file for some unforeseen reason"); + OutputError("Failed to load the configuration file for some unforeseen reason"); } // Failed to load the configuration file return false; } - Uint16 stack_size = SQMOD_STACK_SIZE; - // Attempt to read the database port number - try + // Initialize the log filename + Logger::Get().SetLogFilename(conf.GetValue("Log", "Filename", nullptr)); + // Configure the logging timestamps + Logger::Get().ToggleConsoleTime(conf.GetBoolValue("Log", "ConsoleTimestamp", false)); + Logger::Get().ToggleLogFileTime(conf.GetBoolValue("Log", "LogFileTimestamp", true)); + // Apply the specified logging filters only after initialization was completed + Logger::Get().ToggleConsoleLevel(LOGL_DBG, conf.GetBoolValue("Log", "ConsoleDebug", true)); + Logger::Get().ToggleConsoleLevel(LOGL_USR, conf.GetBoolValue("Log", "ConsoleUser", true)); + Logger::Get().ToggleConsoleLevel(LOGL_SCS, conf.GetBoolValue("Log", "ConsoleSuccess", true)); + Logger::Get().ToggleConsoleLevel(LOGL_INF, conf.GetBoolValue("Log", "ConsoleInfo", true)); + Logger::Get().ToggleConsoleLevel(LOGL_WRN, conf.GetBoolValue("Log", "ConsoleWarning", true)); + Logger::Get().ToggleConsoleLevel(LOGL_ERR, conf.GetBoolValue("Log", "ConsoleError", true)); + Logger::Get().ToggleConsoleLevel(LOGL_FTL, conf.GetBoolValue("Log", "ConsoleFatal", true)); + Logger::Get().ToggleLogFileLevel(LOGL_DBG, conf.GetBoolValue("Log", "LogFileDebug", true)); + Logger::Get().ToggleLogFileLevel(LOGL_USR, conf.GetBoolValue("Log", "LogFileUser", true)); + Logger::Get().ToggleLogFileLevel(LOGL_SCS, conf.GetBoolValue("Log", "LogFileSuccess", true)); + Logger::Get().ToggleLogFileLevel(LOGL_INF, conf.GetBoolValue("Log", "LogFileInfo", true)); + Logger::Get().ToggleLogFileLevel(LOGL_WRN, conf.GetBoolValue("Log", "LogFileWarning", true)); + Logger::Get().ToggleLogFileLevel(LOGL_ERR, conf.GetBoolValue("Log", "LogFileError", true)); + Logger::Get().ToggleLogFileLevel(LOGL_FTL, conf.GetBoolValue("Log", "LogFileFatal", true)); + + LogDbg("Resizing the entity containers"); + // Make sure the entity containers have the proper size + m_Blips.resize(SQMOD_BLIP_POOL); + m_Checkpoints.resize(SQMOD_CHECKPOINT_POOL); + m_Keybinds.resize(SQMOD_KEYBIND_POOL); + m_Objects.resize(SQMOD_OBJECT_POOL); + m_Pickups.resize(SQMOD_PICKUP_POOL); + m_Players.resize(SQMOD_PLAYER_POOL); + m_Vehicles.resize(SQMOD_VEHICLE_POOL); + + // Attempt to read the virtual machine stack size + const LongI stack_size = conf.GetLongValue("Squirrel", "StackSize", SQMOD_STACK_SIZE); + // Make sure that the retrieved number is within range + if (!stack_size) { - Ulong num = conf.GetLongValue("Config", "StackSize", SQMOD_STACK_SIZE); - // Make sure that the retrieved number is within range - if (!num) - { - throw std::out_of_range("stack size too small"); - } - else if (num >= std::numeric_limits< Uint16 >::max()) - { - throw std::out_of_range("stack size too big"); - } - // Save the port number - stack_size = static_cast< Uint16 >(num); - } - catch (const std::exception & e) - { - LogWrn("Unable to obtain a valid stack size [%s]", e.what()); + LogWrn("Invalid virtual machine stack size: %lu", stack_size); + // Stop the initialization process + return false; } - LogDbg("Creating a virtual machine with a stack size of (%d)", stack_size); - // Attempt to create the VM - m_VM = sq_open(stack_size); + LogDbg("Creating a virtual machine (%ld stack size)", stack_size); + // Attempt to create the script virtual machine + m_VM = sq_open(ConvTo< SQInteger >::From(stack_size)); // See if the virtual machine could be created if (cLogFtl(!m_VM, "Unable to create the virtual machine")) { - // Explicitly prevent further use of this pointer - m_VM = nullptr; - // Unable to load the plugin properly - return false; + return false; // Unable to load the plug-in properly! } + // Set this as the default VM DefaultVM::Set(m_VM); - // Enable error handling - ErrorHandling::Enable(true); + // Configure error handling + ErrorHandling::Enable(conf.GetBoolValue("Squirrel", "ErrorHandling", true)); LogDbg("Registering the standard libraries"); // Push the root table on the stack @@ -217,11 +174,11 @@ bool Core::Init() // Pop the root table from the stack sq_pop(m_VM, 1); - LogDbg("Setting the base output function"); + LogDbg("Setting the script output function"); // Tell the VM to use these functions to output user on error messages sq_setprintfunc(m_VM, PrintFunc, ErrorFunc); - LogDbg("Setting the base error handlers"); + LogDbg("Setting the script error handlers"); // Tell the VM to trigger this function on compile time errors sq_setcompilererrorhandler(m_VM, CompilerErrorHandler); // Push the runtime error handler on the stack and create a closure @@ -230,17 +187,17 @@ bool Core::Init() sq_seterrorhandler(m_VM); LogDbg("Registering the plug-in API"); - // Attempt to register the plugin API + // Attempt to register the plug-in API if (cLogFtl(!RegisterAPI(m_VM), "Unable to register the plug-in API")) { return false; // Can't execute scripts without a valid API! } - // Attempt to retrieve the list of strings specified in the config + // Attempt to retrieve the list of scripts specified in the configuration file CSimpleIniA::TNamesDepend scripts; conf.GetAllValues("Scripts", "Source", scripts); // See if any script was specified - if (scripts.size() <= 0 && !conf.GetBoolValue("Config", "EmptyInit", false)) + if (scripts.size() <= 0 && !conf.GetBoolValue("Squirrel", "EmptyInit", false)) { LogWrn("No scripts specified in the configuration file"); // No point in loading the plug-in @@ -248,6 +205,7 @@ bool Core::Init() } else { + LogDbg("Found (%u) scripts in the configuration file", scripts.size()); // Sort the list in it's original order scripts.sort(CSimpleIniA::Entry::LoadOrder()); // Process each specified script paths @@ -258,18 +216,20 @@ bool Core::Init() } } // See if any script could be queued for loading - if (m_Scripts.empty() && !conf.GetBoolValue("Config", "EmptyInit", false)) + if (m_Scripts.empty() && !conf.GetBoolValue("Squirrel", "EmptyInit", false)) { LogErr("No scripts loaded. No reason to load the plug-in"); // No point in loading the plug-in return false; } + LogDbg("Reading the options from the general section"); // Read options only after loading was successful CSimpleIniA::TNamesDepend options; // Are there any options to read? if (conf.GetAllKeys("Options", options) || options.size() > 0) { + LogDbg("Found (%u) options in the configuration file", options); // Process all the specified keys under the [Options] section for (const auto & option : options) { @@ -288,130 +248,103 @@ bool Core::Init() } } } - else - { - LogInf("No options specified in the configuration file"); - } - LogDbg("Applying the specified logging filters"); - // Apply the specified logging filters only after initialization was completed - if (!conf.GetBoolValue("Log", "Debug", true)) - { - _Log->DisableLevel(LL_DBG); - } - if (!conf.GetBoolValue("Log", "User", true)) - { - _Log->DisableLevel(LL_USR); - } - if (!conf.GetBoolValue("Log", "Success", true)) - { - _Log->DisableLevel(LL_SCS); - } - if (!conf.GetBoolValue("Log", "Info", true)) - { - _Log->DisableLevel(LL_INF); - } - if (!conf.GetBoolValue("Log", "Warning", true)) - { - _Log->DisableLevel(LL_WRN); - } - if (!conf.GetBoolValue("Log", "Error", true)) - { - _Log->DisableLevel(LL_ERR); - } - if (!conf.GetBoolValue("Log", "Fatal", true)) - { - _Log->DisableLevel(LL_FTL); - } + // Initialize routines + InitializeRoutines(); + // Initialize commands + InitializeCmdManager(); // Initialization successful return true; } // ------------------------------------------------------------------------------------------------ -bool Core::Load() +bool Core::Execute() { // Are there any scripts to execute? if (cLogErr(m_Scripts.empty(), "No scripts to execute. Plug-in has no purpose")) - return false; // No reason to load the plug-in + { + return false; // No reason to execute the plug-in + } - LogDbg("Signaling outside plugins to register their API"); - // Signal outside plugins to do their monkey business - _Func->SendCustomCommand(0xDEADBABE, ""); + LogDbg("Signaling outside plug-ins to register their API"); + // Tell modules to do their monkey business + _Func->SendPluginCommand(0xDEADBABE, ""); LogDbg("Attempting to execute the specified scripts"); // Go through each specified script - for (Scripts::iterator itr = m_Scripts.begin(); itr != m_Scripts.end(); ++itr) + for (auto & s : m_Scripts) { // Attempt to load and compile the script file try { - itr->second.CompileFile(itr->first); + s.second.CompileFile(s.first); } catch (const Sqrat::Exception & e) { - LogFtl("Unable to compile: %s", itr->first.c_str()); - // Failed to load properly + LogFtl("Unable to compile: %s", s.first.c_str()); + // Failed to executed properly return false; } // Attempt to execute the compiled script code try { - itr->second.Run(); + s.second.Run(); } catch (const Sqrat::Exception & e) { - LogFtl("Unable to execute: %s", itr->first.c_str()); - // Failed to load properly + LogFtl("Unable to execute: %s", s.first.c_str()); + // Failed to executed properly return false; } // At this point the script should be completely loaded - LogScs("Successfully executed script: %s", itr->first.c_str()); + LogScs("Successfully executed script: %s", s.first.c_str()); } // Import already existing entities ImportPlayers(); ImportBlips(); ImportCheckpoints(); - ImportForcefields(); ImportKeybinds(); ImportObjects(); ImportPickups(); - ImportSprites(); - ImportTextdraws(); ImportVehicles(); - // Notify the script callback that the script was loaded + // Notify the script callback that the scripts were loaded EmitScriptLoaded(); - // Successfully loaded + // Successfully executed return true; } // ------------------------------------------------------------------------------------------------ void Core::Terminate() { - LogDbg("Signaling outside plugins to release their resources"); - // Signal outside plugins to do their monkey business - _Func->SendCustomCommand(0xDEADC0DE, ""); + if (m_VM) + { + LogDbg("Signaling outside plug-ins to release their resources"); + // Tell modules to do their monkey business + _Func->SendPluginCommand(0xDEADC0DE, ""); + } // Release all entity resources by clearing the containers m_Players.clear(); m_Blips.clear(); - m_Checkpoints.clear(); m_Keybinds.clear(); m_Objects.clear(); m_Pickups.clear(); - m_Forcefields.clear(); - m_Sprites.clear(); - m_Textdraws.clear(); - m_Vehicles.clear(); + m_Checkpoints.clear(); m_Scripts.clear(); // Release all resources from routines - TerminateRoutine(); + TerminateRoutines(); // Release all resources from command manager - TerminateCommand(); + TerminateCmdManager(); // In case there's a payload for reload - DisableReload(); + ReloadPayload().Release(); + // Release null objects in case any reference to valid objects is stored in them + NullArray().Release(); + NullTable().Release(); + NullObject().Release(); + NullFunction().ReleaseGently(); // Is there a VM to close? if (m_VM) { @@ -419,7 +352,7 @@ void Core::Terminate() ResetFunc(); // Release the script instances m_Scripts.clear(); - // Assertions during close may cause double delete! + // Assertions during close may cause double delete/close! HSQUIRRELVM sq_vm = m_VM; m_VM = nullptr; // Attempt to close the VM @@ -451,9 +384,9 @@ void Core::SetOption(CSStr name, CSStr value) bool Core::LoadScript(CSStr filepath) { // Is the specified path empty? - if (!filepath || *filepath == 0) + if (!filepath || *filepath == '\0') { - return false; // Simply ignore it + return false; // Simply ignore it! } // Get the file path as a string String path(filepath); @@ -462,7 +395,7 @@ bool Core::LoadScript(CSStr filepath) { LogWrn("Script was specified before: %s", path.c_str()); } - // We don't compile the scripts yet. We just store their path and prepare the objects. + // We don't compile the scripts yet. We just store their path and prepare the objects else { // Create a new script container and insert it into the script pool @@ -472,43 +405,81 @@ bool Core::LoadScript(CSStr filepath) return true; } +// ------------------------------------------------------------------------------------------------ +void Core::SetIncomingName(CSStr name) +{ + // Is there an incoming connection buffer that we can write to? + if (!m_IncomingNameBuffer) + { + STHROWF("No incoming player name buffer available"); + } + // Is the specified name valid? + else if (!name || *name == '\0') + { + STHROWF("Invalid player name for incoming connection"); + } + // Calculate the length of the specified name + const size_t len = std::strlen(name); + // Is the length of the name out of bounds? + if (len > m_IncomingNameCapacity) + { + STHROWF("The specified name exceeds the designated buffer"); + } + // Does the name satisfy the minimum length required? + else if (len < 2) + { + STHROWF("The specified name needs to be at least 2 characters: %zu", len); + } + // Copy the specified name to the assigned buffer + std::strncpy(m_IncomingNameBuffer, name, m_IncomingNameCapacity); + // Make sure that the name inside the buffer is null terminated + m_IncomingNameBuffer[len] = '\0'; +} + // ------------------------------------------------------------------------------------------------ void Core::PrintFunc(HSQUIRRELVM /*vm*/, CSStr msg, ...) { + // Initialize the variable argument list va_list args; va_start(args, msg); - _Log->Send(LL_USR, false, msg, args); + // Forward the message to the logger + Logger::Get().Send(LOGL_USR, false, msg, args); + // Finalize the variable argument list va_end(args); } // ------------------------------------------------------------------------------------------------ void Core::ErrorFunc(HSQUIRRELVM /*vm*/, CSStr msg, ...) { + // Initialize the variable argument list va_list args; va_start(args, msg); - _Log->Debug(msg, args); + // Tell the logger to display debugging information + Logger::Get().Debug(msg, args); + // Finalize the variable argument list va_end(args); } // ------------------------------------------------------------------------------------------------ SQInteger Core::RuntimeErrorHandler(HSQUIRRELVM vm) { + // Was there a value thrown? if (sq_gettop(vm) < 1) { - return 0; + return SQ_OK; // No error to display! } - + // Temporary variable for the thrown error CSStr err_msg = nullptr; - + // Attempt to obtain the thrown value as a string if (SQ_SUCCEEDED(sq_getstring(vm, 2, &err_msg))) { - _Log->Debug("%s", err_msg); + Logger::Get().Debug(_SC("%s"), err_msg); } else { - _Log->Debug(_SC("unknown runtime error has occurred")); + Logger::Get().Debug(_SC("Unknown runtime error has occurred")); } - + // We handled the error return SQ_OK; } @@ -518,2884 +489,13 @@ void Core::CompilerErrorHandler(HSQUIRRELVM /*vm*/, CSStr desc, CSStr src, SQInt LogFtl("Message: %s\n[\n=>Location: %s\n=>Line: %d\n=>Column: %d\n]", desc, src, line, column); } -// -------------------------------------------------------------------------------------------- -void Core::ImportBlips() -{ - for (Int32 i = 0; i < SQMOD_BLIP_POOL; ++i) - { - // Information about the blip entity - Int32 world = -1, scale = -1, sprid = -1; - Uint32 color = 0; - Float32 x = 0.0, y = 0.0, z = 0.0; - // See if this entity exists on the server - if (!_Func->GetCoordBlipInfo(i, &world, &x, &y, &z, &scale, &color, &sprid)) - { - continue; // Nothing to import! - } - // Make sure this entity was not allocated already - else if (INVALID_ENTITY(m_Blips[i].mID)) - { - AllocBlip(i, false, SQMOD_CREATE_IMPORT, NullObject()); - // Assign the instance values - m_Blips[i].mWorld = world; - m_Blips[i].mScale = scale; - m_Blips[i].mSprID = sprid; - m_Blips[i].mPosition.Set(x, y, z); - m_Blips[i].mColor.SetRGBA(color); - } - } -} - -void Core::ImportCheckpoints() -{ - for (Int32 i = 0; i < SQMOD_CHECKPOINT_POOL; ++i) - { - // See if this entity exists on the server - if (_Func->GetCheckpointWorld(i) < 0) - { - continue; // Nothing to import! - } - // Make sure this entity was not allocated already - else if (INVALID_ENTITY(m_Checkpoints[i].mID)) - { - AllocCheckpoint(i, false, SQMOD_CREATE_IMPORT, NullObject()); - } - } -} - -void Core::ImportForcefields() -{ - for (Int32 i = 0; i < SQMOD_FORCEFIELD_POOL; ++i) - { - // See if this entity exists on the server - if (_Func->GetSphereWorld(i) < 0) - { - continue; // Nothing to import! - } - // Make sure this entity was not allocated already - else if (INVALID_ENTITY(m_Forcefields[i].mID)) - { - AllocForcefield(i, false, SQMOD_CREATE_IMPORT, NullObject()); - } - } -} - -void Core::ImportKeybinds() -{ - for (Int32 i = 0; i < SQMOD_KEYBIND_POOL; ++i) - { - Uint32 release = 0; - Int32 first = -1, second = -1, third = -1; - // See if this entity exists on the server - if (!_Func->GetKeyBindData(i, &release, &first, &second, &third)) - { - continue; // Nothing to import! - } - // Make sure this entity was not allocated already - else if (INVALID_ENTITY(m_Keybinds[i].mID)) - { - AllocKeybind(i, false, SQMOD_CREATE_IMPORT, NullObject()); - // Assign the instance values - m_Keybinds[i].mFirst = first; - m_Keybinds[i].mSecond = second; - m_Keybinds[i].mThird = third; - m_Keybinds[i].mRelease = static_cast< bool >(release); - } - } -} - -void Core::ImportObjects() -{ - for (Int32 i = 0; i < SQMOD_OBJECT_POOL; ++i) - { - // See if this entity exists on the server - if (_Func->GetObjectModel(i) <= 0) - { - continue; // Nothing to import! - } - // Make sure this entity was not allocated already - else if (INVALID_ENTITY(m_Objects[i].mID)) - { - AllocObject(i, false, SQMOD_CREATE_IMPORT, NullObject()); - } - } -} - -void Core::ImportPickups() -{ - for (Int32 i = 0; i < SQMOD_PICKUP_POOL; ++i) - { - // See if this entity exists on the server - if (_Func->PickupGetModel(i) <= 0) - { - continue; // Nothing to import! - } - // Make sure this entity was not allocated already - else if (INVALID_ENTITY(m_Pickups[i].mID)) - { - AllocPickup(i, false, SQMOD_CREATE_IMPORT, NullObject()); - } - } -} - -void Core::ImportPlayers() -{ - for (Int32 i = 0; i < SQMOD_PLAYER_POOL; ++i) - { - // See if this entity exists on the server - if (!_Func->IsPlayerConnected(i)) - { - continue; // Nothing to import! - } - // Make sure this entity was not allocated already - else if (INVALID_ENTITY(m_Players[i].mID)) - { - ConnectPlayer(i, SQMOD_CREATE_IMPORT, NullObject()); - } - } -} - -void Core::ImportSprites() -{ - /* - for (Int32 i = 0; i < SQMOD_SPRITE_POOL; ++i) - { - // Not possible to detect with current SDK - } - */ -} - -void Core::ImportTextdraws() -{ - /* - for (Int32 i = 0; i < SQMOD_TEXTDRAW_POOL; ++i) - { - // Not possible to detect with current SDK - } - */ -} - -void Core::ImportVehicles() -{ - for (Int32 i = 0; i < SQMOD_VEHICLE_POOL; ++i) - { - // See if this entity exists on the server - if (_Func->GetVehicleModel(i) <= 0) - { - continue; // Nothing to import! - } - // Make sure this entity was not allocated already - else if (INVALID_ENTITY(m_Vehicles[i].mID)) - { - AllocVehicle(i, false, SQMOD_CREATE_IMPORT, NullObject()); - } - } -} - - -// -------------------------------------------------------------------------------------------- -Object & Core::AllocBlip(Int32 id, bool owned, Int32 header, Object & payload) -{ - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(id, SQMOD_BLIP_POOL)) - { - STHROWF("Cannot allocate blip with invalid identifier: %d", id); - } - // Retrieve the specified entity instance - BlipInst & inst = m_Blips[id]; - // Make sure that the instance isn't already allocated - if (VALID_ENTITY(inst.mID)) - { - return inst.mObj; // Return the existing instance - } - // Instantiate the entity manager - inst.mInst = new CBlip(id); - // Create the script object - inst.mObj = Object(inst.mInst, m_VM); - // Make sure that both the instance and script object could be created - if (!inst.mInst || inst.mObj.IsNull()) - { - ResetInst(inst); - STHROWF("Unable to create a blip instance for: %d", id); - } - // Assign the specified entity identifier - inst.mID = id; - // Specify whether the entity is owned by this plug-in - if (owned) - { - inst.mFlags |= ENF_OWNED; - } - else if (inst.mFlags & ENF_OWNED) - { - inst.mFlags ^= ENF_OWNED; - } - // Let the script callbacks know about this entity - EmitBlipCreated(id, header, payload); - // Return the script object - return inst.mObj; -} - -// -------------------------------------------------------------------------------------------- -Object & Core::AllocCheckpoint(Int32 id, bool owned, Int32 header, Object & payload) -{ - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(id, SQMOD_CHECKPOINT_POOL)) - { - STHROWF("Cannot allocate checkpoint with invalid identifier: %d", id); - } - // Retrieve the specified entity instance - CheckpointInst & inst = m_Checkpoints[id]; - // Make sure that the instance isn't already allocated - if (VALID_ENTITY(inst.mID)) - { - return inst.mObj; // Return the existing instance - } - // Instantiate the entity manager - inst.mInst = new CCheckpoint(id); - // Create the script object - inst.mObj = Object(inst.mInst, m_VM); - // Make sure that both the instance and script object could be created - if (!inst.mInst || inst.mObj.IsNull()) - { - ResetInst(inst); - STHROWF("Unable to create a checkpoint instance for: %d", id); - } - // Assign the specified entity identifier - inst.mID = id; - // Specify whether the entity is owned by this plug-in - if (owned) - { - inst.mFlags |= ENF_OWNED; - } - else if (inst.mFlags & ENF_OWNED) - { - inst.mFlags ^= ENF_OWNED; - } - // Let the script callbacks know about this entity - EmitCheckpointCreated(id, header, payload); - // Return the script object - return inst.mObj; -} - -// -------------------------------------------------------------------------------------------- -Object & Core::AllocForcefield(Int32 id, bool owned, Int32 header, Object & payload) -{ - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(id, SQMOD_FORCEFIELD_POOL)) - { - STHROWF("Cannot allocate forcefield with invalid identifier: %d", id); - } - // Retrieve the specified entity instance - ForcefieldInst & inst = m_Forcefields[id]; - // Make sure that the instance isn't already allocated - if (VALID_ENTITY(inst.mID)) - { - return inst.mObj; // Return the existing instance - } - // Instantiate the entity manager - inst.mInst = new CForcefield(id); - // Create the script object - inst.mObj = Object(inst.mInst, m_VM); - // Make sure that both the instance and script object could be created - if (!inst.mInst || inst.mObj.IsNull()) - { - ResetInst(inst); - STHROWF("Unable to create a forcefield instance for: %d", id); - } - // Assign the specified entity identifier - inst.mID = id; - // Specify whether the entity is owned by this plug-in - if (owned) - { - inst.mFlags |= ENF_OWNED; - } - else if (inst.mFlags & ENF_OWNED) - { - inst.mFlags ^= ENF_OWNED; - } - // Let the script callbacks know about this entity - EmitForcefieldCreated(id, header, payload); - // Return the script object - return inst.mObj; -} - -// -------------------------------------------------------------------------------------------- -Object & Core::AllocKeybind(Int32 id, bool owned, Int32 header, Object & payload) -{ - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(id, SQMOD_KEYBIND_POOL)) - { - STHROWF("Cannot allocate keybind with invalid identifier: %d", id); - } - // Retrieve the specified entity instance - KeybindInst & inst = m_Keybinds[id]; - // Make sure that the instance isn't already allocated - if (VALID_ENTITY(inst.mID)) - { - return inst.mObj; // Return the existing instance - } - // Instantiate the entity manager - inst.mInst = new CKeybind(id); - // Create the script object - inst.mObj = Object(inst.mInst, m_VM); - // Make sure that both the instance and script object could be created - if (!inst.mInst || inst.mObj.IsNull()) - { - ResetInst(inst); - STHROWF("Unable to create a keybind instance for: %d", id); - } - // Assign the specified entity identifier - inst.mID = id; - // Specify whether the entity is owned by this plug-in - if (owned) - { - inst.mFlags |= ENF_OWNED; - } - else if (inst.mFlags & ENF_OWNED) - { - inst.mFlags ^= ENF_OWNED; - } - // Let the script callbacks know about this entity - EmitKeybindCreated(id, header, payload); - // Return the script object - return inst.mObj; -} - -// -------------------------------------------------------------------------------------------- -Object & Core::AllocObject(Int32 id, bool owned, Int32 header, Object & payload) -{ - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(id, SQMOD_OBJECT_POOL)) - { - STHROWF("Cannot allocate object with invalid identifier: %d", id); - } - // Retrieve the specified entity instance - ObjectInst & inst = m_Objects[id]; - // Make sure that the instance isn't already allocated - if (VALID_ENTITY(inst.mID)) - { - return inst.mObj; // Return the existing instance - } - // Instantiate the entity manager - inst.mInst = new CObject(id); - // Create the script object - inst.mObj = Object(inst.mInst, m_VM); - // Make sure that both the instance and script object could be created - if (!inst.mInst || inst.mObj.IsNull()) - { - ResetInst(inst); - STHROWF("Unable to create a object instance for: %d", id); - } - // Assign the specified entity identifier - inst.mID = id; - // Specify whether the entity is owned by this plug-in - if (owned) - { - inst.mFlags |= ENF_OWNED; - } - else if (inst.mFlags & ENF_OWNED) - { - inst.mFlags ^= ENF_OWNED; - } - // Let the script callbacks know about this entity - EmitObjectCreated(id, header, payload); - // Return the script object - return inst.mObj; -} - -// -------------------------------------------------------------------------------------------- -Object & Core::AllocPickup(Int32 id, bool owned, Int32 header, Object & payload) -{ - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(id, SQMOD_PICKUP_POOL)) - { - STHROWF("Cannot allocate pickup with invalid identifier: %d", id); - } - // Retrieve the specified entity instance - PickupInst & inst = m_Pickups[id]; - // Make sure that the instance isn't already allocated - if (VALID_ENTITY(inst.mID)) - { - return inst.mObj; // Return the existing instance - } - // Instantiate the entity manager - inst.mInst = new CPickup(id); - // Create the script object - inst.mObj = Object(inst.mInst, m_VM); - // Make sure that both the instance and script object could be created - if (!inst.mInst || inst.mObj.IsNull()) - { - ResetInst(inst); - STHROWF("Unable to create a pickup instance for: %d", id); - } - // Assign the specified entity identifier - inst.mID = id; - // Specify whether the entity is owned by this plug-in - if (owned) - { - inst.mFlags |= ENF_OWNED; - } - else if (inst.mFlags & ENF_OWNED) - { - inst.mFlags ^= ENF_OWNED; - } - // Let the script callbacks know about this entity - EmitPickupCreated(id, header, payload); - // Return the script object - return inst.mObj; -} - -// -------------------------------------------------------------------------------------------- -Object & Core::AllocSprite(Int32 id, bool owned, Int32 header, Object & payload) -{ - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(id, SQMOD_SPRITE_POOL)) - { - STHROWF("Cannot allocate sprite with invalid identifier: %d", id); - } - // Retrieve the specified entity instance - SpriteInst & inst = m_Sprites[id]; - // Make sure that the instance isn't already allocated - if (VALID_ENTITY(inst.mID)) - { - return inst.mObj; // Return the existing instance - } - // Instantiate the entity manager - inst.mInst = new CSprite(id); - // Create the script object - inst.mObj = Object(inst.mInst, m_VM); - // Make sure that both the instance and script object could be created - if (!inst.mInst || inst.mObj.IsNull()) - { - ResetInst(inst); - STHROWF("Unable to create a sprite instance for: %d", id); - } - // Assign the specified entity identifier - inst.mID = id; - // Specify whether the entity is owned by this plug-in - if (owned) - { - inst.mFlags |= ENF_OWNED; - } - else if (inst.mFlags & ENF_OWNED) - { - inst.mFlags ^= ENF_OWNED; - } - // Let the script callbacks know about this entity - EmitSpriteCreated(id, header, payload); - // Return the script object - return inst.mObj; -} - -// -------------------------------------------------------------------------------------------- -Object & Core::AllocTextdraw(Int32 id, bool owned, Int32 header, Object & payload) -{ - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(id, SQMOD_TEXTDRAW_POOL)) - { - STHROWF("Cannot allocate textdraw with invalid identifier: %d", id); - } - // Retrieve the specified entity instance - TextdrawInst & inst = m_Textdraws[id]; - // Make sure that the instance isn't already allocated - if (VALID_ENTITY(inst.mID)) - { - return inst.mObj; // Return the existing instance - } - // Instantiate the entity manager - inst.mInst = new CTextdraw(id); - // Create the script object - inst.mObj = Object(inst.mInst, m_VM); - // Make sure that both the instance and script object could be created - if (!inst.mInst || inst.mObj.IsNull()) - { - ResetInst(inst); - STHROWF("Unable to create a textdraw instance for: %d", id); - } - // Assign the specified entity identifier - inst.mID = id; - // Specify whether the entity is owned by this plug-in - if (owned) - { - inst.mFlags |= ENF_OWNED; - } - else if (inst.mFlags & ENF_OWNED) - { - inst.mFlags ^= ENF_OWNED; - } - // Let the script callbacks know about this entity - EmitTextdrawCreated(id, header, payload); - // Return the script object - return inst.mObj; -} - -// -------------------------------------------------------------------------------------------- -Object & Core::AllocVehicle(Int32 id, bool owned, Int32 header, Object & payload) -{ - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(id, SQMOD_VEHICLE_POOL)) - { - STHROWF("Cannot allocate vehicle with invalid identifier: %d", id); - } - // Retrieve the specified entity instance - VehicleInst & inst = m_Vehicles[id]; - // Make sure that the instance isn't already allocated - if (VALID_ENTITY(inst.mID)) - { - return inst.mObj; // Return the existing instance - } - // Instantiate the entity manager - inst.mInst = new CVehicle(id); - // Create the script object - inst.mObj = Object(inst.mInst, m_VM); - // Make sure that both the instance and script object could be created - if (!inst.mInst || inst.mObj.IsNull()) - { - ResetInst(inst); - STHROWF("Unable to create a vehicle instance for: %d", id); - } - // Assign the specified entity identifier - inst.mID = id; - // Specify whether the entity is owned by this plug-in - if (owned) - { - inst.mFlags |= ENF_OWNED; - } - else if (inst.mFlags & ENF_OWNED) - { - inst.mFlags ^= ENF_OWNED; - } - // Retrieve the associated tracking instance - VehicleTrack & track = m_VehicleTrack[id]; - // Initialize the position - _Func->GetVehiclePos(id, &track.mPosition.x, &track.mPosition.y, &track.mPosition.z); - // Initialize the remaining components - track.mHealth = _Func->GetVehicleHealth(id); - // Let the script callbacks know about this entity - EmitVehicleCreated(id, header, payload); - // Return the script object - return inst.mObj; -} - -// -------------------------------------------------------------------------------------------- -void Core::DeallocBlip(Int32 id, bool destroy, Int32 header, Object & payload) -{ - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(id, SQMOD_BLIP_POOL)) - { - STHROWF("Cannot deallocate blip with invalid identifier: %d", id); - } - // Retrieve the specified entity instance - BlipInst & inst = m_Blips[id]; - // Make sure that the instance is even allocated - if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED)) - { - return; // Nothing to deallocate! - } - // Prevent further attempts to delete this entity - const EntLockGuard elg(inst.mFlags); - // Let the script callbacks know this entity should no longer be used - try - { - EmitBlipDestroyed(id, header, payload); - } - catch (...) - { - // The error was probably dealt with already - } - // Is there a manager instance associated with this entity? - if (inst.mInst) - { - // Prevent further use of this entity - inst.mInst->m_ID = -1; - // Release user data to avoid dangling or circular references - inst.mInst->m_Data.Release(); - } - // Should we delete this entity from the server as well? - if (destroy || (inst.mFlags & ENF_OWNED)) - { - _Func->DestroyCoordBlip(inst.mID); - } - // Reset the entity instance - ResetInst(inst); - // Release associated script callbacks - ResetFunc(inst); - // Prevent further use of the manager instance - inst.mInst = nullptr; - // Release the script object, if any - inst.mObj.Release(); -} - -// -------------------------------------------------------------------------------------------- -void Core::DeallocCheckpoint(Int32 id, bool destroy, Int32 header, Object & payload) -{ - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(id, SQMOD_CHECKPOINT_POOL)) - { - STHROWF("Cannot deallocate checkpoint with invalid identifier: %d", id); - } - // Retrieve the specified entity instance - CheckpointInst & inst = m_Checkpoints[id]; - // Make sure that the instance is even allocated - if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED)) - { - return; // Nothing to deallocate! - } - // Prevent further attempts to delete this entity - const EntLockGuard elg(inst.mFlags); - // Let the script callbacks know this entity should no longer be used - try - { - EmitCheckpointDestroyed(id, header, payload); - } - catch (...) - { - // The error was probably dealt with already - } - // Is there a manager instance associated with this entity? - if (inst.mInst) - { - // Prevent further use of this entity - inst.mInst->m_ID = -1; - // Release user data to avoid dangling or circular references - inst.mInst->m_Data.Release(); - } - // Should we delete this entity from the server as well? - if (destroy || (inst.mFlags & ENF_OWNED)) - { - _Func->DeleteCheckpoint(inst.mID); - } - // Reset the entity instance - ResetInst(inst); - // Release associated script callbacks - ResetFunc(inst); - // Prevent further use of the manager instance - inst.mInst = nullptr; - // Release the script object, if any - inst.mObj.Release(); -} - -// -------------------------------------------------------------------------------------------- -void Core::DeallocForcefield(Int32 id, bool destroy, Int32 header, Object & payload) -{ - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(id, SQMOD_FORCEFIELD_POOL)) - { - STHROWF("Cannot deallocate forcefield with invalid identifier: %d", id); - } - // Retrieve the specified entity instance - ForcefieldInst & inst = m_Forcefields[id]; - // Make sure that the instance is even allocated - if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED)) - { - return; // Nothing to deallocate! - } - // Prevent further attempts to delete this entity - const EntLockGuard elg(inst.mFlags); - // Let the script callbacks know this entity should no longer be used - try - { - EmitForcefieldDestroyed(id, header, payload); - } - catch (...) - { - // The error was probably dealt with already - } - // Is there a manager instance associated with this entity? - if (inst.mInst) - { - // Prevent further use of this entity - inst.mInst->m_ID = -1; - // Release user data to avoid dangling or circular references - inst.mInst->m_Data.Release(); - } - // Should we delete this entity from the server as well? - if (destroy || (inst.mFlags & ENF_OWNED)) - { - _Func->DeleteSphere(inst.mID); - } - // Reset the entity instance - ResetInst(inst); - // Release associated script callbacks - ResetFunc(inst); - // Prevent further use of the manager instance - inst.mInst = nullptr; - // Release the script object, if any - inst.mObj.Release(); -} - -// -------------------------------------------------------------------------------------------- -void Core::DeallocKeybind(Int32 id, bool destroy, Int32 header, Object & payload) -{ - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(id, SQMOD_KEYBIND_POOL)) - { - STHROWF("Cannot deallocate keybind with invalid identifier: %d", id); - } - // Retrieve the specified entity instance - KeybindInst & inst = m_Keybinds[id]; - // Make sure that the instance is even allocated - if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED)) - { - return; // Nothing to deallocate! - } - // Prevent further attempts to delete this entity - const EntLockGuard elg(inst.mFlags); - // Let the script callbacks know this entity should no longer be used - try - { - EmitBlipDestroyed(id, header, payload); - } - catch (...) - { - // The error was dealt with already - } - // Is there a manager instance associated with this entity? - if (inst.mInst) - { - // Prevent further use of this entity - inst.mInst->m_ID = -1; - // Release user data to avoid dangling or circular references - inst.mInst->m_Data.Release(); - } - // Should we delete this entity from the server as well? - if (destroy || (inst.mFlags & ENF_OWNED)) - { - _Func->RemoveKeyBind(inst.mID); - } - // Reset the entity instance - ResetInst(inst); - // Release associated script callbacks - ResetFunc(inst); - // Prevent further use of the manager instance - inst.mInst = nullptr; - // Release the script object, if any - inst.mObj.Release(); -} - -// -------------------------------------------------------------------------------------------- -void Core::DeallocObject(Int32 id, bool destroy, Int32 header, Object & payload) -{ - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(id, SQMOD_OBJECT_POOL)) - { - STHROWF("Cannot deallocate object with invalid identifier: %d", id); - } - // Retrieve the specified entity instance - ObjectInst & inst = m_Objects[id]; - // Make sure that the instance is even allocated - if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED)) - { - return; // Nothing to deallocate! - } - // Prevent further attempts to delete this entity - const EntLockGuard elg(inst.mFlags); - // Let the script callbacks know this entity should no longer be used - try - { - EmitObjectDestroyed(id, header, payload); - } - catch (...) - { - // The error was probably dealt with already - } - // Is there a manager instance associated with this entity? - if (inst.mInst) - { - // Prevent further use of this entity - inst.mInst->m_ID = -1; - // Release user data to avoid dangling or circular references - inst.mInst->m_Data.Release(); - } - // Should we delete this entity from the server as well? - if (destroy || (inst.mFlags & ENF_OWNED)) - { - _Func->DeleteObject(inst.mID); - } - // Reset the entity instance - ResetInst(inst); - // Release associated script callbacks - ResetFunc(inst); - // Prevent further use of the manager instance - inst.mInst = nullptr; - // Release the script object, if any - inst.mObj.Release(); -} - -// -------------------------------------------------------------------------------------------- -void Core::DeallocPickup(Int32 id, bool destroy, Int32 header, Object & payload) -{ - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(id, SQMOD_PICKUP_POOL)) - { - STHROWF("Cannot deallocate pickup with invalid identifier: %d", id); - } - // Retrieve the specified entity instance - PickupInst & inst = m_Pickups[id]; - // Make sure that the instance is even allocated - if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED)) - { - return; // Nothing to deallocate! - } - // Prevent further attempts to delete this entity - const EntLockGuard elg(inst.mFlags); - // Let the script callbacks know this entity should no longer be used - try - { - EmitPickupDestroyed(id, header, payload); - } - catch (...) - { - // The error was probably dealt with already - } - // Is there a manager instance associated with this entity? - if (inst.mInst) - { - // Prevent further use of this entity - inst.mInst->m_ID = -1; - // Release user data to avoid dangling or circular references - inst.mInst->m_Data.Release(); - } - // Should we delete this entity from the server as well? - if (destroy || (inst.mFlags & ENF_OWNED)) - { - _Func->DeletePickup(inst.mID); - } - // Reset the entity instance - ResetInst(inst); - // Release associated script callbacks - ResetFunc(inst); - // Prevent further use of the manager instance - inst.mInst = nullptr; - // Release the script object, if any - inst.mObj.Release(); -} - -// -------------------------------------------------------------------------------------------- -void Core::DeallocSprite(Int32 id, bool destroy, Int32 header, Object & payload) -{ - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(id, SQMOD_SPRITE_POOL)) - { - STHROWF("Cannot deallocate sprite with invalid identifier: %d", id); - } - // Retrieve the specified entity instance - SpriteInst & inst = m_Sprites[id]; - // Make sure that the instance is even allocated - if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED)) - { - return; // Nothing to deallocate! - } - // Prevent further attempts to delete this entity - const EntLockGuard elg(inst.mFlags); - // Let the script callbacks know this entity should no longer be used - try - { - EmitSpriteDestroyed(id, header, payload); - } - catch (...) - { - // The error was probably dealt with already - } - // Is there a manager instance associated with this entity? - if (inst.mInst) - { - // Prevent further use of this entity - inst.mInst->m_ID = -1; - // Release user data to avoid dangling or circular references - inst.mInst->m_Data.Release(); - } - // Should we delete this entity from the server as well? - if (destroy || (inst.mFlags & ENF_OWNED)) - { - _Func->DestroySprite(inst.mID); - } - // Reset the entity instance - ResetInst(inst); - // Release associated script callbacks - ResetFunc(inst); - // Prevent further use of the manager instance - inst.mInst = nullptr; - // Release the script object, if any - inst.mObj.Release(); -} - -// -------------------------------------------------------------------------------------------- -void Core::DeallocTextdraw(Int32 id, bool destroy, Int32 header, Object & payload) -{ - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(id, SQMOD_TEXTDRAW_POOL)) - { - STHROWF("Cannot deallocate textdraw with invalid identifier: %d", id); - } - // Retrieve the specified entity instance - TextdrawInst & inst = m_Textdraws[id]; - // Make sure that the instance is even allocated - if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED)) - { - return; // Nothing to deallocate! - } - // Prevent further attempts to delete this entity - const EntLockGuard elg(inst.mFlags); - // Let the script callbacks know this entity should no longer be used - try - { - EmitTextdrawDestroyed(id, header, payload); - } - catch (...) - { - // The error was probably dealt with already - } - // Is there a manager instance associated with this entity? - if (inst.mInst) - { - // Prevent further use of this entity - inst.mInst->m_ID = -1; - // Release user data to avoid dangling or circular references - inst.mInst->m_Data.Release(); - } - // Should we delete this entity from the server as well? - if (destroy || (inst.mFlags & ENF_OWNED)) - { - _Func->DestroyTextdraw(inst.mID); - } - // Reset the entity instance - ResetInst(inst); - // Release associated script callbacks - ResetFunc(inst); - // Prevent further use of the manager instance - inst.mInst = nullptr; - // Release the script object, if any - inst.mObj.Release(); -} - -// -------------------------------------------------------------------------------------------- -void Core::DeallocVehicle(Int32 id, bool destroy, Int32 header, Object & payload) -{ - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(id, SQMOD_VEHICLE_POOL)) - { - STHROWF("Cannot deallocate vehicle with invalid identifier: %d", id); - } - // Retrieve the specified entity instance - VehicleInst & inst = m_Vehicles[id]; - // Make sure that the instance is even allocated - if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED)) - { - return; // Nothing to deallocate! - } - // Prevent further attempts to delete this entity - const EntLockGuard elg(inst.mFlags); - // Let the script callbacks know this entity should no longer be used - try - { - EmitVehicleDestroyed(id, header, payload); - } - catch (...) - { - // The error was probably dealt with already - } - // Is there a manager instance associated with this entity? - if (inst.mInst) - { - // Prevent further use of this entity - inst.mInst->m_ID = -1; - // Release user data to avoid dangling or circular references - inst.mInst->m_Data.Release(); - } - // Should we delete this entity from the server as well? - if (destroy || (inst.mFlags & ENF_OWNED)) - { - _Func->DeleteVehicle(inst.mID); - } - // Reset the entity instance - ResetInst(inst); - // Release associated script callbacks - ResetFunc(inst); - // Prevent further use of the manager instance - inst.mInst = nullptr; - // Release the script object, if any - inst.mObj.Release(); -} - -// -------------------------------------------------------------------------------------------- -Object & Core::NewBlip(Int32 index, Int32 world, Float32 x, Float32 y, Float32 z, - Int32 scale, Uint32 color, Int32 sprid, - Int32 header, Object & payload) -{ - // Request the server to create this entity - Int32 id = _Func->CreateCoordBlip(index, world, x, y, z, scale, color, sprid); - // Validate the identifier returned by the server - if (INVALID_ENTITYEX(id, SQMOD_BLIP_POOL)) - { - STHROWF("Server returned invalid blip: %d", id); - } - // Attempt to allocate this entity and return the result - return AllocBlip(id, true, header, payload); -} - -// -------------------------------------------------------------------------------------------- -Object & Core::NewCheckpoint(Int32 player, Int32 world, Float32 x, Float32 y, Float32 z, - Uint8 r, Uint8 g, Uint8 b, Uint8 a, Float32 radius, - Int32 header, Object & payload) -{ - // Is the specified player instance even valid? - if (INVALID_ENTITY(m_Players.at(player).mID)) - { - STHROWF("Invalid player reference: %d", player); - } - // Request the server to create this entity - Int32 id = _Func->CreateCheckpoint(player, world, x, y, z, r, g, b, a, radius); - // Validate the identifier returned by the server - if (INVALID_ENTITYEX(id, SQMOD_CHECKPOINT_POOL)) - { - STHROWF("Server returned invalid checkpoint: %d", id); - } - // Attempt to allocate this entity and return the result - return AllocCheckpoint(id, true, header, payload); -} - -// -------------------------------------------------------------------------------------------- -Object & Core::NewForcefield(Int32 player, Int32 world, Float32 x, Float32 y, Float32 z, - Uint8 r, Uint8 g, Uint8 b, Float32 radius, - Int32 header, Object & payload) -{ - // Is the specified player instance even valid? - if (INVALID_ENTITY(m_Players.at(player).mID)) - { - STHROWF("Invalid player reference: %d", player); - } - // Request the server to create this entity - Int32 id = _Func->CreateSphere(player, world, x, y, z, r, g, b, radius); - // Validate the identifier returned by the server - if (INVALID_ENTITYEX(id, SQMOD_FORCEFIELD_POOL)) - { - STHROWF("Server returned invalid forcefield: %d", id); - } - // Attempt to allocate this entity and return the result - return AllocForcefield(id, true, header, payload); -} - -// -------------------------------------------------------------------------------------------- -Object & Core::NewKeybind(Int32 slot, bool release, - Int32 primary, Int32 secondary, Int32 alternative, - Int32 header, Object & payload) -{ - // Request the server to create this entity - Int32 id = _Func->RegisterKeyBind(slot, release, primary, secondary, alternative); - // Validate the identifier returned by the server - if (INVALID_ENTITYEX(id, SQMOD_KEYBIND_POOL)) - { - STHROWF("Server returned invalid keybind: %d", id); - } - // Attempt to allocate this entity and return the result - return AllocKeybind(id, true, header, payload); -} - -// -------------------------------------------------------------------------------------------- -Object & Core::NewObject(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, - Int32 alpha, Int32 header, Object & payload) -{ - // Request the server to create this entity - Int32 id = _Func->CreateObject(model, world, x, y, z, alpha); - // Validate the identifier returned by the server - if (INVALID_ENTITYEX(id, SQMOD_OBJECT_POOL)) - { - STHROWF("Server returned invalid object: %d", id); - } - // Attempt to allocate this entity and return the result - return AllocObject(id, true, header, payload); -} - -// -------------------------------------------------------------------------------------------- -Object & Core::NewPickup(Int32 model, Int32 world, Int32 quantity, - Float32 x, Float32 y, Float32 z, Int32 alpha, bool automatic, - Int32 header, Object & payload) -{ - // Request the server to create this entity - Int32 id = _Func->CreatePickup(model, world, quantity, x, y, z, alpha, automatic); - // Validate the identifier returned by the server - if (INVALID_ENTITYEX(id, SQMOD_PICKUP_POOL)) - { - STHROWF("Server returned invalid pickup: %d", id); - } - // Attempt to allocate this entity and return the result - return AllocPickup(id, true, header, payload); -} - -// -------------------------------------------------------------------------------------------- -Object & Core::NewSprite(Int32 index, CSStr file, Int32 xp, Int32 yp, - Int32 xr, Int32 yr, Float32 angle, Int32 alpha, bool rel, - Int32 header, Object & payload) -{ - // Request the server to create this entity - Int32 id = _Func->CreateSprite(index, file, xp, yp, xr, yr, angle, alpha, rel); - // Validate the identifier returned by the server - if (INVALID_ENTITYEX(id, SQMOD_SPRITE_POOL)) - { - STHROWF("Server returned invalid sprite: %d", id); - } - // Attempt to allocate this entity and return the result - return AllocSprite(id, true, header, payload); -} - -// -------------------------------------------------------------------------------------------- -Object & Core::NewTextdraw(Int32 index, CSStr text, Int32 xp, Int32 yp, - Uint32 color, bool rel, Int32 header, Object & payload) -{ - // Request the server to create this entity - Int32 id = _Func->CreateTextdraw(index, text, xp, yp, color, rel); - // Validate the identifier returned by the server - if (INVALID_ENTITYEX(id, SQMOD_TEXTDRAW_POOL)) - { - STHROWF("Server returned invalid textdraw: %d", id); - } - // Attempt to allocate this entity and return the result - return AllocTextdraw(id, true, header, payload); -} - -// -------------------------------------------------------------------------------------------- -Object & Core::NewVehicle(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, - Float32 angle, Int32 primary, Int32 secondary, - Int32 header, Object & payload) -{ - // Request the server to create this entity - Int32 id = _Func->CreateVehicle(model, world, x, y, z, angle, primary, secondary); - // Validate the identifier returned by the server - if (INVALID_ENTITYEX(id, SQMOD_VEHICLE_POOL)) - { - STHROWF("Server returned invalid vehicle: %d", id); - } - // Attempt to allocate this entity and return the result - return AllocVehicle(id, true, header, payload); -} - -// -------------------------------------------------------------------------------------------- -bool Core::DelBlip(Int32 id, Int32 header, Object & payload) -{ - // Attempt to destroy and deallocate the specified entity instance - DeallocBlip(id, true, header, payload); - // The entity could be destroyed - return true; -} - -bool Core::DelCheckpoint(Int32 id, Int32 header, Object & payload) -{ - // Attempt to destroy and deallocate the specified entity instance - DeallocCheckpoint(id, true, header, payload); - // The entity could be destroyed - return true; -} - -bool Core::DelForcefield(Int32 id, Int32 header, Object & payload) -{ - // Attempt to destroy and deallocate the specified entity instance - DeallocForcefield(id, true, header, payload); - // The entity could be destroyed - return true; -} - -bool Core::DelKeybind(Int32 id, Int32 header, Object & payload) -{ - // Attempt to destroy and deallocate the specified entity instance - DeallocKeybind(id, true, header, payload); - // The entity could be destroyed - return true; -} - -bool Core::DelObject(Int32 id, Int32 header, Object & payload) -{ - // Attempt to destroy and deallocate the specified entity instance - DeallocObject(id, true, header, payload); - // The entity could be destroyed - return true; -} - -bool Core::DelPickup(Int32 id, Int32 header, Object & payload) -{ - // Attempt to destroy and deallocate the specified entity instance - DeallocPickup(id, true, header, payload); - // The entity could be destroyed - return true; -} - -bool Core::DelSprite(Int32 id, Int32 header, Object & payload) -{ - // Attempt to destroy and deallocate the specified entity instance - DeallocSprite(id, true, header, payload); - // The entity could be destroyed - return true; -} - -bool Core::DelTextdraw(Int32 id, Int32 header, Object & payload) -{ - // Attempt to destroy and deallocate the specified entity instance - DeallocTextdraw(id, true, header, payload); - // The entity could be destroyed - return true; -} - -bool Core::DelVehicle(Int32 id, Int32 header, Object & payload) -{ - // Attempt to destroy and deallocate the specified entity instance - DeallocVehicle(id, true, header, payload); - // The entity could be destroyed - return true; -} - -// -------------------------------------------------------------------------------------------- -void Core::ConnectPlayer(Int32 id, Int32 header, Object & payload) -{ - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(id, SQMOD_PLAYER_POOL)) - { - STHROWF("Cannot allocate player with invalid identifier: %d", id); - } - // Retrieve the specified entity instance - PlayerInst & inst = m_Players[id]; - // Make sure that the instance isn't already allocated - if (VALID_ENTITY(inst.mID)) - { - return; // Nothing to allocate! - } - // Instantiate the entity manager - inst.mInst = new CPlayer(id); - // Create the script object - inst.mObj = Object(inst.mInst, m_VM); - // Make sure that both the instance and script object could be created - if (!inst.mInst || inst.mObj.IsNull()) - { - ResetInst(inst); - STHROWF("Unable to create a player instance for: %d", id); - } - // Assign the specified entity identifier - inst.mID = id; - // Retrieve the associated tracking instance - PlayerTrack & track = m_PlayerTrack[id]; - // Initialize the position - _Func->GetPlayerPos(id, &track.mPosition.x, &track.mPosition.y, &track.mPosition.z); - // Initialize the remaining components - track.mHealth = _Func->GetPlayerHealth(id); - track.mArmour = _Func->GetPlayerArmour(id); - track.mWeapon = _Func->GetPlayerWeapon(id); - // Let the script callbacks know about this entity - EmitPlayerCreated(id, header, payload); -} - -void Core::DisconnectPlayer(Int32 id, Int32 header, Object & payload) -{ - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(id, SQMOD_PLAYER_POOL)) - { - STHROWF("Cannot deallocate player with invalid identifier: %d", id); - } - // Retrieve the specified entity instance - PlayerInst & inst = m_Players[id]; - // Make sure that the instance is even allocated - if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED)) - { - return; // Nothing to deallocate! - } - // Prevent further attempts to delete this entity - const EntLockGuard elg(inst.mFlags); - // Let the script callbacks know this entity should no longer be used - try - { - EmitPlayerDestroyed(id, header, payload); - } - catch (...) - { - // The error was probably dealt with already - } - // Is there a manager instance associated with this entity? - if (inst.mInst) - { - // Prevent further use of this entity - inst.mInst->m_ID = -1; - // Release user data to avoid dangling or circular references - inst.mInst->m_Data.Release(); - } - // Reset the entity instance - ResetInst(inst); - // Release associated script callbacks - ResetFunc(inst); - // Prevent further use of the manager instance - inst.mInst = nullptr; - // Release the script object, if any - inst.mObj.Release(); -} - -// ------------------------------------------------------------------------------------------------ -void Core::BindEvent(Int32 id, Object & env, Function & func) -{ - // Obtain the function instance called for this event - Function & event = GetEvent(id); - // Is the specified callback function null? - if (func.IsNull()) - { - event.Release(); // Then release the current callback - } - // Assign the specified environment and function - else - { - event = Function(env.GetVM(), env, func.GetFunc()); - } -} - -// ------------------------------------------------------------------------------------------------ -void Core::EmitBlipCreated(Int32 blip, Int32 header, Object & payload) -{ - Emit(mOnBlipCreated, m_Blips.at(blip).mObj, header, payload); -} - -void Core::EmitCheckpointCreated(Int32 checkpoint, Int32 header, Object & payload) -{ - Emit(mOnCheckpointCreated, m_Checkpoints.at(checkpoint).mObj, header, payload); -} - -void Core::EmitForcefieldCreated(Int32 forcefield, Int32 header, Object & payload) -{ - Emit(mOnForcefieldCreated, m_Forcefields.at(forcefield).mObj, header, payload); -} - -void Core::EmitKeybindCreated(Int32 keybind, Int32 header, Object & payload) -{ - Emit(mOnKeybindCreated, m_Keybinds.at(keybind).mObj, header, payload); -} - -void Core::EmitObjectCreated(Int32 object, Int32 header, Object & payload) -{ - Emit(mOnObjectCreated, m_Objects.at(object).mObj, header, payload); -} - -void Core::EmitPickupCreated(Int32 pickup, Int32 header, Object & payload) -{ - Emit(mOnPickupCreated, m_Pickups.at(pickup).mObj, header, payload); -} - -void Core::EmitPlayerCreated(Int32 player, Int32 header, Object & payload) -{ - Emit(mOnPlayerCreated, m_Players.at(player).mObj, header, payload); -} - -void Core::EmitSpriteCreated(Int32 sprite, Int32 header, Object & payload) -{ - Emit(mOnSpriteCreated, m_Sprites.at(sprite).mObj, header, payload); -} - -void Core::EmitTextdrawCreated(Int32 textdraw, Int32 header, Object & payload) -{ - Emit(mOnTextdrawCreated, m_Textdraws.at(textdraw).mObj, header, payload); -} - -void Core::EmitVehicleCreated(Int32 vehicle, Int32 header, Object & payload) -{ - Emit(mOnVehicleCreated, m_Vehicles.at(vehicle).mObj, header, payload); -} - -void Core::EmitBlipDestroyed(Int32 blip, Int32 header, Object & payload) -{ - BlipInst & _blip = m_Blips.at(blip); - Emit(_blip.mOnDestroyed, header, payload); - Emit(mOnBlipDestroyed, _blip.mObj, header, payload); -} - -void Core::EmitCheckpointDestroyed(Int32 checkpoint, Int32 header, Object & payload) -{ - CheckpointInst & _checkpoint = m_Checkpoints.at(checkpoint); - Emit(_checkpoint.mOnDestroyed, header, payload); - Emit(mOnCheckpointDestroyed, _checkpoint.mObj, header, payload); -} - -void Core::EmitForcefieldDestroyed(Int32 forcefield, Int32 header, Object & payload) -{ - ForcefieldInst & _forcefield = m_Forcefields.at(forcefield); - Emit(_forcefield.mOnDestroyed, header, payload); - Emit(mOnForcefieldDestroyed, _forcefield.mObj, header, payload); -} - -void Core::EmitKeybindDestroyed(Int32 keybind, Int32 header, Object & payload) -{ - KeybindInst & _keybind = m_Keybinds.at(keybind); - Emit(_keybind.mOnDestroyed, header, payload); - Emit(mOnKeybindDestroyed, _keybind.mObj, header, payload); -} - -void Core::EmitObjectDestroyed(Int32 object, Int32 header, Object & payload) -{ - ObjectInst & _object = m_Objects.at(object); - Emit(_object.mOnDestroyed, header, payload); - Emit(mOnObjectDestroyed, _object.mObj, header, payload); -} - -void Core::EmitPickupDestroyed(Int32 pickup, Int32 header, Object & payload) -{ - PickupInst & _pickup = m_Pickups.at(pickup); - Emit(_pickup.mOnDestroyed, header, payload); - Emit(mOnPickupDestroyed, _pickup.mObj, header, payload); -} - -void Core::EmitPlayerDestroyed(Int32 player, Int32 header, Object & payload) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnDestroyed, header, payload); - Emit(mOnPlayerDestroyed, _player.mObj, header, payload); -} - -void Core::EmitSpriteDestroyed(Int32 sprite, Int32 header, Object & payload) -{ - SpriteInst & _sprite = m_Sprites.at(sprite); - Emit(_sprite.mOnDestroyed, header, payload); - Emit(mOnSpriteDestroyed, _sprite.mObj, header, payload); -} - -void Core::EmitTextdrawDestroyed(Int32 textdraw, Int32 header, Object & payload) -{ - TextdrawInst & _textdraw = m_Textdraws.at(textdraw); - Emit(_textdraw.mOnDestroyed, header, payload); - Emit(mOnTextdrawDestroyed, _textdraw.mObj, header, payload); -} - -void Core::EmitVehicleDestroyed(Int32 vehicle, Int32 header, Object & payload) -{ - VehicleInst & _vehicle = m_Vehicles.at(vehicle); - Emit(_vehicle.mOnDestroyed, header, payload); - Emit(mOnVehicleDestroyed, _vehicle.mObj, header, payload); -} - -void Core::EmitBlipCustom(Int32 blip, Int32 header, Object & payload) -{ - BlipInst & _blip = m_Blips.at(blip); - Emit(_blip.mOnCustom, header, payload); - Emit(mOnBlipCustom, _blip.mObj, header, payload); -} - -void Core::EmitCheckpointCustom(Int32 checkpoint, Int32 header, Object & payload) -{ - CheckpointInst & _checkpoint = m_Checkpoints.at(checkpoint); - Emit(_checkpoint.mOnCustom, header, payload); - Emit(mOnCheckpointCustom, _checkpoint.mObj, header, payload); -} - -void Core::EmitForcefieldCustom(Int32 forcefield, Int32 header, Object & payload) -{ - ForcefieldInst & _forcefield = m_Forcefields.at(forcefield); - Emit(_forcefield.mOnCustom, header, payload); - Emit(mOnForcefieldCustom, _forcefield.mObj, header, payload); -} - -void Core::EmitKeybindCustom(Int32 keybind, Int32 header, Object & payload) -{ - KeybindInst & _keybind = m_Keybinds.at(keybind); - Emit(_keybind.mOnCustom, header, payload); - Emit(mOnKeybindCustom, _keybind.mObj, header, payload); -} - -void Core::EmitObjectCustom(Int32 object, Int32 header, Object & payload) -{ - ObjectInst & _object = m_Objects.at(object); - Emit(_object.mOnCustom, header, payload); - Emit(mOnObjectCustom, _object.mObj, header, payload); -} - -void Core::EmitPickupCustom(Int32 pickup, Int32 header, Object & payload) -{ - PickupInst & _pickup = m_Pickups.at(pickup); - Emit(_pickup.mOnCustom, header, payload); - Emit(mOnPickupCustom, _pickup.mObj, header, payload); -} - -void Core::EmitPlayerCustom(Int32 player, Int32 header, Object & payload) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnCustom, header, payload); - Emit(mOnPlayerCustom, _player.mObj, header, payload); -} - -void Core::EmitSpriteCustom(Int32 sprite, Int32 header, Object & payload) -{ - SpriteInst & _sprite = m_Sprites.at(sprite); - Emit(_sprite.mOnCustom, header, payload); - Emit(mOnSpriteCustom, _sprite.mObj, header, payload); -} - -void Core::EmitTextdrawCustom(Int32 textdraw, Int32 header, Object & payload) -{ - TextdrawInst & _textdraw = m_Textdraws.at(textdraw); - Emit(_textdraw.mOnCustom, header, payload); - Emit(mOnTextdrawCustom, _textdraw.mObj, header, payload); -} - -void Core::EmitVehicleCustom(Int32 vehicle, Int32 header, Object & payload) -{ - VehicleInst & _vehicle = m_Vehicles.at(vehicle); - Emit(_vehicle.mOnCustom, header, payload); - Emit(mOnVehicleCustom, _vehicle.mObj, header, payload); -} - -void Core::EmitPlayerAway(Int32 player, bool status) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnAway, status); - Emit(mOnPlayerAway, _player.mObj, status); -} - -void Core::EmitPlayerGameKeys(Int32 player, Int32 previous, Int32 current) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnGameKeys, previous, current); - Emit(mOnPlayerGameKeys, _player.mObj, previous, current); -} - -void Core::EmitPlayerRename(Int32 player, CCStr previous, CCStr current) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnRename, previous, current); - Emit(mOnPlayerRename, _player.mObj, previous, current); -} - -void Core::EmitPlayerRequestClass(Int32 player, Int32 offset) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnRequestClass, offset); - Emit(mOnPlayerRequestClass, _player.mObj, offset); -} - -void Core::EmitPlayerRequestSpawn(Int32 player) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnRequestSpawn); - Emit(mOnPlayerRequestSpawn, _player.mObj); -} - -void Core::EmitPlayerSpawn(Int32 player) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnSpawn); - Emit(mOnPlayerSpawn, _player.mObj); -} - -void Core::EmitPlayerStartTyping(Int32 player) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnStartTyping); - Emit(mOnPlayerStartTyping, _player.mObj); -} - -void Core::EmitPlayerStopTyping(Int32 player) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnStopTyping); - Emit(mOnPlayerStopTyping, _player.mObj); -} - -void Core::EmitPlayerChat(Int32 player, CCStr message) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnChat, message); - Emit(mOnPlayerChat, _player.mObj, message); -} - -void Core::EmitPlayerCommand(Int32 player, CCStr command) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnCommand, command); - Emit(mOnPlayerCommand, _player.mObj, command); - // Send it to the command manager - RunCommand(player, command); -} - -void Core::EmitPlayerMessage(Int32 player, Int32 receiver, CCStr message) -{ - PlayerInst & _player = m_Players.at(player); - PlayerInst & _receiver = m_Players.at(receiver); - Emit(_player.mOnMessage,_receiver.mObj, message); - Emit(mOnPlayerMessage, _player.mObj, _receiver.mObj, message); -} - -void Core::EmitPlayerHealth(Int32 player, Float32 previous, Float32 current) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnHealth, previous, current); - Emit(mOnPlayerHealth, _player.mObj, previous, current); -} - -void Core::EmitPlayerArmour(Int32 player, Float32 previous, Float32 current) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnArmour, previous, current); - Emit(mOnPlayerArmour, _player.mObj, previous, current); -} - -void Core::EmitPlayerWeapon(Int32 player, Int32 previous, Int32 current) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnWeapon, previous, current); - Emit(mOnPlayerWeapon, _player.mObj, previous, current); -} - -void Core::EmitPlayerMove(Int32 player, const Vector3 & previous, const Vector3 & current) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnMove, previous, current); - Emit(mOnPlayerMove, _player.mObj, previous, current); -} - -void Core::EmitPlayerWasted(Int32 player, Int32 reason) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnWasted, reason); - Emit(mOnPlayerWasted, _player.mObj, reason); -} - -void Core::EmitPlayerKilled(Int32 player, Int32 killer, Int32 reason, Int32 body_part) -{ - PlayerInst & _player = m_Players.at(player); - PlayerInst & _killer = m_Players.at(killer); - Emit(_player.mOnKilled, _killer.mObj, reason, body_part); - Emit(mOnPlayerKilled, _player.mObj, _killer.mObj, reason, body_part); -} - -void Core::EmitPlayerTeamKill(Int32 player, Int32 killer, Int32 reason, Int32 body_part) -{ - PlayerInst & _player = m_Players.at(player); - PlayerInst & _killer = m_Players.at(killer); - Emit(_player.mOnTeamKill, _killer.mObj, reason, body_part); - Emit(mOnPlayerTeamKill, _player.mObj, _killer.mObj, reason, body_part); -} - -void Core::EmitPlayerSpectate(Int32 player, Int32 target) -{ - PlayerInst & _player = m_Players.at(player); - PlayerInst & _target = m_Players.at(target); - Emit(_player.mOnSpectate, _target.mObj); - Emit(mOnPlayerSpectate, _player.mObj, _target.mObj); -} - -void Core::EmitPlayerCrashreport(Int32 player, CCStr report) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnCrashreport, report); - Emit(mOnPlayerCrashreport, _player.mObj, report); -} - -void Core::EmitPlayerBurning(Int32 player, bool state) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnBurning, state); - Emit(mOnPlayerBurning, _player.mObj, state); -} - -void Core::EmitPlayerCrouching(Int32 player, bool state) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnCrouching, state); - Emit(mOnPlayerCrouching, _player.mObj, state); -} - -void Core::EmitPlayerState(Int32 player, Int32 previous, Int32 current) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnState, previous, current); - Emit(mOnPlayerState, _player.mObj, previous, current); -} - -void Core::EmitPlayerAction(Int32 player, Int32 previous, Int32 current) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnAction, previous, current); - Emit(mOnPlayerAction, _player.mObj, previous, current); -} - -void Core::EmitStateNone(Int32 player, Int32 previous) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnStateNone, previous); - Emit(mOnStateNone, _player.mObj, previous); -} - -void Core::EmitStateNormal(Int32 player, Int32 previous) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnStateNormal, previous); - Emit(mOnStateNormal, _player.mObj, previous); -} - -void Core::EmitStateShooting(Int32 player, Int32 previous) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnStateShooting, previous); - Emit(mOnStateShooting, _player.mObj, previous); -} - -void Core::EmitStateDriver(Int32 player, Int32 previous) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnStateDriver, previous); - Emit(mOnStateDriver, _player.mObj, previous); -} - -void Core::EmitStatePassenger(Int32 player, Int32 previous) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnStatePassenger, previous); - Emit(mOnStatePassenger, _player.mObj, previous); -} - -void Core::EmitStateEnterDriver(Int32 player, Int32 previous) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnStateEnterDriver, previous); - Emit(mOnStateEnterDriver, _player.mObj, previous); -} - -void Core::EmitStateEnterPassenger(Int32 player, Int32 previous) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnStateEnterPassenger, previous); - Emit(mOnStateEnterPassenger, _player.mObj, previous); -} - -void Core::EmitStateExitVehicle(Int32 player, Int32 previous) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnStateExitVehicle, previous); - Emit(mOnStateExitVehicle, _player.mObj, previous); -} - -void Core::EmitStateUnspawned(Int32 player, Int32 previous) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnStateUnspawned, previous); - Emit(mOnStateUnspawned, _player.mObj, previous); -} - -void Core::EmitActionNone(Int32 player, Int32 previous) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnActionNone, previous); - Emit(mOnActionNone, _player.mObj, previous); -} - -void Core::EmitActionNormal(Int32 player, Int32 previous) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnActionNormal, previous); - Emit(mOnActionNormal, _player.mObj, previous); -} - -void Core::EmitActionAiming(Int32 player, Int32 previous) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnActionAiming, previous); - Emit(mOnActionAiming, _player.mObj, previous); -} - -void Core::EmitActionShooting(Int32 player, Int32 previous) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnActionShooting, previous); - Emit(mOnActionShooting, _player.mObj, previous); -} - -void Core::EmitActionJumping(Int32 player, Int32 previous) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnActionJumping, previous); - Emit(mOnActionJumping, _player.mObj, previous); -} - -void Core::EmitActionLieDown(Int32 player, Int32 previous) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnActionLieDown, previous); - Emit(mOnActionLieDown, _player.mObj, previous); -} - -void Core::EmitActionGettingUp(Int32 player, Int32 previous) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnActionGettingUp, previous); - Emit(mOnActionGettingUp, _player.mObj, previous); -} - -void Core::EmitActionJumpVehicle(Int32 player, Int32 previous) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnActionJumpVehicle, previous); - Emit(mOnActionJumpVehicle, _player.mObj, previous); -} - -void Core::EmitActionDriving(Int32 player, Int32 previous) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnActionDriving, previous); - Emit(mOnActionDriving, _player.mObj, previous); -} - -void Core::EmitActionDying(Int32 player, Int32 previous) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnActionDying, previous); - Emit(mOnActionDying, _player.mObj, previous); -} - -void Core::EmitActionWasted(Int32 player, Int32 previous) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnActionWasted, previous); - Emit(mOnActionWasted, _player.mObj, previous); -} - -void Core::EmitActionEmbarking(Int32 player, Int32 previous) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnActionEmbarking, previous); - Emit(mOnActionEmbarking, _player.mObj, previous); -} - -void Core::EmitActionDisembarking(Int32 player, Int32 previous) -{ - PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnActionDisembarking, previous); - Emit(mOnActionDisembarking, _player.mObj, previous); -} - -void Core::EmitVehicleRespawn(Int32 vehicle) -{ - VehicleInst & _vehicle = m_Vehicles.at(vehicle); - Emit(_vehicle.mOnRespawn); - Emit(mOnVehicleRespawn, _vehicle.mObj); -} - -void Core::EmitVehicleExplode(Int32 vehicle) -{ - VehicleInst & _vehicle = m_Vehicles.at(vehicle); - Emit(_vehicle.mOnExplode); - Emit(mOnVehicleExplode, _vehicle.mObj); -} - -void Core::EmitVehicleHealth(Int32 vehicle, Float32 previous, Float32 current) -{ - VehicleInst & _vehicle = m_Vehicles.at(vehicle); - Emit(_vehicle.mOnHealth, previous, current); - Emit(mOnVehicleHealth, _vehicle.mObj, previous, current); -} - -void Core::EmitVehicleMove(Int32 vehicle, const Vector3 & previous, const Vector3 & current) -{ - VehicleInst & _vehicle = m_Vehicles.at(vehicle); - Emit(_vehicle.mOnMove, previous, current); - Emit(mOnVehicleMove, _vehicle.mObj, previous, current); -} - -void Core::EmitPickupRespawn(Int32 pickup) -{ - PickupInst & _pickup = m_Pickups.at(pickup); - Emit(_pickup.mOnRespawn); - Emit(mOnPickupRespawn, _pickup.mObj); -} - -void Core::EmitPlayerKeyPress(Int32 player, Int32 keybind) -{ - PlayerInst & _player = m_Players.at(player); - KeybindInst & _keybind = m_Keybinds.at(keybind); - Emit(_keybind.mOnKeyPress, _player.mObj); - Emit(_player.mOnKeyPress, _keybind.mObj); - Emit(mOnKeybindKeyPress, _player.mObj, _keybind.mObj); -} - -void Core::EmitPlayerKeyRelease(Int32 player, Int32 keybind) -{ - PlayerInst & _player = m_Players.at(player); - KeybindInst & _keybind = m_Keybinds.at(keybind); - Emit(_keybind.mOnKeyRelease, _player.mObj); - Emit(_player.mOnKeyRelease, _keybind.mObj); - Emit(mOnKeybindKeyRelease, _player.mObj, _keybind.mObj); -} - -void Core::EmitPlayerEmbarking(Int32 player, Int32 vehicle, Int32 slot) -{ - PlayerInst & _player = m_Players.at(player); - VehicleInst & _vehicle = m_Vehicles.at(vehicle); - Emit(_vehicle.mOnEmbarking, _player.mObj, slot); - Emit(_player.mOnEmbarking, _vehicle.mObj, slot); - Emit(mOnVehicleEmbarking, _player.mObj, _vehicle.mObj, slot); -} - -void Core::EmitPlayerEmbarked(Int32 player, Int32 vehicle, Int32 slot) -{ - PlayerInst & _player = m_Players.at(player); - VehicleInst & _vehicle = m_Vehicles.at(vehicle); - Emit(_vehicle.mOnEmbarked, _player.mObj, slot); - Emit(_player.mOnEmbarked, _vehicle.mObj, slot); - Emit(mOnVehicleEmbarked, _player.mObj, _vehicle.mObj, slot); -} - -void Core::EmitPlayerDisembark(Int32 player, Int32 vehicle) -{ - PlayerInst & _player = m_Players.at(player); - VehicleInst & _vehicle = m_Vehicles.at(vehicle); - Emit(_vehicle.mOnDisembark, _player.mObj); - Emit(_player.mOnDisembark, _vehicle.mObj); - Emit(mOnVehicleDisembark, _player.mObj, _vehicle.mObj); -} - -void Core::EmitPickupClaimed(Int32 player, Int32 pickup) -{ - PlayerInst & _player = m_Players.at(player); - PickupInst & _pickup = m_Pickups.at(pickup); - Emit(_pickup.mOnClaimed, _player.mObj); - Emit(_player.mOnPickupClaimed, _pickup.mObj); - Emit(mOnPickupClaimed, _player.mObj, _pickup.mObj); -} - -void Core::EmitPickupCollected(Int32 player, Int32 pickup) -{ - PlayerInst & _player = m_Players.at(player); - PickupInst & _pickup = m_Pickups.at(pickup); - Emit(_pickup.mOnCollected, _player.mObj); - Emit(_player.mOnPickupCollected, _pickup.mObj); - Emit(mOnPickupCollected, _player.mObj, _pickup.mObj); -} - -void Core::EmitObjectShot(Int32 player, Int32 object, Int32 weapon) -{ - PlayerInst & _player = m_Players.at(player); - ObjectInst & _object = m_Objects.at(object); - Emit(_object.mOnShot, _player.mObj, weapon); - Emit(_player.mOnObjectShot, _object.mObj, weapon); - Emit(mOnObjectShot, _player.mObj, _object.mObj, weapon); -} - -void Core::EmitObjectBump(Int32 player, Int32 object) -{ - PlayerInst & _player = m_Players.at(player); - ObjectInst & _object = m_Objects.at(object); - Emit(_object.mOnBump, _player.mObj); - Emit(_player.mOnObjectBump, _object.mObj); - Emit(mOnObjectBump, _player.mObj, _object.mObj); -} - -void Core::EmitCheckpointEntered(Int32 player, Int32 checkpoint) -{ - PlayerInst & _player = m_Players.at(player); - CheckpointInst & _checkpoint = m_Checkpoints.at(checkpoint); - Emit(_checkpoint.mOnEntered, _player.mObj); - Emit(_player.mOnCheckpointEntered, _checkpoint.mObj); - Emit(mOnCheckpointEntered, _player.mObj, _checkpoint.mObj); -} - -void Core::EmitCheckpointExited(Int32 player, Int32 checkpoint) -{ - PlayerInst & _player = m_Players.at(player); - CheckpointInst & _checkpoint = m_Checkpoints.at(checkpoint); - Emit(_checkpoint.mOnExited, _player.mObj); - Emit(_player.mOnCheckpointExited, _checkpoint.mObj); - Emit(mOnCheckpointExited, _player.mObj, _checkpoint.mObj); -} - -void Core::EmitForcefieldEntered(Int32 player, Int32 forcefield) -{ - PlayerInst & _player = m_Players.at(player); - ForcefieldInst & _forcefield = m_Forcefields.at(forcefield); - Emit(_forcefield.mOnEntered, _player.mObj); - Emit(_player.mOnForcefieldEntered, _forcefield.mObj); - Emit(mOnForcefieldEntered, _player.mObj, _forcefield.mObj); -} - -void Core::EmitForcefieldExited(Int32 player, Int32 forcefield) -{ - PlayerInst & _player = m_Players.at(player); - ForcefieldInst & _forcefield = m_Forcefields.at(forcefield); - Emit(_forcefield.mOnExited, _player.mObj); - Emit(_player.mOnForcefieldExited, _forcefield.mObj); - Emit(mOnForcefieldExited, _player.mObj, _forcefield.mObj); -} - -void Core::EmitServerFrame(Float32 delta) -{ - Emit(mOnServerFrame, delta); - // Update routines - ProcessRoutine(); -} - -void Core::EmitServerStartup() -{ - Emit(mOnServerStartup); -} - -void Core::EmitServerShutdown() -{ - Emit(mOnServerShutdown); -} - -void Core::EmitInternalCommand(Int32 type, CCStr text) -{ - Emit(mOnInternalCommand, type, text); -} - -void Core::EmitLoginAttempt(CCStr name, CCStr passwd, CCStr ip) -{ - Emit(mOnLoginAttempt, name, passwd, ip); -} - -void Core::EmitCustomEvent(Int32 group, Int32 header, Object & payload) -{ - Emit(mOnCustomEvent, group, header, payload); -} - -void Core::EmitWorldOption(Int32 option, Object & value) -{ - Emit(mOnWorldOption, option, value); -} - -void Core::EmitWorldToggle(Int32 option, bool value) -{ - Emit(mOnWorldToggle, option, value); -} - -void Core::EmitScriptReload(Int32 header, Object & payload) -{ - Emit(mOnScriptReload, header, payload); -} - -void Core::EmitScriptLoaded() -{ - Emit(mOnScriptLoaded); -} - -// ------------------------------------------------------------------------------------------------ -void Core::EmitPlayerUpdate(Int32 player, Int32 /*type*/) -{ - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(player, SQMOD_PLAYER_POOL)) - { - STHROWF("Cannot update player with invalid identifier: %d", player); - } - // We allocate a dummy vector upfront to retrieve the position - Vector3 pos; - // Retrieve the associated tracking instance - PlayerTrack & inst = m_PlayerTrack[player]; - // Obtain the current position of this instance - _Func->GetPlayerPos(player, &pos.x, &pos.y, &pos.z); - // Did the position change since the last tracked value? - if (pos != inst.mPosition) - { - // Trigger the event specific to this change - EmitPlayerMove(player, inst.mPosition, pos); - // Update the tracked value - inst.mPosition = pos; - } - // Obtain the current health of this instance - Float32 health = _Func->GetPlayerHealth(player); - // Did the health change since the last tracked value? - if (!EpsEq(health, inst.mHealth)) - { - // Trigger the event specific to this change - EmitPlayerHealth(player, inst.mHealth, health); - // Update the tracked value - inst.mHealth = health; - } - // Obtain the current armor of this instance - Float32 armour = _Func->GetPlayerArmour(player); - // Did the armor change since the last tracked value? - if (!EpsEq(armour, inst.mArmour)) - { - // Trigger the event specific to this change - EmitPlayerArmour(player, inst.mArmour, armour); - // Update the tracked value - inst.mArmour = armour; - } - // Obtain the current weapon of this instance - SQInteger wep = _Func->GetPlayerWeapon(player); - // Did the weapon change since the last tracked value? - if (wep != inst.mWeapon) - { - // Trigger the event specific to this change - EmitPlayerWeapon(player, inst.mWeapon, wep); - // Update the tracked value - inst.mWeapon = wep; - } -} - -// ------------------------------------------------------------------------------------------------ -void Core::EmitVehicleUpdate(Int32 vehicle, Int32 /*type*/) -{ - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(vehicle, SQMOD_VEHICLE_POOL)) - { - STHROWF("Cannot update vehicle with invalid identifier: %d", vehicle); - } - // We allocate a dummy vector upfront to retrieve the position - Vector3 pos; - // Retrieve the associated tracking instance - VehicleTrack & inst = m_VehicleTrack[vehicle]; - // Obtain the current position of this instance - _Func->GetVehiclePos(vehicle, &pos.x, &pos.y, &pos.z); - // Did the position change since the last tracked value? - if (pos != inst.mPosition) - { - // Trigger the event specific to this change - EmitVehicleMove(vehicle, inst.mPosition, pos); - // Update the tracked value - inst.mPosition = pos; - } - // Obtain the current health of this instance - Float32 health = _Func->GetVehicleHealth(vehicle); - // Did the health change since the last tracked value? - if (!EpsEq(health, inst.mHealth)) - { - // Trigger the event specific to this change - EmitVehicleHealth(vehicle, inst.mHealth, health); - // Update the tracked value - inst.mHealth = health; - } -} - -// ------------------------------------------------------------------------------------------------ -void Core::EmitEntityPool(Int32 type, Int32 id, bool deleted) -{ - // See what type of change happened in the entity pool - switch (type) - { - case SQMOD_ENTITY_POOL_VEHICLE: - if (deleted && VALID_ENTITY(m_Vehicles[id].mID)) - { - DeallocVehicle(id, false, SQMOD_DESTROY_POOL, NullObject()); - } - else if (INVALID_ENTITY(m_Vehicles[id].mID)) - { - AllocVehicle(id, false, SQMOD_CREATE_POOL, NullObject()); - } - break; - case SQMOD_ENTITY_POOL_OBJECT: - if (deleted && VALID_ENTITY(m_Objects[id].mID)) - { - DeallocObject(id, false, SQMOD_DESTROY_POOL, NullObject()); - } - else if (INVALID_ENTITY(m_Objects[id].mID)) - { - AllocObject(id, false, SQMOD_CREATE_POOL, NullObject()); - } - break; - case SQMOD_ENTITY_POOL_PICKUP: - if (deleted && VALID_ENTITY(m_Pickups[id].mID)) - { - DeallocPickup(id, false, SQMOD_DESTROY_POOL, NullObject()); - } - else if (INVALID_ENTITY(m_Pickups[id].mID)) - { - AllocPickup(id, false, SQMOD_CREATE_POOL, NullObject()); - } - break; - case SQMOD_ENTITY_POOL_RADIO: - // @TODO Implement... - break; - case SQMOD_ENTITY_POOL_SPRITE: - if (deleted && VALID_ENTITY(m_Sprites[id].mID)) - { - DeallocPickup(id, false, SQMOD_DESTROY_POOL, NullObject()); - } - else if (INVALID_ENTITY(m_Sprites[id].mID)) - { - AllocPickup(id, false, SQMOD_CREATE_POOL, NullObject()); - } - break; - case SQMOD_ENTITY_POOL_TEXTDRAW: - if (deleted && VALID_ENTITY(m_Textdraws[id].mID)) - { - DeallocTextdraw(id, false, SQMOD_DESTROY_POOL, NullObject()); - } - else if (INVALID_ENTITY(m_Textdraws[id].mID)) - { - AllocTextdraw(id, false, SQMOD_CREATE_POOL, NullObject()); - } - break; - case SQMOD_ENTITY_POOL_BLIP: - if (deleted && VALID_ENTITY(m_Blips[id].mID)) - { - DeallocBlip(id, false, SQMOD_DESTROY_POOL, NullObject()); - } - else if (INVALID_ENTITY(m_Blips[id].mID)) - { - // Make sure that the specified entity identifier is valid - if (INVALID_ENTITYEX(id, SQMOD_BLIP_POOL)) - { - STHROWF("Cannot allocate blip with invalid identifier: %d", id); - } - // Retrieve the specified entity instance - BlipInst & inst = m_Blips[id]; - // Make sure that the instance isn't already allocated - if (VALID_ENTITY(inst.mID)) - { - STHROWF("Cannot allocate blip that already exists: %d", id); - } - // Information about the blip entity - Int32 world, scale, sprid; - Uint32 color; - Float32 x, y, z; - // Get the blip information from the server - _Func->GetCoordBlipInfo(id, &world, &x, &y, &z, &scale, &color, &sprid); - // Assign the obtain information - inst.mWorld = world; - inst.mScale = scale; - inst.mSprID = sprid; - inst.mColor.SetRGBA(color); - inst.mPosition.Set(x, y, z); - // Now we can allocate the instance after we have all the information - AllocBlip(id, false, SQMOD_CREATE_POOL, NullObject()); - } - break; - default: - LogErr("Unknown change in the entity pool of type: %d", type); - } -} - -// ------------------------------------------------------------------------------------------------ -void Core::ResetInst(BlipInst & inst) -{ - inst.mID = -1; - inst.mFlags = ENF_DEFAULT; - inst.mWorld = -1; - inst.mScale = -1; - inst.mSprID = -1; - inst.mPosition.Clear(); - inst.mColor.Clear(); -} - -void Core::ResetInst(CheckpointInst & inst) -{ - inst.mID = -1; - inst.mFlags = ENF_DEFAULT; -} - -void Core::ResetInst(ForcefieldInst & inst) -{ - inst.mID = -1; - inst.mFlags = ENF_DEFAULT; -} - -void Core::ResetInst(KeybindInst & inst) -{ - inst.mID = -1; - inst.mFlags = ENF_DEFAULT; - inst.mFirst = -1; - inst.mSecond = -1; - inst.mThird = -1; - inst.mRelease = -1; -} - -void Core::ResetInst(ObjectInst & inst) -{ - inst.mID = -1; - inst.mFlags = ENF_DEFAULT; -} - -void Core::ResetInst(PickupInst & inst) -{ - inst.mID = -1; - inst.mFlags = ENF_DEFAULT; -} - -void Core::ResetInst(PlayerInst & inst) -{ - inst.mID = -1; - inst.mFlags = ENF_DEFAULT; - inst.mAuthority = 0; - for (unsigned n = 0; n < SQMOD_PLAYER_MSG_PREFIXES; ++n) - { - inst.mPrefixes[n].assign(""); - } - inst.mMessageColor = 0x6599FFFF; - inst.mAnnounceStyle = 1; -} - -void Core::ResetInst(SpriteInst & inst) -{ - inst.mID = -1; - inst.mFlags = ENF_DEFAULT; - inst.mPath.clear(); -} - -void Core::ResetInst(TextdrawInst & inst) -{ - inst.mID = -1; - inst.mFlags = ENF_DEFAULT; - inst.mText.clear(); -} - -void Core::ResetInst(VehicleInst & inst) -{ - inst.mID = -1; - inst.mFlags = ENF_DEFAULT; -} - -// ------------------------------------------------------------------------------------------------ -void Core::ResetFunc(BlipInst & inst) -{ - inst.mOnDestroyed.ReleaseGently(); - inst.mOnCustom.ReleaseGently(); -} - -void Core::ResetFunc(CheckpointInst & inst) -{ - inst.mOnDestroyed.ReleaseGently(); - inst.mOnCustom.ReleaseGently(); - inst.mOnEntered.ReleaseGently(); - inst.mOnExited.ReleaseGently(); -} - -void Core::ResetFunc(ForcefieldInst & inst) -{ - inst.mOnDestroyed.ReleaseGently(); - inst.mOnCustom.ReleaseGently(); - inst.mOnEntered.ReleaseGently(); - inst.mOnExited.ReleaseGently(); -} - -void Core::ResetFunc(KeybindInst & inst) -{ - inst.mOnDestroyed.ReleaseGently(); - inst.mOnCustom.ReleaseGently(); - inst.mOnKeyPress.ReleaseGently(); - inst.mOnKeyRelease.ReleaseGently(); -} - -void Core::ResetFunc(ObjectInst & inst) -{ - inst.mOnDestroyed.ReleaseGently(); - inst.mOnCustom.ReleaseGently(); - inst.mOnShot.ReleaseGently(); - inst.mOnBump.ReleaseGently(); -} - -void Core::ResetFunc(PickupInst & inst) -{ - inst.mOnDestroyed.ReleaseGently(); - inst.mOnCustom.ReleaseGently(); - inst.mOnRespawn.ReleaseGently(); - inst.mOnClaimed.ReleaseGently(); - inst.mOnCollected.ReleaseGently(); -} - -void Core::ResetFunc(PlayerInst & inst) -{ - inst.mOnDestroyed.ReleaseGently(); - inst.mOnCustom.ReleaseGently(); - inst.mOnAway.ReleaseGently(); - inst.mOnGameKeys.ReleaseGently(); - inst.mOnRename.ReleaseGently(); - inst.mOnRequestClass.ReleaseGently(); - inst.mOnRequestSpawn.ReleaseGently(); - inst.mOnSpawn.ReleaseGently(); - inst.mOnStartTyping.ReleaseGently(); - inst.mOnStopTyping.ReleaseGently(); - inst.mOnChat.ReleaseGently(); - inst.mOnCommand.ReleaseGently(); - inst.mOnMessage.ReleaseGently(); - inst.mOnHealth.ReleaseGently(); - inst.mOnArmour.ReleaseGently(); - inst.mOnWeapon.ReleaseGently(); - inst.mOnMove.ReleaseGently(); - inst.mOnWasted.ReleaseGently(); - inst.mOnKilled.ReleaseGently(); - inst.mOnTeamKill.ReleaseGently(); - inst.mOnSpectate.ReleaseGently(); - inst.mOnCrashreport.ReleaseGently(); - inst.mOnBurning.ReleaseGently(); - inst.mOnCrouching.ReleaseGently(); - inst.mOnState.ReleaseGently(); - inst.mOnAction.ReleaseGently(); - inst.mOnStateNone.ReleaseGently(); - inst.mOnStateNormal.ReleaseGently(); - inst.mOnStateShooting.ReleaseGently(); - inst.mOnStateDriver.ReleaseGently(); - inst.mOnStatePassenger.ReleaseGently(); - inst.mOnStateEnterDriver.ReleaseGently(); - inst.mOnStateEnterPassenger.ReleaseGently(); - inst.mOnStateExitVehicle.ReleaseGently(); - inst.mOnStateUnspawned.ReleaseGently(); - inst.mOnActionNone.ReleaseGently(); - inst.mOnActionNormal.ReleaseGently(); - inst.mOnActionAiming.ReleaseGently(); - inst.mOnActionShooting.ReleaseGently(); - inst.mOnActionJumping.ReleaseGently(); - inst.mOnActionLieDown.ReleaseGently(); - inst.mOnActionGettingUp.ReleaseGently(); - inst.mOnActionJumpVehicle.ReleaseGently(); - inst.mOnActionDriving.ReleaseGently(); - inst.mOnActionDying.ReleaseGently(); - inst.mOnActionWasted.ReleaseGently(); - inst.mOnActionEmbarking.ReleaseGently(); - inst.mOnActionDisembarking.ReleaseGently(); - inst.mOnKeyPress.ReleaseGently(); - inst.mOnKeyRelease.ReleaseGently(); - inst.mOnEmbarking.ReleaseGently(); - inst.mOnEmbarked.ReleaseGently(); - inst.mOnDisembark.ReleaseGently(); - inst.mOnPickupClaimed.ReleaseGently(); - inst.mOnPickupCollected.ReleaseGently(); - inst.mOnObjectShot.ReleaseGently(); - inst.mOnObjectBump.ReleaseGently(); - inst.mOnCheckpointEntered.ReleaseGently(); - inst.mOnCheckpointExited.ReleaseGently(); - inst.mOnForcefieldEntered.ReleaseGently(); - inst.mOnForcefieldExited.ReleaseGently(); -} - -void Core::ResetFunc(SpriteInst & inst) -{ - inst.mOnDestroyed.ReleaseGently(); - inst.mOnCustom.ReleaseGently(); -} - -void Core::ResetFunc(TextdrawInst & inst) -{ - inst.mOnDestroyed.ReleaseGently(); - inst.mOnCustom.ReleaseGently(); -} - -void Core::ResetFunc(VehicleInst & inst) -{ - inst.mOnDestroyed.ReleaseGently(); - inst.mOnCustom.ReleaseGently(); - inst.mOnRespawn.ReleaseGently(); - inst.mOnExplode.ReleaseGently(); - inst.mOnHealth.ReleaseGently(); - inst.mOnMove.ReleaseGently(); - inst.mOnEmbarking.ReleaseGently(); - inst.mOnEmbarked.ReleaseGently(); - inst.mOnDisembark.ReleaseGently(); -} - -void Core::ResetFunc() -{ - mOnBlipCreated.ReleaseGently(); - mOnCheckpointCreated.ReleaseGently(); - mOnForcefieldCreated.ReleaseGently(); - mOnKeybindCreated.ReleaseGently(); - mOnObjectCreated.ReleaseGently(); - mOnPickupCreated.ReleaseGently(); - mOnPlayerCreated.ReleaseGently(); - mOnSpriteCreated.ReleaseGently(); - mOnTextdrawCreated.ReleaseGently(); - mOnVehicleCreated.ReleaseGently(); - mOnBlipDestroyed.ReleaseGently(); - mOnCheckpointDestroyed.ReleaseGently(); - mOnForcefieldDestroyed.ReleaseGently(); - mOnKeybindDestroyed.ReleaseGently(); - mOnObjectDestroyed.ReleaseGently(); - mOnPickupDestroyed.ReleaseGently(); - mOnPlayerDestroyed.ReleaseGently(); - mOnSpriteDestroyed.ReleaseGently(); - mOnTextdrawDestroyed.ReleaseGently(); - mOnVehicleDestroyed.ReleaseGently(); - mOnBlipCustom.ReleaseGently(); - mOnCheckpointCustom.ReleaseGently(); - mOnForcefieldCustom.ReleaseGently(); - mOnKeybindCustom.ReleaseGently(); - mOnObjectCustom.ReleaseGently(); - mOnPickupCustom.ReleaseGently(); - mOnPlayerCustom.ReleaseGently(); - mOnSpriteCustom.ReleaseGently(); - mOnTextdrawCustom.ReleaseGently(); - mOnVehicleCustom.ReleaseGently(); - mOnPlayerAway.ReleaseGently(); - mOnPlayerGameKeys.ReleaseGently(); - mOnPlayerRename.ReleaseGently(); - mOnPlayerRequestClass.ReleaseGently(); - mOnPlayerRequestSpawn.ReleaseGently(); - mOnPlayerSpawn.ReleaseGently(); - mOnPlayerStartTyping.ReleaseGently(); - mOnPlayerStopTyping.ReleaseGently(); - mOnPlayerChat.ReleaseGently(); - mOnPlayerCommand.ReleaseGently(); - mOnPlayerMessage.ReleaseGently(); - mOnPlayerHealth.ReleaseGently(); - mOnPlayerArmour.ReleaseGently(); - mOnPlayerWeapon.ReleaseGently(); - mOnPlayerMove.ReleaseGently(); - mOnPlayerWasted.ReleaseGently(); - mOnPlayerKilled.ReleaseGently(); - mOnPlayerTeamKill.ReleaseGently(); - mOnPlayerSpectate.ReleaseGently(); - mOnPlayerCrashreport.ReleaseGently(); - mOnPlayerBurning.ReleaseGently(); - mOnPlayerCrouching.ReleaseGently(); - mOnPlayerState.ReleaseGently(); - mOnPlayerAction.ReleaseGently(); - mOnStateNone.ReleaseGently(); - mOnStateNormal.ReleaseGently(); - mOnStateShooting.ReleaseGently(); - mOnStateDriver.ReleaseGently(); - mOnStatePassenger.ReleaseGently(); - mOnStateEnterDriver.ReleaseGently(); - mOnStateEnterPassenger.ReleaseGently(); - mOnStateExitVehicle.ReleaseGently(); - mOnStateUnspawned.ReleaseGently(); - mOnActionNone.ReleaseGently(); - mOnActionNormal.ReleaseGently(); - mOnActionAiming.ReleaseGently(); - mOnActionShooting.ReleaseGently(); - mOnActionJumping.ReleaseGently(); - mOnActionLieDown.ReleaseGently(); - mOnActionGettingUp.ReleaseGently(); - mOnActionJumpVehicle.ReleaseGently(); - mOnActionDriving.ReleaseGently(); - mOnActionDying.ReleaseGently(); - mOnActionWasted.ReleaseGently(); - mOnActionEmbarking.ReleaseGently(); - mOnActionDisembarking.ReleaseGently(); - mOnVehicleRespawn.ReleaseGently(); - mOnVehicleExplode.ReleaseGently(); - mOnVehicleHealth.ReleaseGently(); - mOnVehicleMove.ReleaseGently(); - mOnPickupRespawn.ReleaseGently(); - mOnKeybindKeyPress.ReleaseGently(); - mOnKeybindKeyRelease.ReleaseGently(); - mOnVehicleEmbarking.ReleaseGently(); - mOnVehicleEmbarked.ReleaseGently(); - mOnVehicleDisembark.ReleaseGently(); - mOnPickupClaimed.ReleaseGently(); - mOnPickupCollected.ReleaseGently(); - mOnObjectShot.ReleaseGently(); - mOnObjectBump.ReleaseGently(); - mOnCheckpointEntered.ReleaseGently(); - mOnCheckpointExited.ReleaseGently(); - mOnForcefieldEntered.ReleaseGently(); - mOnForcefieldExited.ReleaseGently(); - mOnServerFrame.ReleaseGently(); - mOnServerStartup.ReleaseGently(); - mOnServerShutdown.ReleaseGently(); - mOnInternalCommand.ReleaseGently(); - mOnLoginAttempt.ReleaseGently(); - mOnCustomEvent.ReleaseGently(); - mOnWorldOption.ReleaseGently(); - mOnWorldToggle.ReleaseGently(); - mOnScriptReload.ReleaseGently(); - mOnScriptLoaded.ReleaseGently(); -} - -// ------------------------------------------------------------------------------------------------ -Function & Core::GetEvent(Int32 evid) -{ - switch (evid) - { - case EVT_BLIPCREATED: return mOnBlipCreated; - case EVT_CHECKPOINTCREATED: return mOnCheckpointCreated; - case EVT_FORCEFIELDCREATED: return mOnForcefieldCreated; - case EVT_KEYBINDCREATED: return mOnKeybindCreated; - case EVT_OBJECTCREATED: return mOnObjectCreated; - case EVT_PICKUPCREATED: return mOnPickupCreated; - case EVT_PLAYERCREATED: return mOnPlayerCreated; - case EVT_SPRITECREATED: return mOnSpriteCreated; - case EVT_TEXTDRAWCREATED: return mOnTextdrawCreated; - case EVT_VEHICLECREATED: return mOnVehicleCreated; - case EVT_BLIPDESTROYED: return mOnBlipDestroyed; - case EVT_CHECKPOINTDESTROYED: return mOnCheckpointDestroyed; - case EVT_FORCEFIELDDESTROYED: return mOnForcefieldDestroyed; - case EVT_KEYBINDDESTROYED: return mOnKeybindDestroyed; - case EVT_OBJECTDESTROYED: return mOnObjectDestroyed; - case EVT_PICKUPDESTROYED: return mOnPickupDestroyed; - case EVT_PLAYERDESTROYED: return mOnPlayerDestroyed; - case EVT_SPRITEDESTROYED: return mOnSpriteDestroyed; - case EVT_TEXTDRAWDESTROYED: return mOnTextdrawDestroyed; - case EVT_VEHICLEDESTROYED: return mOnVehicleDestroyed; - case EVT_BLIPCUSTOM: return mOnBlipCustom; - case EVT_CHECKPOINTCUSTOM: return mOnCheckpointCustom; - case EVT_FORCEFIELDCUSTOM: return mOnForcefieldCustom; - case EVT_KEYBINDCUSTOM: return mOnKeybindCustom; - case EVT_OBJECTCUSTOM: return mOnObjectCustom; - case EVT_PICKUPCUSTOM: return mOnPickupCustom; - case EVT_PLAYERCUSTOM: return mOnPlayerCustom; - case EVT_SPRITECUSTOM: return mOnSpriteCustom; - case EVT_TEXTDRAWCUSTOM: return mOnTextdrawCustom; - case EVT_VEHICLECUSTOM: return mOnVehicleCustom; - case EVT_PLAYERAWAY: return mOnPlayerAway; - case EVT_PLAYERGAMEKEYS: return mOnPlayerGameKeys; - case EVT_PLAYERRENAME: return mOnPlayerRename; - case EVT_PLAYERREQUESTCLASS: return mOnPlayerRequestClass; - case EVT_PLAYERREQUESTSPAWN: return mOnPlayerRequestSpawn; - case EVT_PLAYERSPAWN: return mOnPlayerSpawn; - case EVT_PLAYERSTARTTYPING: return mOnPlayerStartTyping; - case EVT_PLAYERSTOPTYPING: return mOnPlayerStopTyping; - case EVT_PLAYERCHAT: return mOnPlayerChat; - case EVT_PLAYERCOMMAND: return mOnPlayerCommand; - case EVT_PLAYERMESSAGE: return mOnPlayerMessage; - case EVT_PLAYERHEALTH: return mOnPlayerHealth; - case EVT_PLAYERARMOUR: return mOnPlayerArmour; - case EVT_PLAYERWEAPON: return mOnPlayerWeapon; - case EVT_PLAYERMOVE: return mOnPlayerMove; - case EVT_PLAYERWASTED: return mOnPlayerWasted; - case EVT_PLAYERKILLED: return mOnPlayerKilled; - case EVT_PLAYERTEAMKILL: return mOnPlayerTeamKill; - case EVT_PLAYERSPECTATE: return mOnPlayerSpectate; - case EVT_PLAYERCRASHREPORT: return mOnPlayerCrashreport; - case EVT_PLAYERBURNING: return mOnPlayerBurning; - case EVT_PLAYERCROUCHING: return mOnPlayerCrouching; - case EVT_PLAYERSTATE: return mOnPlayerState; - case EVT_PLAYERACTION: return mOnPlayerAction; - case EVT_STATENONE: return mOnStateNone; - case EVT_STATENORMAL: return mOnStateNormal; - case EVT_STATESHOOTING: return mOnStateShooting; - case EVT_STATEDRIVER: return mOnStateDriver; - case EVT_STATEPASSENGER: return mOnStatePassenger; - case EVT_STATEENTERDRIVER: return mOnStateEnterDriver; - case EVT_STATEENTERPASSENGER: return mOnStateEnterPassenger; - case EVT_STATEEXITVEHICLE: return mOnStateExitVehicle; - case EVT_STATEUNSPAWNED: return mOnStateUnspawned; - case EVT_ACTIONNONE: return mOnActionNone; - case EVT_ACTIONNORMAL: return mOnActionNormal; - case EVT_ACTIONAIMING: return mOnActionAiming; - case EVT_ACTIONSHOOTING: return mOnActionShooting; - case EVT_ACTIONJUMPING: return mOnActionJumping; - case EVT_ACTIONLIEDOWN: return mOnActionLieDown; - case EVT_ACTIONGETTINGUP: return mOnActionGettingUp; - case EVT_ACTIONJUMPVEHICLE: return mOnActionJumpVehicle; - case EVT_ACTIONDRIVING: return mOnActionDriving; - case EVT_ACTIONDYING: return mOnActionDying; - case EVT_ACTIONWASTED: return mOnActionWasted; - case EVT_ACTIONEMBARKING: return mOnActionEmbarking; - case EVT_ACTIONDISEMBARKING: return mOnActionDisembarking; - case EVT_VEHICLERESPAWN: return mOnVehicleRespawn; - case EVT_VEHICLEEXPLODE: return mOnVehicleExplode; - case EVT_VEHICLEHEALTH: return mOnVehicleHealth; - case EVT_VEHICLEMOVE: return mOnVehicleMove; - case EVT_PICKUPRESPAWN: return mOnPickupRespawn; - case EVT_KEYBINDKEYPRESS: return mOnKeybindKeyPress; - case EVT_KEYBINDKEYRELEASE: return mOnKeybindKeyRelease; - case EVT_VEHICLEEMBARKING: return mOnVehicleEmbarking; - case EVT_VEHICLEEMBARKED: return mOnVehicleEmbarked; - case EVT_VEHICLEDISEMBARK: return mOnVehicleDisembark; - case EVT_PICKUPCLAIMED: return mOnPickupClaimed; - case EVT_PICKUPCOLLECTED: return mOnPickupCollected; - case EVT_OBJECTSHOT: return mOnObjectShot; - case EVT_OBJECTBUMP: return mOnObjectBump; - case EVT_CHECKPOINTENTERED: return mOnCheckpointEntered; - case EVT_CHECKPOINTEXITED: return mOnCheckpointExited; - case EVT_FORCEFIELDENTERED: return mOnForcefieldEntered; - case EVT_FORCEFIELDEXITED: return mOnForcefieldExited; - case EVT_SERVERFRAME: return mOnServerFrame; - case EVT_SERVERSTARTUP: return mOnServerStartup; - case EVT_SERVERSHUTDOWN: return mOnServerShutdown; - case EVT_INTERNALCOMMAND: return mOnInternalCommand; - case EVT_LOGINATTEMPT: return mOnLoginAttempt; - case EVT_CUSTOMEVENT: return mOnCustomEvent; - case EVT_WORLDOPTION: return mOnWorldOption; - case EVT_WORLDTOGGLE: return mOnWorldToggle; - case EVT_SCRIPTRELOAD: return mOnScriptReload; - case EVT_SCRIPTLOADED: return mOnScriptLoaded; - default: return NullFunction(); - } -} - - -// ------------------------------------------------------------------------------------------------ -Function & Core::GetBlipEvent(Int32 id, Int32 evid) -{ - BlipInst & inst = m_Blips.at(id); - - switch (evid) - { - case EVT_BLIPDESTROYED: return inst.mOnDestroyed; - case EVT_BLIPCUSTOM: return inst.mOnCustom; - default: return NullFunction(); - } -} - -Function & Core::GetCheckpointEvent(Int32 id, Int32 evid) -{ - CheckpointInst & inst = m_Checkpoints.at(id); - - switch (evid) - { - case EVT_CHECKPOINTDESTROYED: return inst.mOnDestroyed; - case EVT_CHECKPOINTCUSTOM: return inst.mOnCustom; - case EVT_CHECKPOINTENTERED: return inst.mOnEntered; - case EVT_CHECKPOINTEXITED: return inst.mOnExited; - default: return NullFunction(); - } -} - -Function & Core::GetForcefieldEvent(Int32 id, Int32 evid) -{ - ForcefieldInst & inst = m_Forcefields.at(id); - - switch (evid) - { - case EVT_FORCEFIELDDESTROYED: return inst.mOnDestroyed; - case EVT_FORCEFIELDCUSTOM: return inst.mOnCustom; - case EVT_FORCEFIELDENTERED: return inst.mOnEntered; - case EVT_FORCEFIELDEXITED: return inst.mOnExited; - default: return NullFunction(); - } -} - -Function & Core::GetKeybindEvent(Int32 id, Int32 evid) -{ - KeybindInst & inst = m_Keybinds.at(id); - - switch (evid) - { - case EVT_KEYBINDDESTROYED: return inst.mOnDestroyed; - case EVT_KEYBINDCUSTOM: return inst.mOnCustom; - case EVT_KEYBINDKEYPRESS: return inst.mOnKeyPress; - case EVT_KEYBINDKEYRELEASE: return inst.mOnKeyRelease; - default: return NullFunction(); - } -} - -Function & Core::GetObjectEvent(Int32 id, Int32 evid) -{ - ObjectInst & inst = m_Objects.at(id); - - switch (evid) - { - case EVT_OBJECTDESTROYED: return inst.mOnDestroyed; - case EVT_OBJECTCUSTOM: return inst.mOnCustom; - case EVT_OBJECTSHOT: return inst.mOnShot; - case EVT_OBJECTBUMP: return inst.mOnBump; - default: return NullFunction(); - } -} - -Function & Core::GetPickupEvent(Int32 id, Int32 evid) -{ - PickupInst & inst = m_Pickups.at(id); - - switch (evid) - { - case EVT_PICKUPDESTROYED: return inst.mOnDestroyed; - case EVT_PICKUPCUSTOM: return inst.mOnCustom; - case EVT_PICKUPRESPAWN: return inst.mOnRespawn; - case EVT_PICKUPCLAIMED: return inst.mOnClaimed; - case EVT_PICKUPCOLLECTED: return inst.mOnCollected; - default: return NullFunction(); - } -} - -Function & Core::GetPlayerEvent(Int32 id, Int32 evid) -{ - PlayerInst & inst = m_Players.at(id); - - switch (evid) - { - case EVT_PLAYERDESTROYED: return inst.mOnDestroyed; - case EVT_PLAYERCUSTOM: return inst.mOnCustom; - case EVT_PLAYERAWAY: return inst.mOnAway; - case EVT_PLAYERGAMEKEYS: return inst.mOnGameKeys; - case EVT_PLAYERRENAME: return inst.mOnRename; - case EVT_PLAYERREQUESTCLASS: return inst.mOnRequestClass; - case EVT_PLAYERREQUESTSPAWN: return inst.mOnRequestSpawn; - case EVT_PLAYERSPAWN: return inst.mOnSpawn; - case EVT_PLAYERSTARTTYPING: return inst.mOnStartTyping; - case EVT_PLAYERSTOPTYPING: return inst.mOnStopTyping; - case EVT_PLAYERCHAT: return inst.mOnChat; - case EVT_PLAYERCOMMAND: return inst.mOnCommand; - case EVT_PLAYERMESSAGE: return inst.mOnMessage; - case EVT_PLAYERHEALTH: return inst.mOnHealth; - case EVT_PLAYERARMOUR: return inst.mOnArmour; - case EVT_PLAYERWEAPON: return inst.mOnWeapon; - case EVT_PLAYERMOVE: return inst.mOnMove; - case EVT_PLAYERWASTED: return inst.mOnWasted; - case EVT_PLAYERKILLED: return inst.mOnKilled; - case EVT_PLAYERTEAMKILL: return inst.mOnTeamKill; - case EVT_PLAYERSPECTATE: return inst.mOnSpectate; - case EVT_PLAYERCRASHREPORT: return inst.mOnCrashreport; - case EVT_PLAYERBURNING: return inst.mOnBurning; - case EVT_PLAYERCROUCHING: return inst.mOnCrouching; - case EVT_PLAYERSTATE: return inst.mOnState; - case EVT_PLAYERACTION: return inst.mOnAction; - case EVT_STATENONE: return inst.mOnStateNone; - case EVT_STATENORMAL: return inst.mOnStateNormal; - case EVT_STATESHOOTING: return inst.mOnStateShooting; - case EVT_STATEDRIVER: return inst.mOnStateDriver; - case EVT_STATEPASSENGER: return inst.mOnStatePassenger; - case EVT_STATEENTERDRIVER: return inst.mOnStateEnterDriver; - case EVT_STATEENTERPASSENGER: return inst.mOnStateEnterPassenger; - case EVT_STATEEXITVEHICLE: return inst.mOnStateExitVehicle; - case EVT_STATEUNSPAWNED: return inst.mOnStateUnspawned; - case EVT_ACTIONNONE: return inst.mOnActionNone; - case EVT_ACTIONNORMAL: return inst.mOnActionNormal; - case EVT_ACTIONAIMING: return inst.mOnActionAiming; - case EVT_ACTIONSHOOTING: return inst.mOnActionShooting; - case EVT_ACTIONJUMPING: return inst.mOnActionJumping; - case EVT_ACTIONLIEDOWN: return inst.mOnActionLieDown; - case EVT_ACTIONGETTINGUP: return inst.mOnActionGettingUp; - case EVT_ACTIONJUMPVEHICLE: return inst.mOnActionJumpVehicle; - case EVT_ACTIONDRIVING: return inst.mOnActionDriving; - case EVT_ACTIONDYING: return inst.mOnActionDying; - case EVT_ACTIONWASTED: return inst.mOnActionWasted; - case EVT_ACTIONEMBARKING: return inst.mOnActionEmbarking; - case EVT_ACTIONDISEMBARKING: return inst.mOnActionDisembarking; - case EVT_KEYBINDKEYPRESS: return inst.mOnKeyPress; - case EVT_KEYBINDKEYRELEASE: return inst.mOnKeyRelease; - case EVT_VEHICLEEMBARKING: return inst.mOnEmbarking; - case EVT_VEHICLEEMBARKED: return inst.mOnEmbarked; - case EVT_VEHICLEDISEMBARK: return inst.mOnDisembark; - case EVT_PICKUPCLAIMED: return inst.mOnPickupClaimed; - case EVT_PICKUPCOLLECTED: return inst.mOnPickupCollected; - case EVT_OBJECTSHOT: return inst.mOnObjectShot; - case EVT_OBJECTBUMP: return inst.mOnObjectBump; - case EVT_CHECKPOINTENTERED: return inst.mOnCheckpointEntered; - case EVT_CHECKPOINTEXITED: return inst.mOnCheckpointExited; - case EVT_FORCEFIELDENTERED: return inst.mOnForcefieldEntered; - case EVT_FORCEFIELDEXITED: return inst.mOnForcefieldExited; - default: return NullFunction(); - } -} - -Function & Core::GetSpriteEvent(Int32 id, Int32 evid) -{ - SpriteInst & inst = m_Sprites.at(id); - - switch (evid) - { - case EVT_SPRITEDESTROYED: return inst.mOnDestroyed; - case EVT_SPRITECUSTOM: return inst.mOnCustom; - default: return NullFunction(); - } -} - -Function & Core::GetTextdrawEvent(Int32 id, Int32 evid) -{ - TextdrawInst & inst = m_Textdraws.at(id); - - switch (evid) - { - case EVT_TEXTDRAWDESTROYED: return inst.mOnDestroyed; - case EVT_TEXTDRAWCUSTOM: return inst.mOnCustom; - default: return NullFunction(); - } -} - -Function & Core::GetVehicleEvent(Int32 id, Int32 evid) -{ - VehicleInst & inst = m_Vehicles.at(id); - - switch (evid) - { - case EVT_VEHICLEDESTROYED: return inst.mOnDestroyed; - case EVT_VEHICLECUSTOM: return inst.mOnCustom; - case EVT_VEHICLERESPAWN: return inst.mOnRespawn; - case EVT_VEHICLEEXPLODE: return inst.mOnExplode; - case EVT_VEHICLEHEALTH: return inst.mOnHealth; - case EVT_VEHICLEMOVE: return inst.mOnMove; - case EVT_VEHICLEEMBARKING: return inst.mOnEmbarking; - case EVT_VEHICLEEMBARKED: return inst.mOnEmbarked; - case EVT_VEHICLEDISEMBARK: return inst.mOnDisembark; - default: return NullFunction(); - } -} - // ------------------------------------------------------------------------------------------------ Core::BlipInst::~BlipInst() { // Should we notify that this entity is being cleaned up? if (mID >= 0) { - _Core->EmitBlipDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject()); + Core::Get().EmitBlipDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject()); } // Is there a manager instance associated with this entity? if (mInst) @@ -3411,15 +511,16 @@ Core::BlipInst::~BlipInst() _Func->DestroyCoordBlip(mID); } // Don't release the callbacks abruptly in destructor - _Core->ResetFunc(*this); + Core::ResetFunc(*this); } +// ------------------------------------------------------------------------------------------------ Core::CheckpointInst::~CheckpointInst() { // Should we notify that this entity is being cleaned up? if (mID >= 0) { - _Core->EmitCheckpointDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject()); + Core::Get().EmitCheckpointDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject()); } // Is there a manager instance associated with this entity? if (mInst) @@ -3432,42 +533,19 @@ Core::CheckpointInst::~CheckpointInst() // Are we supposed to clean up this entity? if (mID >= 0 && (mFlags & ENF_OWNED)) { - _Func->DeleteCheckpoint(mID); + _Func->DeleteCheckPoint(mID); } // Don't release the callbacks abruptly in destructor - _Core->ResetFunc(*this); -} - -Core::ForcefieldInst::~ForcefieldInst() -{ - // Should we notify that this entity is being cleaned up? - if (mID >= 0) - { - _Core->EmitForcefieldDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject()); - } - // Is there a manager instance associated with this entity? - if (mInst) - { - // Prevent further use of this entity - mInst->m_ID = -1; - // Release user data to avoid dangling or circular references - mInst->m_Data.Release(); - } - // Are we supposed to clean up this entity? - if (mID >= 0 && (mFlags & ENF_OWNED)) - { - _Func->DeleteSphere(mID); - } - // Don't release the callbacks abruptly in destructor - _Core->ResetFunc(*this); + Core::ResetFunc(*this); } +// ------------------------------------------------------------------------------------------------ Core::KeybindInst::~KeybindInst() { // Should we notify that this entity is being cleaned up? if (mID >= 0) { - _Core->EmitKeybindDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject()); + Core::Get().EmitKeybindDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject()); } // Is there a manager instance associated with this entity? if (mInst) @@ -3483,15 +561,16 @@ Core::KeybindInst::~KeybindInst() _Func->RemoveKeyBind(mID); } // Don't release the callbacks abruptly in destructor - _Core->ResetFunc(*this); + Core::ResetFunc(*this); } +// ------------------------------------------------------------------------------------------------ Core::ObjectInst::~ObjectInst() { // Should we notify that this entity is being cleaned up? if (mID >= 0) { - _Core->EmitObjectDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject()); + Core::Get().EmitObjectDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject()); } // Is there a manager instance associated with this entity? if (mInst) @@ -3507,15 +586,16 @@ Core::ObjectInst::~ObjectInst() _Func->DeleteObject(mID); } // Don't release the callbacks abruptly in destructor - _Core->ResetFunc(*this); + Core::ResetFunc(*this); } +// ------------------------------------------------------------------------------------------------ Core::PickupInst::~PickupInst() { // Should we notify that this entity is being cleaned up? if (mID >= 0) { - _Core->EmitPickupDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject()); + Core::Get().EmitPickupDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject()); } // Is there a manager instance associated with this entity? if (mInst) @@ -3531,15 +611,16 @@ Core::PickupInst::~PickupInst() _Func->DeletePickup(mID); } // Don't release the callbacks abruptly in destructor - _Core->ResetFunc(*this); + Core::ResetFunc(*this); } +// ------------------------------------------------------------------------------------------------ Core::PlayerInst::~PlayerInst() { // Should we notify that this entity is being cleaned up? if (mID >= 0) { - _Core->EmitPlayerDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject()); + Core::Get().EmitPlayerDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject()); } // Is there a manager instance associated with this entity? if (mInst) @@ -3548,65 +629,20 @@ Core::PlayerInst::~PlayerInst() mInst->m_ID = -1; // Release user data to avoid dangling or circular references mInst->m_Data.Release(); + // Release the used memory buffer + mInst->m_Buffer.ResetAll(); } // Don't release the callbacks abruptly in destructor - _Core->ResetFunc(*this); -} - -Core::SpriteInst::~SpriteInst() -{ - // Should we notify that this entity is being cleaned up? - if (mID >= 0) - { - _Core->EmitSpriteDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject()); - } - // Is there a manager instance associated with this entity? - if (mInst) - { - // Prevent further use of this entity - mInst->m_ID = -1; - // Release user data to avoid dangling or circular references - mInst->m_Data.Release(); - } - // Are we supposed to clean up this entity? - if (mID >= 0 && (mFlags & ENF_OWNED)) - { - _Func->DestroySprite(mID); - } - // Don't release the callbacks abruptly in destructor - _Core->ResetFunc(*this); -} - -Core::TextdrawInst::~TextdrawInst() -{ - // Should we notify that this entity is being cleaned up? - if (mID >= 0) - { - _Core->EmitTextdrawDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject()); - } - // Is there a manager instance associated with this entity? - if (mInst) - { - // Prevent further use of this entity - mInst->m_ID = -1; - // Release user data to avoid dangling or circular references - mInst->m_Data.Release(); - } - // Are we supposed to clean up this entity? - if (mID >= 0 && (mFlags & ENF_OWNED)) - { - _Func->DestroyTextdraw(mID); - } - // Don't release the callbacks abruptly in destructor - _Core->ResetFunc(*this); + Core::ResetFunc(*this); } +// ------------------------------------------------------------------------------------------------ Core::VehicleInst::~VehicleInst() { // Should we notify that this entity is being cleaned up? if (mID >= 0) { - _Core->EmitVehicleDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject()); + Core::Get().EmitVehicleDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject()); } // Is there a manager instance associated with this entity? if (mInst) @@ -3622,7 +658,7 @@ Core::VehicleInst::~VehicleInst() _Func->DeleteVehicle(mID); } // Don't release the callbacks abruptly in destructor - _Core->ResetFunc(*this); + Core::ResetFunc(*this); } } // Namespace:: SqMod diff --git a/source/Core.hpp b/source/Core.hpp index f464faaf..8fcaa3ef 100644 --- a/source/Core.hpp +++ b/source/Core.hpp @@ -1,12 +1,10 @@ #ifndef _CORE_HPP_ #define _CORE_HPP_ -// ------------------------------------------------------------------------------------------------ -#include "Base/Shared.hpp" - // ------------------------------------------------------------------------------------------------ #include "Base/Shared.hpp" #include "Base/Vector3.hpp" +#include "Base/Quaternion.hpp" #include "Base/Color4.hpp" // ------------------------------------------------------------------------------------------------ @@ -16,51 +14,62 @@ // ------------------------------------------------------------------------------------------------ namespace SqMod { -// ------------------------------------------------------------------------------------------------ -extern SQMOD_MANAGEDPTR_TYPE(Core) _Core; +/* ------------------------------------------------------------------------------------------------ + * Circular locks employed by the central core. +*/ +enum CoreCircularLocks +{ + CCL_EMIT_SERVER_OPTION = (1 << 0) +}; /* ------------------------------------------------------------------------------------------------ * Core module class responsible for managing resources. */ class Core { +private: + + // -------------------------------------------------------------------------------------------- + static Core s_Inst; // Core instance. + + /* -------------------------------------------------------------------------------------------- + * Default constructor. + */ + Core(); + + /* -------------------------------------------------------------------------------------------- + * Copy constructor. (disabled) + */ + Core(const Core & o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Move constructor. (disabled) + */ + Core(Core && o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Destructor. + */ + ~Core(); + + /* -------------------------------------------------------------------------------------------- + * Copy assignment operator. (disabled) + */ + Core & operator = (const Core & o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Move assignment operator. (disabled) + */ + Core & operator = (Core && o) = delete; + protected: /* -------------------------------------------------------------------------------------------- - * Helper structure meant to track changes in player instances. - */ - struct PlayerTrack - { - PlayerTrack() : mWeapon(-1), mHealth(0), mArmour(0), mPosition() - { /* ... */ } - - Int32 mWeapon; /* Last used player weapon. */ - Float32 mHealth; /* Last known player health. */ - Float32 mArmour; /* Last known player armour */ - Vector3 mPosition; /* Last known player position. */ - }; - - /* -------------------------------------------------------------------------------------------- - * Helper structure meant to track changes in vehicle instances. - */ - struct VehicleTrack - { - VehicleTrack() : mHealth(0), mPosition() - { /* ... */ } - - Float32 mHealth; /* Last known vehicle health. */ - Vector3 mPosition; /* Last known vehicle position. */ - }; - - // -------------------------------------------------------------------------------------------- - typedef String MsgPrefix[SQMOD_PLAYER_MSG_PREFIXES]; - - /* -------------------------------------------------------------------------------------------- - * ... + * Helper structure used to identify a blip entity instance on the server. */ struct BlipInst { - BlipInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(NULL) + BlipInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr) { /* ... */ } ~BlipInst(); @@ -85,16 +94,14 @@ protected: // ---------------------------------------------------------------------------------------- Function mOnDestroyed; Function mOnCustom; - - // ---------------------------------------------------------------------------------------- }; /* -------------------------------------------------------------------------------------------- - * ... + * Helper structure used to identify a checkpoint entity instance on the server. */ struct CheckpointInst { - CheckpointInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(NULL) + CheckpointInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr) { /* ... */ } ~CheckpointInst(); @@ -104,7 +111,6 @@ protected: Uint16 mFlags; CCheckpoint * mInst; Object mObj; - // ---------------------------------------------------------------------------------------- Function mOnDestroyed; Function mOnCustom; @@ -115,35 +121,11 @@ protected: }; /* -------------------------------------------------------------------------------------------- - * ... - */ - struct ForcefieldInst - { - ForcefieldInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(NULL) - { /* ... */ } - - ~ForcefieldInst(); - - // ---------------------------------------------------------------------------------------- - Int32 mID; - Uint16 mFlags; - CForcefield * mInst; - Object mObj; - // ---------------------------------------------------------------------------------------- - Function mOnDestroyed; - Function mOnCustom; - - // ---------------------------------------------------------------------------------------- - Function mOnEntered; - Function mOnExited; - }; - - /* -------------------------------------------------------------------------------------------- - * ... + * Helper structure used to identify a keybind entity instance on the server. */ struct KeybindInst { - KeybindInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(NULL) + KeybindInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr) { /* ... */ } ~KeybindInst(); @@ -170,11 +152,11 @@ protected: }; /* -------------------------------------------------------------------------------------------- - * ... + * Helper structure used to identify an object entity instance on the server. */ struct ObjectInst { - ObjectInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(NULL) + ObjectInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr) { /* ... */ } ~ObjectInst(); @@ -191,15 +173,15 @@ protected: // ---------------------------------------------------------------------------------------- Function mOnShot; - Function mOnBump; + Function mOnTouched; }; /* -------------------------------------------------------------------------------------------- - * ... + * Helper structure used to identify a pickup entity instance on the server. */ struct PickupInst { - PickupInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(NULL) + PickupInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr) { /* ... */ } ~PickupInst(); @@ -221,11 +203,11 @@ protected: }; /* -------------------------------------------------------------------------------------------- - * ... + * Helper structure used to identify a player entity instance on the server. */ struct PlayerInst { - PlayerInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(NULL) + PlayerInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr) { /* ... */ } ~PlayerInst(); @@ -236,54 +218,41 @@ protected: CPlayer * mInst; Object mObj; + // ---------------------------------------------------------------------------------------- + Int32 mLastWeapon; + Float32 mLastHealth; + Float32 mLastArmour; + Float32 mLastHeading; + Vector3 mLastPosition; + // ---------------------------------------------------------------------------------------- Int32 mAuthority; - // ---------------------------------------------------------------------------------------- - MsgPrefix mPrefixes; - - // ---------------------------------------------------------------------------------------- - Uint32 mMessageColor; - Int32 mAnnounceStyle; - // ---------------------------------------------------------------------------------------- Function mOnDestroyed; Function mOnCustom; // ---------------------------------------------------------------------------------------- - Function mOnAway; - Function mOnGameKeys; - Function mOnRename; Function mOnRequestClass; Function mOnRequestSpawn; Function mOnSpawn; - Function mOnStartTyping; - Function mOnStopTyping; - Function mOnChat; - Function mOnCommand; - Function mOnMessage; - Function mOnHealth; - Function mOnArmour; - Function mOnWeapon; - Function mOnMove; Function mOnWasted; Function mOnKilled; - Function mOnTeamKill; - Function mOnSpectate; - Function mOnCrashreport; - Function mOnBurning; - Function mOnCrouching; + Function mOnEmbarking; + Function mOnEmbarked; + Function mOnDisembark; + Function mOnRename; Function mOnState; - Function mOnAction; Function mOnStateNone; Function mOnStateNormal; - Function mOnStateShooting; + Function mOnStateAim; Function mOnStateDriver; Function mOnStatePassenger; Function mOnStateEnterDriver; Function mOnStateEnterPassenger; - Function mOnStateExitVehicle; + Function mOnStateExit; Function mOnStateUnspawned; + Function mOnAction; Function mOnActionNone; Function mOnActionNormal; Function mOnActionAiming; @@ -297,79 +266,41 @@ protected: Function mOnActionWasted; Function mOnActionEmbarking; Function mOnActionDisembarking; + Function mOnBurning; + Function mOnCrouching; + Function mOnGameKeys; + Function mOnStartTyping; + Function mOnStopTyping; + Function mOnAway; + Function mOnMessage; + Function mOnCommand; + Function mOnPrivateMessage; Function mOnKeyPress; Function mOnKeyRelease; - Function mOnEmbarking; - Function mOnEmbarked; - Function mOnDisembark; + Function mOnSpectate; + Function mOnCrashreport; + Function mOnObjectShot; + Function mOnObjectTouched; Function mOnPickupClaimed; Function mOnPickupCollected; - Function mOnObjectShot; - Function mOnObjectBump; Function mOnCheckpointEntered; Function mOnCheckpointExited; - Function mOnForcefieldEntered; - Function mOnForcefieldExited; + Function mOnClientScriptData; + Function mOnUpdate; + Function mOnHealth; + Function mOnArmour; + Function mOnWeapon; + Function mOnHeading; + Function mOnPosition; + Function mOnOption; }; /* -------------------------------------------------------------------------------------------- - * ... - */ - struct SpriteInst - { - SpriteInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(NULL) - { /* ... */ } - - ~SpriteInst(); - - // ---------------------------------------------------------------------------------------- - Int32 mID; - Uint16 mFlags; - CSprite * mInst; - Object mObj; - - // ---------------------------------------------------------------------------------------- - String mPath; - - // ---------------------------------------------------------------------------------------- - Function mOnDestroyed; - Function mOnCustom; - - // ---------------------------------------------------------------------------------------- - }; - - /* -------------------------------------------------------------------------------------------- - * ... - */ - struct TextdrawInst - { - TextdrawInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(NULL) - { /* ... */ } - - ~TextdrawInst(); - - // ---------------------------------------------------------------------------------------- - Int32 mID; - Uint16 mFlags; - CTextdraw * mInst; - Object mObj; - - // ---------------------------------------------------------------------------------------- - String mText; - - // ---------------------------------------------------------------------------------------- - Function mOnDestroyed; - Function mOnCustom; - - // ---------------------------------------------------------------------------------------- - }; - - /* -------------------------------------------------------------------------------------------- - * ... + * Helper structure used to identify a vehicle entity instance on the server. */ struct VehicleInst { - VehicleInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(NULL) + VehicleInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr) { /* ... */ } ~VehicleInst(); @@ -380,18 +311,29 @@ protected: CVehicle * mInst; Object mObj; + // ---------------------------------------------------------------------------------------- + Int32 mLastPrimaryColour; + Int32 mLastSecondaryColour; + Float32 mLastHealth; + Vector3 mLastPosition; + Quaternion mLastRotation; + // ---------------------------------------------------------------------------------------- Function mOnDestroyed; Function mOnCustom; // ---------------------------------------------------------------------------------------- - Function mOnRespawn; - Function mOnExplode; - Function mOnHealth; - Function mOnMove; Function mOnEmbarking; Function mOnEmbarked; Function mOnDisembark; + Function mOnExplode; + Function mOnRespawn; + Function mOnUpdate; + Function mOnColour; + Function mOnHealth; + Function mOnPosition; + Function mOnRotation; + Function mOnOption; }; public: @@ -399,19 +341,12 @@ public: // -------------------------------------------------------------------------------------------- typedef std::vector< BlipInst > Blips; typedef std::vector< CheckpointInst > Checkpoints; - typedef std::vector< ForcefieldInst > Forcefields; typedef std::vector< KeybindInst > Keybinds; typedef std::vector< ObjectInst > Objects; typedef std::vector< PickupInst > Pickups; typedef std::vector< PlayerInst > Players; - typedef std::vector< SpriteInst > Sprites; - typedef std::vector< TextdrawInst > Textdraws; typedef std::vector< VehicleInst > Vehicles; - // -------------------------------------------------------------------------------------------- - typedef PlayerTrack PlayerInstTrack[SQMOD_PLAYER_POOL]; - typedef VehicleTrack VehicleInstTrack[SQMOD_VEHICLE_POOL]; - // -------------------------------------------------------------------------------------------- typedef std::unordered_map< String, Script > Scripts; typedef std::unordered_map< String, String > Options; @@ -419,89 +354,81 @@ public: private: // -------------------------------------------------------------------------------------------- - Int32 m_State; - HSQUIRRELVM m_VM; - Scripts m_Scripts; - Options m_Options; + Int32 m_State; // Current plugin state. + HSQUIRRELVM m_VM; // Script virtual machine. + Scripts m_Scripts; // Loaded scripts objects. + Options m_Options; // Custom configuration options. // -------------------------------------------------------------------------------------------- - Blips m_Blips; - Checkpoints m_Checkpoints; - Forcefields m_Forcefields; - Keybinds m_Keybinds; - Objects m_Objects; - Pickups m_Pickups; - Players m_Players; - Sprites m_Sprites; - Textdraws m_Textdraws; - Vehicles m_Vehicles; + Blips m_Blips; // Blips pool. + Checkpoints m_Checkpoints; // Checkpoints pool. + Keybinds m_Keybinds; // Keybinds pool. + Objects m_Objects; // Objects pool. + Pickups m_Pickups; // Pickups pool. + Players m_Players; // Players pool. + Vehicles m_Vehicles; // Vehicles pool. // -------------------------------------------------------------------------------------------- - PlayerInstTrack m_PlayerTrack; - VehicleInstTrack m_VehicleTrack; + Uint32 m_CircularLocks; // Prevent events from triggering themselves. -protected: - - /* -------------------------------------------------------------------------------------------- - * Default constructor. - */ - Core(); - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. (disabled) - */ - Core(const Core &); - - /* -------------------------------------------------------------------------------------------- - * Copy assignment operator. (disabled) - */ - Core & operator = (const Core &); + // -------------------------------------------------------------------------------------------- + CStr m_IncomingNameBuffer; // Name of an incomming connection. + size_t m_IncomingNameCapacity; // Incomming connection name size. public: /* -------------------------------------------------------------------------------------------- - * Destructor. + * Retrieve the core instance. */ - ~Core(); - - /* -------------------------------------------------------------------------------------------- - * Singleton retriever. - */ - static Core * Get() + static Core & Get() { - if (!_Core) - { - _Core = SQMOD_MANAGEDPTR_MAKE(Core, new Core()); - } - - return SQMOD_MANAGEDPTR_GET(_Core); + return s_Inst; } /* -------------------------------------------------------------------------------------------- - * Lifetime managers. + * Initialize the plug-in core. + */ + bool Initialize(); + + /* -------------------------------------------------------------------------------------------- + * Load and execute plug-in resources. + */ + bool Execute(); + + /* -------------------------------------------------------------------------------------------- + * Terminate the plug-in core. */ - bool Init(); - bool Load(); void Terminate(); /* -------------------------------------------------------------------------------------------- - * State mutators. + * Modify the current plug-in state. */ void SetState(Int32 val) { m_State = val; } + /* -------------------------------------------------------------------------------------------- + * Retrieve the current plug-in state. + */ Int32 GetState() const { return m_State; } /* -------------------------------------------------------------------------------------------- - * Option mutators. + * Retrieve the value of the specified option. */ CSStr GetOption(CSStr name) const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value of the specified option or the fallback value if it doesn't exist. + */ CSStr GetOption(CSStr name, CSStr value) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the value of the specified option. + */ void SetOption(CSStr name, CSStr value); /* -------------------------------------------------------------------------------------------- @@ -512,11 +439,40 @@ public: return m_VM; } + /* -------------------------------------------------------------------------------------------- + * Retrieve the circular locks. + */ + Uint32 & GetCircularLock() + { + return m_CircularLocks; + } + + /* -------------------------------------------------------------------------------------------- + * See if certain circular locks are enabled. + */ + bool IsCircularLock(Uint32 lock) const + { + return (m_CircularLocks & lock); + } + /* -------------------------------------------------------------------------------------------- * Adds a script to the load queue. */ bool LoadScript(CSStr filepath); + /* -------------------------------------------------------------------------------------------- + * Modify the name for the currently assigned incoming connection. + */ + void SetIncomingName(CSStr name); + + /* -------------------------------------------------------------------------------------------- + * retrieve the name for the currently assigned incoming connection.. + */ + CSStr GetIncomingName() + { + return (!m_IncomingNameBuffer) ? _SC("") : m_IncomingNameBuffer; + } + protected: /* -------------------------------------------------------------------------------------------- @@ -533,62 +489,49 @@ protected: SQInteger line, SQInteger column); /* -------------------------------------------------------------------------------------------- - * Entity instance scaners. + * Entity scaners. */ void ImportBlips(); void ImportCheckpoints(); - void ImportForcefields(); void ImportKeybinds(); void ImportObjects(); void ImportPickups(); void ImportPlayers(); - void ImportSprites(); - void ImportTextdraws(); void ImportVehicles(); /* -------------------------------------------------------------------------------------------- - * Instance allocators. + * Entity allocators. */ Object & AllocBlip(Int32 id, bool owned, Int32 header, Object & payload); Object & AllocCheckpoint(Int32 id, bool owned, Int32 header, Object & payload); - Object & AllocForcefield(Int32 id, bool owned, Int32 header, Object & payload); Object & AllocKeybind(Int32 id, bool owned, Int32 header, Object & payload); Object & AllocObject(Int32 id, bool owned, Int32 header, Object & payload); Object & AllocPickup(Int32 id, bool owned, Int32 header, Object & payload); - Object & AllocSprite(Int32 id, bool owned, Int32 header, Object & payload); - Object & AllocTextdraw(Int32 id, bool owned, Int32 header, Object & payload); Object & AllocVehicle(Int32 id, bool owned, Int32 header, Object & payload); /* -------------------------------------------------------------------------------------------- - * Instance deallocators. + * Entity deallocators. */ void DeallocBlip(Int32 id, bool destroy, Int32 header, Object & payload); void DeallocCheckpoint(Int32 id, bool destroy, Int32 header, Object & payload); - void DeallocForcefield(Int32 id, bool destroy, Int32 header, Object & payload); void DeallocKeybind(Int32 id, bool destroy, Int32 header, Object & payload); void DeallocObject(Int32 id, bool destroy, Int32 header, Object & payload); void DeallocPickup(Int32 id, bool destroy, Int32 header, Object & payload); - void DeallocSprite(Int32 id, bool destroy, Int32 header, Object & payload); - void DeallocTextdraw(Int32 id, bool destroy, Int32 header, Object & payload); void DeallocVehicle(Int32 id, bool destroy, Int32 header, Object & payload); public: /* -------------------------------------------------------------------------------------------- - * Instance creators. + * Entity creators. */ Object & NewBlip(Int32 index, Int32 world, Float32 x, Float32 y, Float32 z, Int32 scale, Uint32 color, Int32 sprid, Int32 header, Object & payload); - Object & NewCheckpoint(Int32 player, Int32 world, Float32 x, Float32 y, Float32 z, + Object & NewCheckpoint(Int32 player, Int32 world, bool sphere, Float32 x, Float32 y, Float32 z, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Float32 radius, Int32 header, Object & payload); - Object & NewForcefield(Int32 player, Int32 world, Float32 x, Float32 y, Float32 z, - Uint8 r, Uint8 g, Uint8 b, Float32 radius, - Int32 header, Object & payload); - Object & NewKeybind(Int32 slot, bool release, Int32 primary, Int32 secondary, Int32 alternative, Int32 header, Object & payload); @@ -612,30 +555,24 @@ public: Int32 header, Object & payload); /* -------------------------------------------------------------------------------------------- - * Instance destroyers. + * Entity destroyers. */ bool DelBlip(Int32 id, Int32 header, Object & payload); bool DelCheckpoint(Int32 id, Int32 header, Object & payload); - bool DelForcefield(Int32 id, Int32 header, Object & payload); bool DelKeybind(Int32 id, Int32 header, Object & payload); bool DelObject(Int32 id, Int32 header, Object & payload); bool DelPickup(Int32 id, Int32 header, Object & payload); - bool DelSprite(Int32 id, Int32 header, Object & payload); - bool DelTextdraw(Int32 id, Int32 header, Object & payload); bool DelVehicle(Int32 id, Int32 header, Object & payload); /* -------------------------------------------------------------------------------------------- - * Instance retrievers. + * Entity retrievers. */ BlipInst & GetBlip(Int32 id) { return m_Blips.at(id); } CheckpointInst & GetCheckpoint(Int32 id) { return m_Checkpoints.at(id); } - ForcefieldInst & GetForcefield(Int32 id) { return m_Forcefields.at(id); } KeybindInst & GetKeybind(Int32 id) { return m_Keybinds.at(id); } ObjectInst & GetObject(Int32 id) { return m_Objects.at(id); } PickupInst & GetPickup(Int32 id) { return m_Pickups.at(id); } PlayerInst & GetPlayer(Int32 id) { return m_Players.at(id); } - SpriteInst & GetSprite(Int32 id) { return m_Sprites.at(id); } - TextdrawInst & GetTextdraw(Int32 id) { return m_Textdraws.at(id); } VehicleInst & GetVehicle(Int32 id) { return m_Vehicles.at(id); } /* -------------------------------------------------------------------------------------------- @@ -643,13 +580,10 @@ public: */ const Blips & GetBlips() const { return m_Blips; } const Checkpoints & GetCheckpoints() const { return m_Checkpoints; } - const Forcefields & GetForcefields() const { return m_Forcefields; } const Keybinds & GetKeybinds() const { return m_Keybinds; } const Objects & GetObjects() const { return m_Objects; } const Pickups & GetPickups() const { return m_Pickups; } const Players & GetPlayers() const { return m_Players; } - const Sprites & GetSprites() const { return m_Sprites; } - const Textdraws & GetTextdraws() const { return m_Textdraws; } const Vehicles & GetVehicles() const { return m_Vehicles; } protected: @@ -657,85 +591,42 @@ protected: /* -------------------------------------------------------------------------------------------- * Instance cleaners. */ - void ResetInst(BlipInst & inst); - void ResetInst(CheckpointInst & inst); - void ResetInst(ForcefieldInst & inst); - void ResetInst(KeybindInst & inst); - void ResetInst(ObjectInst & inst); - void ResetInst(PickupInst & inst); - void ResetInst(PlayerInst & inst); - void ResetInst(SpriteInst & inst); - void ResetInst(TextdrawInst & inst); - void ResetInst(VehicleInst & inst); + static void ResetInst(BlipInst & inst); + static void ResetInst(CheckpointInst & inst); + static void ResetInst(KeybindInst & inst); + static void ResetInst(ObjectInst & inst); + static void ResetInst(PickupInst & inst); + static void ResetInst(PlayerInst & inst); + static void ResetInst(VehicleInst & inst); /* -------------------------------------------------------------------------------------------- * Bindings cleaners. */ - void ResetFunc(BlipInst & inst); - void ResetFunc(CheckpointInst & inst); - void ResetFunc(ForcefieldInst & inst); - void ResetFunc(KeybindInst & inst); - void ResetFunc(ObjectInst & inst); - void ResetFunc(PickupInst & inst); - void ResetFunc(PlayerInst & inst); - void ResetFunc(SpriteInst & inst); - void ResetFunc(TextdrawInst & inst); - void ResetFunc(VehicleInst & inst); - void ResetFunc(); + static void ResetFunc(BlipInst & inst); + static void ResetFunc(CheckpointInst & inst); + static void ResetFunc(KeybindInst & inst); + static void ResetFunc(ObjectInst & inst); + static void ResetFunc(PickupInst & inst); + static void ResetFunc(PlayerInst & inst); + static void ResetFunc(VehicleInst & inst); + static void ResetFunc(); // -------------------------------------------------------------------------------------------- static void Emit(Function & func) { if (!func.IsNull()) + { func.Execute(); + } } // -------------------------------------------------------------------------------------------- - template < typename A1 > - static void Emit(Function & func, A1 a1) + template < typename... Args > static void Emit(Function & func, Args&&... args) { if (!func.IsNull()) - func.Execute(a1); - } - - // -------------------------------------------------------------------------------------------- - template < typename A1, typename A2 > - static void Emit(Function & func, A1 a1, A2 a2) - { - if (!func.IsNull()) - func.Execute(a1, a2); - } - - // -------------------------------------------------------------------------------------------- - template < typename A1, typename A2, typename A3 > - static void Emit(Function & func, A1 a1, A2 a2, A3 a3) - { - if (!func.IsNull()) - func.Execute(a1, a2, a3); - } - - // -------------------------------------------------------------------------------------------- - template < typename A1, typename A2, typename A3, typename A4 > - static void Emit(Function & func, A1 a1, A2 a2, A3 a3, A4 a4) - { - if (!func.IsNull()) - func.Execute(a1, a2, a3, a4); - } - - // -------------------------------------------------------------------------------------------- - template < typename A1, typename A2, typename A3, typename A4, typename A5 > - static void Emit(Function & func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) - { - if (!func.IsNull()) - func.Execute(a1, a2, a3, a4, a5); - } - - // -------------------------------------------------------------------------------------------- - template < typename A1, typename A2, typename A3, typename A4, typename A5, typename A6 > - static void Emit(Function & func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) - { - if (!func.IsNull()) - func.Execute(a1, a2, a3, a4, a5, a6); + { + func.Execute(std::forward< Args >(args)...); + } } public: @@ -752,133 +643,138 @@ public: void DisconnectPlayer(Int32 id, Int32 header, Object & payload); /* -------------------------------------------------------------------------------------------- - * Event propagators. + * Server events. */ void EmitBlipCreated(Int32 blip, Int32 header, Object & payload); - void EmitCheckpointCreated(Int32 checkpoint, Int32 header, Object & payload); - void EmitForcefieldCreated(Int32 forcefield, Int32 header, Object & payload); + void EmitCheckpointCreated(Int32 forcefield, Int32 header, Object & payload); void EmitKeybindCreated(Int32 keybind, Int32 header, Object & payload); void EmitObjectCreated(Int32 object, Int32 header, Object & payload); void EmitPickupCreated(Int32 pickup, Int32 header, Object & payload); void EmitPlayerCreated(Int32 player, Int32 header, Object & payload); - void EmitSpriteCreated(Int32 sprite, Int32 header, Object & payload); - void EmitTextdrawCreated(Int32 textdraw, Int32 header, Object & payload); void EmitVehicleCreated(Int32 vehicle, Int32 header, Object & payload); void EmitBlipDestroyed(Int32 blip, Int32 header, Object & payload); - void EmitCheckpointDestroyed(Int32 checkpoint, Int32 header, Object & payload); - void EmitForcefieldDestroyed(Int32 forcefield, Int32 header, Object & payload); + void EmitCheckpointDestroyed(Int32 forcefield, Int32 header, Object & payload); void EmitKeybindDestroyed(Int32 keybind, Int32 header, Object & payload); void EmitObjectDestroyed(Int32 object, Int32 header, Object & payload); void EmitPickupDestroyed(Int32 pickup, Int32 header, Object & payload); void EmitPlayerDestroyed(Int32 player, Int32 header, Object & payload); - void EmitSpriteDestroyed(Int32 sprite, Int32 header, Object & payload); - void EmitTextdrawDestroyed(Int32 textdraw, Int32 header, Object & payload); void EmitVehicleDestroyed(Int32 vehicle, Int32 header, Object & payload); void EmitBlipCustom(Int32 blip, Int32 header, Object & payload); - void EmitCheckpointCustom(Int32 checkpoint, Int32 header, Object & payload); - void EmitForcefieldCustom(Int32 forcefield, Int32 header, Object & payload); + void EmitCheckpointCustom(Int32 forcefield, Int32 header, Object & payload); void EmitKeybindCustom(Int32 keybind, Int32 header, Object & payload); void EmitObjectCustom(Int32 object, Int32 header, Object & payload); void EmitPickupCustom(Int32 pickup, Int32 header, Object & payload); void EmitPlayerCustom(Int32 player, Int32 header, Object & payload); - void EmitSpriteCustom(Int32 sprite, Int32 header, Object & payload); - void EmitTextdrawCustom(Int32 textdraw, Int32 header, Object & payload); void EmitVehicleCustom(Int32 vehicle, Int32 header, Object & payload); - void EmitPlayerAway(Int32 player, bool status); - void EmitPlayerGameKeys(Int32 player, Int32 previous, Int32 current); - void EmitPlayerRename(Int32 player, CCStr previous, CCStr current); - void EmitPlayerRequestClass(Int32 player, Int32 offset); - void EmitPlayerRequestSpawn(Int32 player); - void EmitPlayerSpawn(Int32 player); - void EmitPlayerStartTyping(Int32 player); - void EmitPlayerStopTyping(Int32 player); - void EmitPlayerChat(Int32 player, CCStr message); - void EmitPlayerCommand(Int32 player, CCStr command); - void EmitPlayerMessage(Int32 player, Int32 receiver, CCStr message); - void EmitPlayerHealth(Int32 player, Float32 previous, Float32 current); - void EmitPlayerArmour(Int32 player, Float32 previous, Float32 current); - void EmitPlayerWeapon(Int32 player, Int32 previous, Int32 current); - void EmitPlayerMove(Int32 player, const Vector3 & previous, const Vector3 & current); - void EmitPlayerWasted(Int32 player, Int32 reason); - void EmitPlayerKilled(Int32 player, Int32 killer, Int32 reason, Int32 body_part); - void EmitPlayerTeamKill(Int32 player, Int32 killer, Int32 reason, Int32 body_part); - void EmitPlayerSpectate(Int32 player, Int32 target); - void EmitPlayerCrashreport(Int32 player, CCStr report); - void EmitPlayerBurning(Int32 player, bool state); - void EmitPlayerCrouching(Int32 player, bool state); - void EmitPlayerState(Int32 player, Int32 previous, Int32 current); - void EmitPlayerAction(Int32 player, Int32 previous, Int32 current); - void EmitStateNone(Int32 player, Int32 previous); - void EmitStateNormal(Int32 player, Int32 previous); - void EmitStateShooting(Int32 player, Int32 previous); - void EmitStateDriver(Int32 player, Int32 previous); - void EmitStatePassenger(Int32 player, Int32 previous); - void EmitStateEnterDriver(Int32 player, Int32 previous); - void EmitStateEnterPassenger(Int32 player, Int32 previous); - void EmitStateExitVehicle(Int32 player, Int32 previous); - void EmitStateUnspawned(Int32 player, Int32 previous); - void EmitActionNone(Int32 player, Int32 previous); - void EmitActionNormal(Int32 player, Int32 previous); - void EmitActionAiming(Int32 player, Int32 previous); - void EmitActionShooting(Int32 player, Int32 previous); - void EmitActionJumping(Int32 player, Int32 previous); - void EmitActionLieDown(Int32 player, Int32 previous); - void EmitActionGettingUp(Int32 player, Int32 previous); - void EmitActionJumpVehicle(Int32 player, Int32 previous); - void EmitActionDriving(Int32 player, Int32 previous); - void EmitActionDying(Int32 player, Int32 previous); - void EmitActionWasted(Int32 player, Int32 previous); - void EmitActionEmbarking(Int32 player, Int32 previous); - void EmitActionDisembarking(Int32 player, Int32 previous); - void EmitVehicleRespawn(Int32 vehicle); - void EmitVehicleExplode(Int32 vehicle); - void EmitVehicleHealth(Int32 vehicle, Float32 previous, Float32 current); - void EmitVehicleMove(Int32 vehicle, const Vector3 & previous, const Vector3 & current); - void EmitPickupRespawn(Int32 pickup); - void EmitPlayerKeyPress(Int32 player, Int32 keybind); - void EmitPlayerKeyRelease(Int32 player, Int32 keybind); - void EmitPlayerEmbarking(Int32 player, Int32 vehicle, Int32 slot); - void EmitPlayerEmbarked(Int32 player, Int32 vehicle, Int32 slot); - void EmitPlayerDisembark(Int32 player, Int32 vehicle); - void EmitPickupClaimed(Int32 player, Int32 pickup); - void EmitPickupCollected(Int32 player, Int32 pickup); - void EmitObjectShot(Int32 player, Int32 object, Int32 weapon); - void EmitObjectBump(Int32 player, Int32 object); - void EmitCheckpointEntered(Int32 player, Int32 checkpoint); - void EmitCheckpointExited(Int32 player, Int32 checkpoint); - void EmitForcefieldEntered(Int32 player, Int32 forcefield); - void EmitForcefieldExited(Int32 player, Int32 forcefield); - void EmitServerFrame(Float32 delta); void EmitServerStartup(); void EmitServerShutdown(); - void EmitInternalCommand(Int32 type, CCStr text); - void EmitLoginAttempt(CCStr name, CCStr passwd, CCStr ip); - void EmitCustomEvent(Int32 group, Int32 header, Object & payload); - void EmitWorldOption(Int32 option, Object & value); - void EmitWorldToggle(Int32 option, bool value); - void EmitScriptReload(Int32 header, Object & payload); - void EmitScriptLoaded(); - void EmitPlayerUpdate(Int32 player, Int32 type); - void EmitVehicleUpdate(Int32 vehicle, Int32 type); - void EmitEntityPool(Int32 type, Int32 id, bool deleted); + void EmitServerFrame(Float32 elapsed_time); + void EmitPluginCommand(Uint32 command_identifier, CCStr message); + void EmitIncomingConnection(CStr player_name, size_t name_buffer_size, CCStr user_password, CCStr ip_address); + void EmitPlayerRequestClass(Int32 player_id, Int32 offset); + void EmitPlayerRequestSpawn(Int32 player_id); + void EmitPlayerSpawn(Int32 player_id); + void EmitPlayerWasted(Int32 player_id, Int32 reason); + void EmitPlayerKilled(Int32 player_id, Int32 killer_id, Int32 reason, vcmpBodyPart body_part, bool team_kill); + void EmitPlayerEmbarking(Int32 player_id, Int32 vehicle_id, Int32 slot_index); + void EmitPlayerEmbarked(Int32 player_id, Int32 vehicle_id, Int32 slot_index); + void EmitPlayerDisembark(Int32 player_id, Int32 vehicle_id); + void EmitPlayerRename(Int32 player_id, CCStr old_name, CCStr new_name); + void EmitPlayerState(Int32 player_id, Int32 old_state, Int32 new_state); + void EmitStateNone(Int32 player_id, Int32 old_state); + void EmitStateNormal(Int32 player_id, Int32 old_state); + void EmitStateAim(Int32 player_id, Int32 old_state); + void EmitStateDriver(Int32 player_id, Int32 old_state); + void EmitStatePassenger(Int32 player_id, Int32 old_state); + void EmitStateEnterDriver(Int32 player_id, Int32 old_state); + void EmitStateEnterPassenger(Int32 player_id, Int32 old_state); + void EmitStateExit(Int32 player_id, Int32 old_state); + void EmitStateUnspawned(Int32 player_id, Int32 old_state); + void EmitPlayerAction(Int32 player_id, Int32 old_action, Int32 new_action); + void EmitActionNone(Int32 player_id, Int32 old_action); + void EmitActionNormal(Int32 player_id, Int32 old_action); + void EmitActionAiming(Int32 player_id, Int32 old_action); + void EmitActionShooting(Int32 player_id, Int32 old_action); + void EmitActionJumping(Int32 player_id, Int32 old_action); + void EmitActionLieDown(Int32 player_id, Int32 old_action); + void EmitActionGettingUp(Int32 player_id, Int32 old_action); + void EmitActionJumpVehicle(Int32 player_id, Int32 old_action); + void EmitActionDriving(Int32 player_id, Int32 old_action); + void EmitActionDying(Int32 player_id, Int32 old_action); + void EmitActionWasted(Int32 player_id, Int32 old_action); + void EmitActionEmbarking(Int32 player_id, Int32 old_action); + void EmitActionDisembarking(Int32 player_id, Int32 old_action); + void EmitPlayerBurning(Int32 player_id, bool is_on_fire); + void EmitPlayerCrouching(Int32 player_id, bool is_crouching); + void EmitPlayerGameKeys(Int32 player_id, Uint32 old_keys, Uint32 new_keys); + void EmitPlayerStartTyping(Int32 player_id); + void EmitPlayerStopTyping(Int32 player_id); + void EmitPlayerAway(Int32 player_id, bool is_away); + void EmitPlayerMessage(Int32 player_id, CCStr message); + void EmitPlayerCommand(Int32 player_id, CCStr message); + void EmitPlayerPrivateMessage(Int32 player_id, Int32 target_player_id, CCStr message); + void EmitPlayerKeyPress(Int32 player_id, Int32 bind_id); + void EmitPlayerKeyRelease(Int32 player_id, Int32 bind_id); + void EmitPlayerSpectate(Int32 player_id, Int32 target_player_id); + void EmitPlayerCrashreport(Int32 player_id, CCStr report); + void EmitVehicleExplode(Int32 vehicle_id); + void EmitVehicleRespawn(Int32 vehicle_id); + void EmitObjectShot(Int32 object_id, Int32 player_id, Int32 weapon_id); + void EmitObjectTouched(Int32 object_id, Int32 player_id); + void EmitPickupClaimed(Int32 pickup_id, Int32 player_id); + void EmitPickupCollected(Int32 pickup_id, Int32 player_id); + void EmitPickupRespawn(Int32 pickup_id); + void EmitCheckpointEntered(Int32 forcefield_id, Int32 player_id); + void EmitCheckpointExited(Int32 forcefield_id, Int32 player_id); /* -------------------------------------------------------------------------------------------- - * Retrie global event bidings. + * Miscellaneous events. + */ + void EmitPlayerHealth(Int32 player_id, Float32 old_health, Float32 new_health); + void EmitPlayerArmour(Int32 player_id, Float32 old_armour, Float32 new_armour); + void EmitPlayerWeapon(Int32 player_id, Int32 old_weapon, Int32 new_weapon); + void EmitPlayerHeading(Int32 player_id, Float32 old_heading, Float32 new_heading); + void EmitPlayerPosition(Int32 player_id); + void EmitPlayerOption(Int32 player_id, Int32 option_id, bool value, Int32 header, Object & payload); + void EmitVehicleColour(Int32 vehicle_id, Int32 changed); + void EmitVehicleHealth(Int32 vehicle_id, Float32 old_health, Float32 new_health); + void EmitVehiclePosition(Int32 vehicle_id); + void EmitVehicleRotation(Int32 vehicle_id); + void EmitVehicleOption(Int32 vehicle_id, Int32 option_id, bool value, Int32 header, Object & payload); + void EmitServerOption(Int32 option, bool value, Int32 header, Object & payload); + void EmitScriptReload(Int32 header, Object & payload); + void EmitScriptLoaded(); + + /* -------------------------------------------------------------------------------------------- + * Entity pool changes events. + */ + void EmitEntityPool(vcmpEntityPool entity_type, Int32 entity_id, bool is_deleted); + + /* -------------------------------------------------------------------------------------------- + * Entity update events. + */ + void EmitPlayerUpdate(Int32 player_id, vcmpPlayerUpdate update_type); + void EmitVehicleUpdate(Int32 vehicle_id, vcmpVehicleUpdate update_type); + + /* -------------------------------------------------------------------------------------------- + * Client data streams event. + */ + void EmitClientScriptData(Int32 player_id, const uint8_t * data, size_t size); + + /* -------------------------------------------------------------------------------------------- + * Retrieve global event bindings. */ Function & GetEvent(Int32 evid); /* -------------------------------------------------------------------------------------------- - * Retrie local event bidings. + * Retrieve local event bindings. */ Function & GetBlipEvent(Int32 id, Int32 evid); Function & GetCheckpointEvent(Int32 id, Int32 evid); - Function & GetForcefieldEvent(Int32 id, Int32 evid); Function & GetKeybindEvent(Int32 id, Int32 evid); Function & GetObjectEvent(Int32 id, Int32 evid); Function & GetPickupEvent(Int32 id, Int32 evid); Function & GetPlayerEvent(Int32 id, Int32 evid); - Function & GetSpriteEvent(Int32 id, Int32 evid); - Function & GetTextdrawEvent(Int32 id, Int32 evid); Function & GetVehicleEvent(Int32 id, Int32 evid); private: @@ -886,69 +782,52 @@ private: /* -------------------------------------------------------------------------------------------- * Global event bindings. */ + Function mOnCustomEvent; Function mOnBlipCreated; Function mOnCheckpointCreated; - Function mOnForcefieldCreated; Function mOnKeybindCreated; Function mOnObjectCreated; Function mOnPickupCreated; Function mOnPlayerCreated; - Function mOnSpriteCreated; - Function mOnTextdrawCreated; Function mOnVehicleCreated; Function mOnBlipDestroyed; Function mOnCheckpointDestroyed; - Function mOnForcefieldDestroyed; Function mOnKeybindDestroyed; Function mOnObjectDestroyed; Function mOnPickupDestroyed; Function mOnPlayerDestroyed; - Function mOnSpriteDestroyed; - Function mOnTextdrawDestroyed; Function mOnVehicleDestroyed; Function mOnBlipCustom; Function mOnCheckpointCustom; - Function mOnForcefieldCustom; Function mOnKeybindCustom; Function mOnObjectCustom; Function mOnPickupCustom; Function mOnPlayerCustom; - Function mOnSpriteCustom; - Function mOnTextdrawCustom; Function mOnVehicleCustom; - Function mOnPlayerAway; - Function mOnPlayerGameKeys; - Function mOnPlayerRename; + Function mOnServerStartup; + Function mOnServerShutdown; + Function mOnServerFrame; + Function mOnIncomingConnection; Function mOnPlayerRequestClass; Function mOnPlayerRequestSpawn; Function mOnPlayerSpawn; - Function mOnPlayerStartTyping; - Function mOnPlayerStopTyping; - Function mOnPlayerChat; - Function mOnPlayerCommand; - Function mOnPlayerMessage; - Function mOnPlayerHealth; - Function mOnPlayerArmour; - Function mOnPlayerWeapon; - Function mOnPlayerMove; Function mOnPlayerWasted; Function mOnPlayerKilled; - Function mOnPlayerTeamKill; - Function mOnPlayerSpectate; - Function mOnPlayerCrashreport; - Function mOnPlayerBurning; - Function mOnPlayerCrouching; + Function mOnPlayerEmbarking; + Function mOnPlayerEmbarked; + Function mOnPlayerDisembark; + Function mOnPlayerRename; Function mOnPlayerState; - Function mOnPlayerAction; Function mOnStateNone; Function mOnStateNormal; - Function mOnStateShooting; + Function mOnStateAim; Function mOnStateDriver; Function mOnStatePassenger; Function mOnStateEnterDriver; Function mOnStateEnterPassenger; - Function mOnStateExitVehicle; + Function mOnStateExit; Function mOnStateUnspawned; + Function mOnPlayerAction; Function mOnActionNone; Function mOnActionNormal; Function mOnActionAiming; @@ -962,32 +841,44 @@ private: Function mOnActionWasted; Function mOnActionEmbarking; Function mOnActionDisembarking; - Function mOnVehicleRespawn; + Function mOnPlayerBurning; + Function mOnPlayerCrouching; + Function mOnPlayerGameKeys; + Function mOnPlayerStartTyping; + Function mOnPlayerStopTyping; + Function mOnPlayerAway; + Function mOnPlayerMessage; + Function mOnPlayerCommand; + Function mOnPlayerPrivateMessage; + Function mOnPlayerKeyPress; + Function mOnPlayerKeyRelease; + Function mOnPlayerSpectate; + Function mOnPlayerCrashreport; Function mOnVehicleExplode; - Function mOnVehicleHealth; - Function mOnVehicleMove; - Function mOnPickupRespawn; - Function mOnKeybindKeyPress; - Function mOnKeybindKeyRelease; - Function mOnVehicleEmbarking; - Function mOnVehicleEmbarked; - Function mOnVehicleDisembark; + Function mOnVehicleRespawn; + Function mOnObjectShot; + Function mOnObjectTouched; Function mOnPickupClaimed; Function mOnPickupCollected; - Function mOnObjectShot; - Function mOnObjectBump; + Function mOnPickupRespawn; Function mOnCheckpointEntered; Function mOnCheckpointExited; - Function mOnForcefieldEntered; - Function mOnForcefieldExited; - Function mOnServerFrame; - Function mOnServerStartup; - Function mOnServerShutdown; - Function mOnInternalCommand; - Function mOnLoginAttempt; - Function mOnCustomEvent; - Function mOnWorldOption; - Function mOnWorldToggle; + Function mOnEntityPool; + Function mOnClientScriptData; + Function mOnPlayerUpdate; + Function mOnVehicleUpdate; + Function mOnPlayerHealth; + Function mOnPlayerArmour; + Function mOnPlayerWeapon; + Function mOnPlayerHeading; + Function mOnPlayerPosition; + Function mOnPlayerOption; + Function mOnVehicleColour; + Function mOnVehicleHealth; + Function mOnVehiclePosition; + Function mOnVehicleRotation; + Function mOnVehicleOption; + Function mOnServerOption; Function mOnScriptReload; Function mOnScriptLoaded; }; diff --git a/source/CoreEntity.cpp b/source/CoreEntity.cpp new file mode 100644 index 00000000..8624716a --- /dev/null +++ b/source/CoreEntity.cpp @@ -0,0 +1,963 @@ +// ------------------------------------------------------------------------------------------------ +#include "Core.hpp" + +// ------------------------------------------------------------------------------------------------ +#include "Entity/Blip.hpp" +#include "Entity/Checkpoint.hpp" +#include "Entity/Keybind.hpp" +#include "Entity/Object.hpp" +#include "Entity/Pickup.hpp" +#include "Entity/Player.hpp" +#include "Entity/Vehicle.hpp" + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +// -------------------------------------------------------------------------------------------- +void Core::ImportBlips() +{ + // Information about the blip entity + Int32 world = -1, scale = -1, sprid = -1; + Uint32 color = 0; + Float32 x = 0.0, y = 0.0, z = 0.0; + + for (Int32 i = 0; i < SQMOD_BLIP_POOL; ++i) + { + // See if this entity exists on the server and whether was not allocated already + if (_Func->CheckEntityExists(vcmpEntityPoolBlip, i) && INVALID_ENTITY(m_Blips[i].mID)) + { + _Func->GetCoordBlipInfo(i, &world, &x, &y, &z, &scale, &color, &sprid); + // Make the properties available before triggering the event + m_Blips[i].mWorld = world; + m_Blips[i].mScale = scale; + m_Blips[i].mSprID = sprid; + m_Blips[i].mPosition.Set(x, y, z); + m_Blips[i].mColor.SetRGBA(color); + // Attempt to allocate the instance + AllocBlip(i, false, SQMOD_CREATE_IMPORT, NullObject()); + } + } +} + +// ------------------------------------------------------------------------------------------------ +void Core::ImportCheckpoints() +{ + for (Int32 i = 0; i < SQMOD_CHECKPOINT_POOL; ++i) + { + // See if this entity exists on the server and whether was not allocated already + if (_Func->CheckEntityExists(vcmpEntityPoolCheckPoint, i) && INVALID_ENTITY(m_Checkpoints[i].mID)) + { + AllocCheckpoint(i, false, SQMOD_CREATE_IMPORT, NullObject()); + } + } +} + +// ------------------------------------------------------------------------------------------------ +void Core::ImportKeybinds() +{ + // Information about the key-bind entity + Uint8 release = 0; + Int32 first = -1, second = -1, third = -1; + + for (Int32 i = 0; i < SQMOD_KEYBIND_POOL; ++i) + { + // See if this entity exists on the server and whether was not allocated already + if ((_Func->GetKeyBindData(i, &release, &first, &second, &third) != vcmpErrorNoSuchEntity) + && (INVALID_ENTITY(m_Keybinds[i].mID))) + { + // Make the properties available before triggering the event + m_Keybinds[i].mFirst = first; + m_Keybinds[i].mSecond = second; + m_Keybinds[i].mThird = third; + m_Keybinds[i].mRelease = release; + // Attempt to allocate the instance + AllocKeybind(i, false, SQMOD_CREATE_IMPORT, NullObject()); + } + } +} + +// ------------------------------------------------------------------------------------------------ +void Core::ImportObjects() +{ + for (Int32 i = 0; i < SQMOD_OBJECT_POOL; ++i) + { + // See if this entity exists on the server and whether was not allocated already + if (_Func->CheckEntityExists(vcmpEntityPoolObject, i) && INVALID_ENTITY(m_Objects[i].mID)) + { + AllocObject(i, false, SQMOD_CREATE_IMPORT, NullObject()); + } + } +} + +// ------------------------------------------------------------------------------------------------ +void Core::ImportPickups() +{ + for (Int32 i = 0; i < SQMOD_PICKUP_POOL; ++i) + { + // See if this entity exists on the server and whether was not allocated already + if (_Func->CheckEntityExists(vcmpEntityPoolPickup, i) && (INVALID_ENTITY(m_Pickups[i].mID))) + { + AllocPickup(i, false, SQMOD_CREATE_IMPORT, NullObject()); + } + } +} + +// ------------------------------------------------------------------------------------------------ +void Core::ImportPlayers() +{ + for (Int32 i = 0; i < SQMOD_PLAYER_POOL; ++i) + { + // See if this entity exists on the server and whether was not allocated already + if (_Func->IsPlayerConnected(i) && (INVALID_ENTITY(m_Players[i].mID))) + { + ConnectPlayer(i, SQMOD_CREATE_IMPORT, NullObject()); + } + } +} + +// ------------------------------------------------------------------------------------------------ +void Core::ImportVehicles() +{ + for (Int32 i = 0; i < SQMOD_VEHICLE_POOL; ++i) + { + // See if this entity exists on the server and whether was not allocated already + if (_Func->CheckEntityExists(vcmpEntityPoolVehicle, i) && INVALID_ENTITY(m_Vehicles[i].mID)) + { + AllocVehicle(i, false, SQMOD_CREATE_IMPORT, NullObject()); + } + } +} + +// -------------------------------------------------------------------------------------------- +Object & Core::AllocBlip(Int32 id, bool owned, Int32 header, Object & payload) +{ + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(id, SQMOD_BLIP_POOL)) + { + STHROWF("Cannot allocate blip with invalid identifier: %d", id); + } + // Retrieve the specified entity instance + BlipInst & inst = m_Blips[id]; + // Make sure that the instance isn't already allocated + if (VALID_ENTITY(inst.mID)) + { + return inst.mObj; // Return the existing instance + } + // Instantiate the entity manager + inst.mInst = new CBlip(id); + // Create the script object + inst.mObj = Object(inst.mInst, m_VM); + // Make sure that both the instance and script object could be created + if (!inst.mInst || inst.mObj.IsNull()) + { + ResetInst(inst); + STHROWF("Unable to create a blip instance for: %d", id); + } + // Assign the specified entity identifier + inst.mID = id; + // Specify whether the entity is owned by this plug-in + if (owned) + { + inst.mFlags |= ENF_OWNED; + } + else if (inst.mFlags & ENF_OWNED) + { + inst.mFlags ^= ENF_OWNED; + } + // Let the script callbacks know about this entity + EmitBlipCreated(id, header, payload); + // Return the script object + return inst.mObj; +} + +// -------------------------------------------------------------------------------------------- +Object & Core::AllocCheckpoint(Int32 id, bool owned, Int32 header, Object & payload) +{ + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(id, SQMOD_CHECKPOINT_POOL)) + { + STHROWF("Cannot allocate checkpoint with invalid identifier: %d", id); + } + // Retrieve the specified entity instance + CheckpointInst & inst = m_Checkpoints[id]; + // Make sure that the instance isn't already allocated + if (VALID_ENTITY(inst.mID)) + { + return inst.mObj; // Return the existing instance + } + // Instantiate the entity manager + inst.mInst = new CCheckpoint(id); + // Create the script object + inst.mObj = Object(inst.mInst, m_VM); + // Make sure that both the instance and script object could be created + if (!inst.mInst || inst.mObj.IsNull()) + { + ResetInst(inst); + STHROWF("Unable to create a checkpoint instance for: %d", id); + } + // Assign the specified entity identifier + inst.mID = id; + // Specify whether the entity is owned by this plug-in + if (owned) + { + inst.mFlags |= ENF_OWNED; + } + else if (inst.mFlags & ENF_OWNED) + { + inst.mFlags ^= ENF_OWNED; + } + // Let the script callbacks know about this entity + EmitCheckpointCreated(id, header, payload); + // Return the script object + return inst.mObj; +} + +// -------------------------------------------------------------------------------------------- +Object & Core::AllocKeybind(Int32 id, bool owned, Int32 header, Object & payload) +{ + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(id, SQMOD_KEYBIND_POOL)) + { + STHROWF("Cannot allocate keybind with invalid identifier: %d", id); + } + // Retrieve the specified entity instance + KeybindInst & inst = m_Keybinds[id]; + // Make sure that the instance isn't already allocated + if (VALID_ENTITY(inst.mID)) + { + return inst.mObj; // Return the existing instance + } + // Instantiate the entity manager + inst.mInst = new CKeybind(id); + // Create the script object + inst.mObj = Object(inst.mInst, m_VM); + // Make sure that both the instance and script object could be created + if (!inst.mInst || inst.mObj.IsNull()) + { + ResetInst(inst); + STHROWF("Unable to create a keybind instance for: %d", id); + } + // Assign the specified entity identifier + inst.mID = id; + // Specify whether the entity is owned by this plug-in + if (owned) + { + inst.mFlags |= ENF_OWNED; + } + else if (inst.mFlags & ENF_OWNED) + { + inst.mFlags ^= ENF_OWNED; + } + // Let the script callbacks know about this entity + EmitKeybindCreated(id, header, payload); + // Return the script object + return inst.mObj; +} + +// -------------------------------------------------------------------------------------------- +Object & Core::AllocObject(Int32 id, bool owned, Int32 header, Object & payload) +{ + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(id, SQMOD_OBJECT_POOL)) + { + STHROWF("Cannot allocate object with invalid identifier: %d", id); + } + // Retrieve the specified entity instance + ObjectInst & inst = m_Objects[id]; + // Make sure that the instance isn't already allocated + if (VALID_ENTITY(inst.mID)) + { + return inst.mObj; // Return the existing instance + } + // Instantiate the entity manager + inst.mInst = new CObject(id); + // Create the script object + inst.mObj = Object(inst.mInst, m_VM); + // Make sure that both the instance and script object could be created + if (!inst.mInst || inst.mObj.IsNull()) + { + ResetInst(inst); + STHROWF("Unable to create a object instance for: %d", id); + } + // Assign the specified entity identifier + inst.mID = id; + // Specify whether the entity is owned by this plug-in + if (owned) + { + inst.mFlags |= ENF_OWNED; + } + else if (inst.mFlags & ENF_OWNED) + { + inst.mFlags ^= ENF_OWNED; + } + // Let the script callbacks know about this entity + EmitObjectCreated(id, header, payload); + // Return the script object + return inst.mObj; +} + +// -------------------------------------------------------------------------------------------- +Object & Core::AllocPickup(Int32 id, bool owned, Int32 header, Object & payload) +{ + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(id, SQMOD_PICKUP_POOL)) + { + STHROWF("Cannot allocate pickup with invalid identifier: %d", id); + } + // Retrieve the specified entity instance + PickupInst & inst = m_Pickups[id]; + // Make sure that the instance isn't already allocated + if (VALID_ENTITY(inst.mID)) + { + return inst.mObj; // Return the existing instance + } + // Instantiate the entity manager + inst.mInst = new CPickup(id); + // Create the script object + inst.mObj = Object(inst.mInst, m_VM); + // Make sure that both the instance and script object could be created + if (!inst.mInst || inst.mObj.IsNull()) + { + ResetInst(inst); + STHROWF("Unable to create a pickup instance for: %d", id); + } + // Assign the specified entity identifier + inst.mID = id; + // Specify whether the entity is owned by this plug-in + if (owned) + { + inst.mFlags |= ENF_OWNED; + } + else if (inst.mFlags & ENF_OWNED) + { + inst.mFlags ^= ENF_OWNED; + } + // Let the script callbacks know about this entity + EmitPickupCreated(id, header, payload); + // Return the script object + return inst.mObj; +} + +// -------------------------------------------------------------------------------------------- +Object & Core::AllocVehicle(Int32 id, bool owned, Int32 header, Object & payload) +{ + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(id, SQMOD_VEHICLE_POOL)) + { + STHROWF("Cannot allocate vehicle with invalid identifier: %d", id); + } + // Retrieve the specified entity instance + VehicleInst & inst = m_Vehicles[id]; + // Make sure that the instance isn't already allocated + if (VALID_ENTITY(inst.mID)) + { + return inst.mObj; // Return the existing instance + } + // Instantiate the entity manager + inst.mInst = new CVehicle(id); + // Create the script object + inst.mObj = Object(inst.mInst, m_VM); + // Make sure that both the instance and script object could be created + if (!inst.mInst || inst.mObj.IsNull()) + { + ResetInst(inst); + STHROWF("Unable to create a vehicle instance for: %d", id); + } + // Assign the specified entity identifier + inst.mID = id; + // Specify whether the entity is owned by this plug-in + if (owned) + { + inst.mFlags |= ENF_OWNED; + } + else if (inst.mFlags & ENF_OWNED) + { + inst.mFlags ^= ENF_OWNED; + } + // Let the script callbacks know about this entity + EmitVehicleCreated(id, header, payload); + // Return the script object + return inst.mObj; +} + +// -------------------------------------------------------------------------------------------- +void Core::DeallocBlip(Int32 id, bool destroy, Int32 header, Object & payload) +{ + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(id, SQMOD_BLIP_POOL)) + { + STHROWF("Cannot deallocate blip with invalid identifier: %d", id); + } + // Retrieve the specified entity instance + BlipInst & inst = m_Blips[id]; + // Make sure that the instance is even allocated + if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED)) + { + return; // Nothing to deallocate! + } + // Prevent further attempts to delete this entity + const BitGuardU16 bg(inst.mFlags, static_cast< Uint16 >(ENF_LOCKED)); + // Let the script callbacks know this entity should no longer be used + try + { + EmitBlipDestroyed(id, header, payload); + } + catch (...) + { + // The error was probably dealt with already + } + // Is there a manager instance associated with this entity? + if (inst.mInst) + { + // Prevent further use of this entity + inst.mInst->m_ID = -1; + // Release user data to avoid dangling or circular references + inst.mInst->m_Data.Release(); + } + // Should we delete this entity from the server as well? + if (destroy || (inst.mFlags & ENF_OWNED)) + { + _Func->DestroyCoordBlip(inst.mID); + } + // Reset the entity instance + ResetInst(inst); + // Release associated script callbacks + ResetFunc(inst); + // Prevent further use of the manager instance + inst.mInst = nullptr; + // Release the script object, if any + inst.mObj.Release(); +} + +// -------------------------------------------------------------------------------------------- +void Core::DeallocCheckpoint(Int32 id, bool destroy, Int32 header, Object & payload) +{ + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(id, SQMOD_CHECKPOINT_POOL)) + { + STHROWF("Cannot deallocate checkpoint with invalid identifier: %d", id); + } + // Retrieve the specified entity instance + CheckpointInst & inst = m_Checkpoints[id]; + // Make sure that the instance is even allocated + if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED)) + { + return; // Nothing to deallocate! + } + // Prevent further attempts to delete this entity + const BitGuardU16 bg(inst.mFlags, static_cast< Uint16 >(ENF_LOCKED)); + // Let the script callbacks know this entity should no longer be used + try + { + EmitCheckpointDestroyed(id, header, payload); + } + catch (...) + { + // The error was probably dealt with already + } + // Is there a manager instance associated with this entity? + if (inst.mInst) + { + // Prevent further use of this entity + inst.mInst->m_ID = -1; + // Release user data to avoid dangling or circular references + inst.mInst->m_Data.Release(); + } + // Should we delete this entity from the server as well? + if (destroy || (inst.mFlags & ENF_OWNED)) + { + _Func->DeleteCheckPoint(inst.mID); + } + // Reset the entity instance + ResetInst(inst); + // Release associated script callbacks + ResetFunc(inst); + // Prevent further use of the manager instance + inst.mInst = nullptr; + // Release the script object, if any + inst.mObj.Release(); +} + +// -------------------------------------------------------------------------------------------- +void Core::DeallocKeybind(Int32 id, bool destroy, Int32 header, Object & payload) +{ + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(id, SQMOD_KEYBIND_POOL)) + { + STHROWF("Cannot deallocate keybind with invalid identifier: %d", id); + } + // Retrieve the specified entity instance + KeybindInst & inst = m_Keybinds[id]; + // Make sure that the instance is even allocated + if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED)) + { + return; // Nothing to deallocate! + } + // Prevent further attempts to delete this entity + const BitGuardU16 bg(inst.mFlags, static_cast< Uint16 >(ENF_LOCKED)); + // Let the script callbacks know this entity should no longer be used + try + { + EmitBlipDestroyed(id, header, payload); + } + catch (...) + { + // The error was dealt with already + } + // Is there a manager instance associated with this entity? + if (inst.mInst) + { + // Prevent further use of this entity + inst.mInst->m_ID = -1; + // Release user data to avoid dangling or circular references + inst.mInst->m_Data.Release(); + } + // Should we delete this entity from the server as well? + if (destroy || (inst.mFlags & ENF_OWNED)) + { + _Func->RemoveKeyBind(inst.mID); + } + // Reset the entity instance + ResetInst(inst); + // Release associated script callbacks + ResetFunc(inst); + // Prevent further use of the manager instance + inst.mInst = nullptr; + // Release the script object, if any + inst.mObj.Release(); +} + +// -------------------------------------------------------------------------------------------- +void Core::DeallocObject(Int32 id, bool destroy, Int32 header, Object & payload) +{ + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(id, SQMOD_OBJECT_POOL)) + { + STHROWF("Cannot deallocate object with invalid identifier: %d", id); + } + // Retrieve the specified entity instance + ObjectInst & inst = m_Objects[id]; + // Make sure that the instance is even allocated + if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED)) + { + return; // Nothing to deallocate! + } + // Prevent further attempts to delete this entity + const BitGuardU16 bg(inst.mFlags, static_cast< Uint16 >(ENF_LOCKED)); + // Let the script callbacks know this entity should no longer be used + try + { + EmitObjectDestroyed(id, header, payload); + } + catch (...) + { + // The error was probably dealt with already + } + // Is there a manager instance associated with this entity? + if (inst.mInst) + { + // Prevent further use of this entity + inst.mInst->m_ID = -1; + // Release user data to avoid dangling or circular references + inst.mInst->m_Data.Release(); + } + // Should we delete this entity from the server as well? + if (destroy || (inst.mFlags & ENF_OWNED)) + { + _Func->DeleteObject(inst.mID); + } + // Reset the entity instance + ResetInst(inst); + // Release associated script callbacks + ResetFunc(inst); + // Prevent further use of the manager instance + inst.mInst = nullptr; + // Release the script object, if any + inst.mObj.Release(); +} + +// -------------------------------------------------------------------------------------------- +void Core::DeallocPickup(Int32 id, bool destroy, Int32 header, Object & payload) +{ + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(id, SQMOD_PICKUP_POOL)) + { + STHROWF("Cannot deallocate pickup with invalid identifier: %d", id); + } + // Retrieve the specified entity instance + PickupInst & inst = m_Pickups[id]; + // Make sure that the instance is even allocated + if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED)) + { + return; // Nothing to deallocate! + } + // Prevent further attempts to delete this entity + const BitGuardU16 bg(inst.mFlags, static_cast< Uint16 >(ENF_LOCKED)); + // Let the script callbacks know this entity should no longer be used + try + { + EmitPickupDestroyed(id, header, payload); + } + catch (...) + { + // The error was probably dealt with already + } + // Is there a manager instance associated with this entity? + if (inst.mInst) + { + // Prevent further use of this entity + inst.mInst->m_ID = -1; + // Release user data to avoid dangling or circular references + inst.mInst->m_Data.Release(); + } + // Should we delete this entity from the server as well? + if (destroy || (inst.mFlags & ENF_OWNED)) + { + _Func->DeletePickup(inst.mID); + } + // Reset the entity instance + ResetInst(inst); + // Release associated script callbacks + ResetFunc(inst); + // Prevent further use of the manager instance + inst.mInst = nullptr; + // Release the script object, if any + inst.mObj.Release(); +} + +// -------------------------------------------------------------------------------------------- +void Core::DeallocVehicle(Int32 id, bool destroy, Int32 header, Object & payload) +{ + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(id, SQMOD_VEHICLE_POOL)) + { + STHROWF("Cannot deallocate vehicle with invalid identifier: %d", id); + } + // Retrieve the specified entity instance + VehicleInst & inst = m_Vehicles[id]; + // Make sure that the instance is even allocated + if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED)) + { + return; // Nothing to deallocate! + } + // Prevent further attempts to delete this entity + const BitGuardU16 bg(inst.mFlags, static_cast< Uint16 >(ENF_LOCKED)); + // Let the script callbacks know this entity should no longer be used + try + { + EmitVehicleDestroyed(id, header, payload); + } + catch (...) + { + // The error was probably dealt with already + } + // Is there a manager instance associated with this entity? + if (inst.mInst) + { + // Prevent further use of this entity + inst.mInst->m_ID = -1; + // Release user data to avoid dangling or circular references + inst.mInst->m_Data.Release(); + } + // Should we delete this entity from the server as well? + if (destroy || (inst.mFlags & ENF_OWNED)) + { + _Func->DeleteVehicle(inst.mID); + } + // Reset the entity instance + ResetInst(inst); + // Release associated script callbacks + ResetFunc(inst); + // Prevent further use of the manager instance + inst.mInst = nullptr; + // Release the script object, if any + inst.mObj.Release(); +} + +// -------------------------------------------------------------------------------------------- +Object & Core::NewBlip(Int32 index, Int32 world, Float32 x, Float32 y, Float32 z, + Int32 scale, Uint32 color, Int32 sprid, + Int32 header, Object & payload) +{ + // Request the server to create this entity + const Int32 id = _Func->CreateCoordBlip(index, world, x, y, z, scale, color, sprid); + // See if the entity creation failed on the server + if (_Func->GetLastError() == vcmpErrorPoolExhausted) + { + STHROWF("Blip pool was exhausted: %d", id); + } + // Validate the identifier returned by the server + else if (INVALID_ENTITYEX(id, SQMOD_BLIP_POOL)) + { + STHROWF("Server returned invalid blip: %d", id); + } + // Attempt to allocate this entity and return the result + return AllocBlip(id, true, header, payload); +} + +// -------------------------------------------------------------------------------------------- +Object & Core::NewCheckpoint(Int32 player, Int32 world, bool sphere, Float32 x, Float32 y, Float32 z, + Uint8 r, Uint8 g, Uint8 b, Uint8 a, Float32 radius, + Int32 header, Object & payload) +{ + // Request the server to create this entity + const Int32 id = _Func->CreateCheckPoint(player, world, sphere, x, y, z, r, g, b, a, radius); + // See if the entity creation failed on the server + if (_Func->GetLastError() == vcmpErrorNoSuchEntity) + { + STHROWF("Invalid player reference: %d", player); + } + else if (_Func->GetLastError() == vcmpErrorPoolExhausted) + { + STHROWF("Checkpoint pool was exhausted: %d", id); + } + // Validate the identifier returned by the server + else if (INVALID_ENTITYEX(id, SQMOD_CHECKPOINT_POOL)) + { + STHROWF("Server returned invalid checkpoint: %d", id); + } + // Attempt to allocate this entity and return the result + return AllocCheckpoint(id, true, header, payload); +} + +// -------------------------------------------------------------------------------------------- +Object & Core::NewKeybind(Int32 slot, bool release, Int32 primary, Int32 secondary, Int32 alternative, + Int32 header, Object & payload) +{ + // Request the server to create this entity + const Int32 id = _Func->RegisterKeyBind(slot, release, primary, secondary, alternative); + // See if the entity creation failed on the server + if (_Func->GetLastError() == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Out of bounds keybind argument: %d", id); + } + // Validate the identifier returned by the server + else if (INVALID_ENTITYEX(id, SQMOD_KEYBIND_POOL)) + { + STHROWF("Server returned invalid keybind: %d", id); + } + // Attempt to allocate this entity and return the result + return AllocKeybind(id, true, header, payload); +} + +// -------------------------------------------------------------------------------------------- +Object & Core::NewObject(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, Int32 alpha, + Int32 header, Object & payload) +{ + // Request the server to create this entity + const Int32 id = _Func->CreateObject(model, world, x, y, z, alpha); + // See if the entity creation failed on the server + if (_Func->GetLastError() == vcmpErrorPoolExhausted) + { + STHROWF("Object pool was exhausted: %d", id); + } + // Validate the identifier returned by the server + else if (INVALID_ENTITYEX(id, SQMOD_OBJECT_POOL)) + { + STHROWF("Server returned invalid object: %d", id); + } + // Attempt to allocate this entity and return the result + return AllocObject(id, true, header, payload); +} + +// -------------------------------------------------------------------------------------------- +Object & Core::NewPickup(Int32 model, Int32 world, Int32 quantity, + Float32 x, Float32 y, Float32 z, Int32 alpha, bool automatic, + Int32 header, Object & payload) +{ + // Request the server to create this entity + const Int32 id = _Func->CreatePickup(model, world, quantity, x, y, z, alpha, automatic); + // See if the entity creation failed on the server + if (_Func->GetLastError() == vcmpErrorPoolExhausted) + { + STHROWF("Pickup pool was exhausted: %d", id); + } + // Validate the identifier returned by the server + else if (INVALID_ENTITYEX(id, SQMOD_PICKUP_POOL)) + { + STHROWF("Server returned invalid pickup: %d", id); + } + // Attempt to allocate this entity and return the result + return AllocPickup(id, true, header, payload); +} + +// -------------------------------------------------------------------------------------------- +Object & Core::NewVehicle(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, + Float32 angle, Int32 primary, Int32 secondary, + Int32 header, Object & payload) +{ + // Request the server to create this entity + const Int32 id = _Func->CreateVehicle(model, world, x, y, z, angle, primary, secondary); + // See if the entity creation failed on the server + if (_Func->GetLastError() == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Out of bounds vehicle argument: %d", id); + } + else if (_Func->GetLastError() == vcmpErrorPoolExhausted) + { + STHROWF("Vehicle pool was exhausted: %d", id); + } + // Validate the identifier returned by the server + else if (INVALID_ENTITYEX(id, SQMOD_VEHICLE_POOL)) + { + STHROWF("Server returned invalid vehicle: %d", id); + } + // Attempt to allocate this entity and return the result + return AllocVehicle(id, true, header, payload); +} + +// -------------------------------------------------------------------------------------------- +bool Core::DelBlip(Int32 id, Int32 header, Object & payload) +{ + // Attempt to destroy and deallocate the specified entity instance + DeallocBlip(id, true, header, payload); + // The entity could be destroyed + return true; +} + +// ------------------------------------------------------------------------------------------------ +bool Core::DelCheckpoint(Int32 id, Int32 header, Object & payload) +{ + // Attempt to destroy and deallocate the specified entity instance + DeallocCheckpoint(id, true, header, payload); + // The entity could be destroyed + return true; +} + +// ------------------------------------------------------------------------------------------------ +bool Core::DelKeybind(Int32 id, Int32 header, Object & payload) +{ + // Attempt to destroy and deallocate the specified entity instance + DeallocKeybind(id, true, header, payload); + // The entity could be destroyed + return true; +} + +// ------------------------------------------------------------------------------------------------ +bool Core::DelObject(Int32 id, Int32 header, Object & payload) +{ + // Attempt to destroy and deallocate the specified entity instance + DeallocObject(id, true, header, payload); + // The entity could be destroyed + return true; +} + +// ------------------------------------------------------------------------------------------------ +bool Core::DelPickup(Int32 id, Int32 header, Object & payload) +{ + // Attempt to destroy and deallocate the specified entity instance + DeallocPickup(id, true, header, payload); + // The entity could be destroyed + return true; +} + +// ------------------------------------------------------------------------------------------------ +bool Core::DelVehicle(Int32 id, Int32 header, Object & payload) +{ + // Attempt to destroy and deallocate the specified entity instance + DeallocVehicle(id, true, header, payload); + // The entity could be destroyed + return true; +} + +// ------------------------------------------------------------------------------------------------ +void Core::BindEvent(Int32 id, Object & env, Function & func) +{ + // Obtain the function instance called for this event + Function & event = GetEvent(id); + // Is the specified callback function null? + if (func.IsNull()) + { + event.Release(); // Then release the current callback + } + // Assign the specified environment and function + else + { + event = Function(env.GetVM(), env, func.GetFunc()); + } +} + +// -------------------------------------------------------------------------------------------- +void Core::ConnectPlayer(Int32 id, Int32 header, Object & payload) +{ + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(id, SQMOD_PLAYER_POOL)) + { + STHROWF("Cannot allocate player with invalid identifier: %d", id); + } + // Retrieve the specified entity instance + PlayerInst & inst = m_Players[id]; + // Make sure that the instance isn't already allocated + if (VALID_ENTITY(inst.mID)) + { + return; // Nothing to allocate! + } + // Instantiate the entity manager + inst.mInst = new CPlayer(id); + // Create the script object + inst.mObj = Object(inst.mInst, m_VM); + // Make sure that both the instance and script object could be created + if (!inst.mInst || inst.mObj.IsNull()) + { + ResetInst(inst); + STHROWF("Unable to create a player instance for: %d", id); + } + // Assign the specified entity identifier + inst.mID = id; + // Initialize the position + _Func->GetPlayerPosition(id, &inst.mLastPosition.x, &inst.mLastPosition.y, &inst.mLastPosition.z); + // Initialize the remaining attributes + inst.mLastWeapon = _Func->GetPlayerWeapon(id); + inst.mLastHealth = _Func->GetPlayerHealth(id); + inst.mLastArmour = _Func->GetPlayerArmour(id); + inst.mLastHeading = _Func->GetPlayerHeading(id); + // Let the script callbacks know about this entity + EmitPlayerCreated(id, header, payload); +} + +void Core::DisconnectPlayer(Int32 id, Int32 header, Object & payload) +{ + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(id, SQMOD_PLAYER_POOL)) + { + STHROWF("Cannot deallocate player with invalid identifier: %d", id); + } + // Retrieve the specified entity instance + PlayerInst & inst = m_Players[id]; + // Make sure that the instance is even allocated and we're allowed to deallocate it + if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED)) + { + return; // Nothing to deallocate! + } + // Prevent further attempts to delete this entity + const BitGuardU16 bg(inst.mFlags, static_cast< Uint16 >(ENF_LOCKED)); + // Let the script callbacks know this entity should no longer be used + try + { + EmitPlayerDestroyed(id, header, payload); + } + catch (...) + { + // The error was probably dealt with already + } + // Is there a manager instance associated with this entity? + if (inst.mInst) + { + // Prevent further use of this entity + inst.mInst->m_ID = -1; + // Release user data to avoid dangling or circular references + inst.mInst->m_Data.Release(); + // Release the used memory buffer + inst.mInst->m_Buffer.ResetAll(); + } + // Reset the entity instance + ResetInst(inst); + // Release associated script callbacks + ResetFunc(inst); + // Prevent further use of the manager instance + inst.mInst = nullptr; + // Release the script object, if any + inst.mObj.Release(); +} + +} // Namespace:: SqMod diff --git a/source/CoreEvents.cpp b/source/CoreEvents.cpp new file mode 100644 index 00000000..a82596f3 --- /dev/null +++ b/source/CoreEvents.cpp @@ -0,0 +1,1055 @@ +// ------------------------------------------------------------------------------------------------ +#include "Core.hpp" +#include "Base/Shared.hpp" +#include "Base/Stack.hpp" +#include "Base/Buffer.hpp" +#include "Library/Utils/BufferWrapper.hpp" + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +// ------------------------------------------------------------------------------------------------ +extern void ProcessRoutines(); + +// ------------------------------------------------------------------------------------------------ +void Core::EmitBlipCreated(Int32 blip, Int32 header, Object & payload) +{ + Emit(mOnBlipCreated, m_Blips.at(blip).mObj, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitCheckpointCreated(Int32 checkpoint, Int32 header, Object & payload) +{ + Emit(mOnCheckpointCreated, m_Checkpoints.at(checkpoint).mObj, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitKeybindCreated(Int32 keybind, Int32 header, Object & payload) +{ + Emit(mOnKeybindCreated, m_Keybinds.at(keybind).mObj, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitObjectCreated(Int32 object, Int32 header, Object & payload) +{ + Emit(mOnObjectCreated, m_Objects.at(object).mObj, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPickupCreated(Int32 pickup, Int32 header, Object & payload) +{ + Emit(mOnPickupCreated, m_Pickups.at(pickup).mObj, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerCreated(Int32 player, Int32 header, Object & payload) +{ + Emit(mOnPlayerCreated, m_Players.at(player).mObj, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitVehicleCreated(Int32 vehicle, Int32 header, Object & payload) +{ + Emit(mOnVehicleCreated, m_Vehicles.at(vehicle).mObj, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitBlipDestroyed(Int32 blip, Int32 header, Object & payload) +{ + BlipInst & _blip = m_Blips.at(blip); + Emit(_blip.mOnDestroyed, header, payload); + Emit(mOnBlipDestroyed, _blip.mObj, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitCheckpointDestroyed(Int32 checkpoint, Int32 header, Object & payload) +{ + CheckpointInst & _checkpoint = m_Checkpoints.at(checkpoint); + Emit(_checkpoint.mOnDestroyed, header, payload); + Emit(mOnCheckpointDestroyed, _checkpoint.mObj, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitKeybindDestroyed(Int32 keybind, Int32 header, Object & payload) +{ + KeybindInst & _keybind = m_Keybinds.at(keybind); + Emit(_keybind.mOnDestroyed, header, payload); + Emit(mOnKeybindDestroyed, _keybind.mObj, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitObjectDestroyed(Int32 object, Int32 header, Object & payload) +{ + ObjectInst & _object = m_Objects.at(object); + Emit(_object.mOnDestroyed, header, payload); + Emit(mOnObjectDestroyed, _object.mObj, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPickupDestroyed(Int32 pickup, Int32 header, Object & payload) +{ + PickupInst & _pickup = m_Pickups.at(pickup); + Emit(_pickup.mOnDestroyed, header, payload); + Emit(mOnPickupDestroyed, _pickup.mObj, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerDestroyed(Int32 player, Int32 header, Object & payload) +{ + PlayerInst & _player = m_Players.at(player); + Emit(_player.mOnDestroyed, header, payload); + Emit(mOnPlayerDestroyed, _player.mObj, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitVehicleDestroyed(Int32 vehicle, Int32 header, Object & payload) +{ + VehicleInst & _vehicle = m_Vehicles.at(vehicle); + Emit(_vehicle.mOnDestroyed, header, payload); + Emit(mOnVehicleDestroyed, _vehicle.mObj, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitBlipCustom(Int32 blip, Int32 header, Object & payload) +{ + BlipInst & _blip = m_Blips.at(blip); + Emit(_blip.mOnCustom, header, payload); + Emit(mOnBlipCustom, _blip.mObj, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitCheckpointCustom(Int32 checkpoint, Int32 header, Object & payload) +{ + CheckpointInst & _checkpoint = m_Checkpoints.at(checkpoint); + Emit(_checkpoint.mOnCustom, header, payload); + Emit(mOnCheckpointCustom, _checkpoint.mObj, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitKeybindCustom(Int32 keybind, Int32 header, Object & payload) +{ + KeybindInst & _keybind = m_Keybinds.at(keybind); + Emit(_keybind.mOnCustom, header, payload); + Emit(mOnKeybindCustom, _keybind.mObj, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitObjectCustom(Int32 object, Int32 header, Object & payload) +{ + ObjectInst & _object = m_Objects.at(object); + Emit(_object.mOnCustom, header, payload); + Emit(mOnObjectCustom, _object.mObj, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPickupCustom(Int32 pickup, Int32 header, Object & payload) +{ + PickupInst & _pickup = m_Pickups.at(pickup); + Emit(_pickup.mOnCustom, header, payload); + Emit(mOnPickupCustom, _pickup.mObj, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerCustom(Int32 player, Int32 header, Object & payload) +{ + PlayerInst & _player = m_Players.at(player); + Emit(_player.mOnCustom, header, payload); + Emit(mOnPlayerCustom, _player.mObj, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitVehicleCustom(Int32 vehicle, Int32 header, Object & payload) +{ + VehicleInst & _vehicle = m_Vehicles.at(vehicle); + Emit(_vehicle.mOnCustom, header, payload); + Emit(mOnVehicleCustom, _vehicle.mObj, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitServerStartup() +{ + Emit(mOnServerStartup); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitServerShutdown() +{ + Emit(mOnServerShutdown); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitServerFrame(Float32 elapsed_time) +{ + // Update routines + ProcessRoutines(); + // Now forward the event + Emit(mOnServerFrame, elapsed_time); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPluginCommand(Uint32 /*command_identifier*/, CCStr /*message*/) +{ + // Ignored for now... +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitIncomingConnection(CStr player_name, size_t name_buffer_size, CCStr user_password, CCStr ip_address) +{ + // Save the buffer information so that we can write to it from the string + m_IncomingNameBuffer = player_name; + m_IncomingNameCapacity = name_buffer_size; + // Attempt to forward the event to the script callback + try + { + Emit(mOnIncomingConnection, player_name, name_buffer_size, user_password, ip_address); + } + catch (...) + { + // We catch the exception so we can release the assigned buffer + } + // Release any stored buffer information + m_IncomingNameBuffer = nullptr; + m_IncomingNameCapacity = 0; +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerRequestClass(Int32 player_id, Int32 offset) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnRequestClass, offset); + Emit(mOnPlayerRequestClass, _player.mObj, offset); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerRequestSpawn(Int32 player_id) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnRequestSpawn); + Emit(mOnPlayerRequestSpawn, _player.mObj); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerSpawn(Int32 player_id) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnSpawn); + Emit(mOnPlayerSpawn, _player.mObj); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerWasted(Int32 player_id, Int32 reason) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnWasted, reason); + Emit(mOnPlayerWasted, _player.mObj, reason); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerKilled(Int32 player_id, Int32 killer_id, Int32 reason, vcmpBodyPart body_part, bool team_kill) +{ + PlayerInst & _player = m_Players.at(player_id); + PlayerInst & _killer = m_Players.at(killer_id); + Emit(_player.mOnKilled, _killer.mObj, reason, static_cast< Int32 >(body_part), team_kill); + Emit(mOnPlayerKilled, _player.mObj, _killer.mObj, reason, static_cast< Int32 >(body_part), team_kill); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerEmbarking(Int32 player_id, Int32 vehicle_id, Int32 slot_index) +{ + PlayerInst & _player = m_Players.at(player_id); + VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); + Emit(_player.mOnEmbarking, _vehicle.mObj, slot_index); + Emit(_vehicle.mOnEmbarking, _player.mObj, slot_index); + Emit(mOnPlayerEmbarking, _player.mObj, _vehicle.mObj, slot_index); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerEmbarked(Int32 player_id, Int32 vehicle_id, Int32 slot_index) +{ + PlayerInst & _player = m_Players.at(player_id); + VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); + Emit(_player.mOnEmbarked, _vehicle.mObj, slot_index); + Emit(_vehicle.mOnEmbarked, _player.mObj, slot_index); + Emit(mOnPlayerEmbarked, _player.mObj, _vehicle.mObj, slot_index); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerDisembark(Int32 player_id, Int32 vehicle_id) +{ + PlayerInst & _player = m_Players.at(player_id); + VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); + Emit(_player.mOnDisembark, _vehicle.mObj); + Emit(_vehicle.mOnDisembark, _player.mObj); + Emit(mOnPlayerDisembark, _player.mObj, _vehicle.mObj); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerRename(Int32 player_id, CCStr old_name, CCStr new_name) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnRename, old_name, new_name); + Emit(mOnPlayerRename, _player.mObj, old_name, new_name); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerState(Int32 player_id, Int32 old_state, Int32 new_state) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnState, old_state, new_state); + Emit(mOnPlayerState, _player.mObj, old_state, new_state); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitStateNone(Int32 player_id, Int32 old_state) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnStateNone, old_state); + Emit(mOnStateNone, _player.mObj, old_state); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitStateNormal(Int32 player_id, Int32 old_state) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnStateNormal, old_state); + Emit(mOnStateNormal, _player.mObj, old_state); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitStateAim(Int32 player_id, Int32 old_state) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnStateAim, old_state); + Emit(mOnStateAim, _player.mObj, old_state); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitStateDriver(Int32 player_id, Int32 old_state) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnStateDriver, old_state); + Emit(mOnStateDriver, _player.mObj, old_state); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitStatePassenger(Int32 player_id, Int32 old_state) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnStatePassenger, old_state); + Emit(mOnStatePassenger, _player.mObj, old_state); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitStateEnterDriver(Int32 player_id, Int32 old_state) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnStateEnterDriver, old_state); + Emit(mOnStateEnterDriver, _player.mObj, old_state); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitStateEnterPassenger(Int32 player_id, Int32 old_state) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnStateEnterPassenger, old_state); + Emit(mOnStateEnterPassenger, _player.mObj, old_state); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitStateExit(Int32 player_id, Int32 old_state) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnStateExit, old_state); + Emit(mOnStateExit, _player.mObj, old_state); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitStateUnspawned(Int32 player_id, Int32 old_state) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnStateUnspawned, old_state); + Emit(mOnStateUnspawned, _player.mObj, old_state); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerAction(Int32 player_id, Int32 old_action, Int32 new_action) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnAction, old_action, new_action); + Emit(mOnPlayerAction, _player.mObj, old_action, new_action); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitActionNone(Int32 player_id, Int32 old_action) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnActionNone, old_action); + Emit(mOnActionNone, _player.mObj, old_action); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitActionNormal(Int32 player_id, Int32 old_action) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnActionNormal, old_action); + Emit(mOnActionNormal, _player.mObj, old_action); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitActionAiming(Int32 player_id, Int32 old_action) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnActionAiming, old_action); + Emit(mOnActionAiming, _player.mObj, old_action); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitActionShooting(Int32 player_id, Int32 old_action) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnActionShooting, old_action); + Emit(mOnActionShooting, _player.mObj, old_action); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitActionJumping(Int32 player_id, Int32 old_action) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnActionJumping, old_action); + Emit(mOnActionJumping, _player.mObj, old_action); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitActionLieDown(Int32 player_id, Int32 old_action) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnActionLieDown, old_action); + Emit(mOnActionLieDown, _player.mObj, old_action); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitActionGettingUp(Int32 player_id, Int32 old_action) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnActionGettingUp, old_action); + Emit(mOnActionGettingUp, _player.mObj, old_action); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitActionJumpVehicle(Int32 player_id, Int32 old_action) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnActionJumpVehicle, old_action); + Emit(mOnActionJumpVehicle, _player.mObj, old_action); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitActionDriving(Int32 player_id, Int32 old_action) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnActionDriving, old_action); + Emit(mOnActionDriving, _player.mObj, old_action); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitActionDying(Int32 player_id, Int32 old_action) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnActionDying, old_action); + Emit(mOnActionDying, _player.mObj, old_action); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitActionWasted(Int32 player_id, Int32 old_action) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnActionWasted, old_action); + Emit(mOnActionWasted, _player.mObj, old_action); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitActionEmbarking(Int32 player_id, Int32 old_action) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnActionEmbarking, old_action); + Emit(mOnActionEmbarking, _player.mObj, old_action); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitActionDisembarking(Int32 player_id, Int32 old_action) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnActionDisembarking, old_action); + Emit(mOnActionDisembarking, _player.mObj, old_action); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerBurning(Int32 player_id, bool is_on_fire) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnBurning, is_on_fire); + Emit(mOnPlayerBurning, _player.mObj, is_on_fire); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerCrouching(Int32 player_id, bool is_crouching) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnCrouching, is_crouching); + Emit(mOnPlayerCrouching, _player.mObj, is_crouching); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerGameKeys(Int32 player_id, Uint32 old_keys, Uint32 new_keys) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnGameKeys, old_keys, new_keys); + Emit(mOnPlayerGameKeys, _player.mObj, old_keys, new_keys); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerStartTyping(Int32 player_id) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnStartTyping); + Emit(mOnPlayerStartTyping, _player.mObj); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerStopTyping(Int32 player_id) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnStopTyping); + Emit(mOnPlayerStopTyping, _player.mObj); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerAway(Int32 player_id, bool is_away) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnAway, is_away); + Emit(mOnPlayerAway, _player.mObj, is_away); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerMessage(Int32 player_id, CCStr message) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnMessage, message); + Emit(mOnPlayerMessage, _player.mObj, message); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerCommand(Int32 player_id, CCStr message) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnCommand, message); + Emit(mOnPlayerCommand, _player.mObj, message); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerPrivateMessage(Int32 player_id, Int32 target_player_id, CCStr message) +{ + PlayerInst & _player = m_Players.at(player_id); + PlayerInst & _receiver = m_Players.at(target_player_id); + Emit(_player.mOnMessage,_receiver.mObj, message); + Emit(mOnPlayerMessage, _player.mObj, _receiver.mObj, message); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerKeyPress(Int32 player_id, Int32 bind_id) +{ + PlayerInst & _player = m_Players.at(player_id); + KeybindInst & _keybind = m_Keybinds.at(bind_id); + Emit(_player.mOnKeyPress, _keybind.mObj); + Emit(_keybind.mOnKeyPress, _player.mObj); + Emit(mOnPlayerKeyPress, _player.mObj, _keybind.mObj); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerKeyRelease(Int32 player_id, Int32 bind_id) +{ + PlayerInst & _player = m_Players.at(player_id); + KeybindInst & _keybind = m_Keybinds.at(bind_id); + Emit(_keybind.mOnKeyRelease, _player.mObj); + Emit(_player.mOnKeyRelease, _keybind.mObj); + Emit(mOnPlayerKeyRelease, _player.mObj, _keybind.mObj); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerSpectate(Int32 player_id, Int32 target_player_id) +{ + PlayerInst & _player = m_Players.at(player_id); + PlayerInst & _target = m_Players.at(target_player_id); + Emit(_player.mOnSpectate, _target.mObj); + Emit(mOnPlayerSpectate, _player.mObj, _target.mObj); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerCrashreport(Int32 player_id, CCStr report) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnCrashreport, report); + Emit(mOnPlayerCrashreport, _player.mObj, report); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitVehicleExplode(Int32 vehicle_id) +{ + VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); + Emit(_vehicle.mOnExplode); + Emit(mOnVehicleExplode, _vehicle.mObj); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitVehicleRespawn(Int32 vehicle_id) +{ + VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); + Emit(_vehicle.mOnRespawn); + Emit(mOnVehicleRespawn, _vehicle.mObj); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitObjectShot(Int32 object_id, Int32 player_id, Int32 weapon_id) +{ + ObjectInst & _object = m_Objects.at(object_id); + PlayerInst & _player = m_Players.at(player_id); + Emit(_object.mOnShot, _player.mObj, weapon_id); + Emit(_player.mOnObjectShot, _object.mObj, weapon_id); + Emit(mOnObjectShot, _player.mObj, _object.mObj, weapon_id); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitObjectTouched(Int32 object_id, Int32 player_id) +{ + ObjectInst & _object = m_Objects.at(object_id); + PlayerInst & _player = m_Players.at(player_id); + Emit(_object.mOnTouched, _player.mObj); + Emit(_player.mOnObjectTouched, _object.mObj); + Emit(mOnObjectTouched, _player.mObj, _object.mObj); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPickupClaimed(Int32 pickup_id, Int32 player_id) +{ + PickupInst & _pickup = m_Pickups.at(pickup_id); + PlayerInst & _player = m_Players.at(player_id); + Emit(_pickup.mOnClaimed, _player.mObj); + Emit(_player.mOnPickupClaimed, _pickup.mObj); + Emit(mOnPickupClaimed, _player.mObj, _pickup.mObj); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPickupCollected(Int32 pickup_id, Int32 player_id) +{ + PickupInst & _pickup = m_Pickups.at(pickup_id); + PlayerInst & _player = m_Players.at(player_id); + Emit(_pickup.mOnCollected, _player.mObj); + Emit(_player.mOnPickupCollected, _pickup.mObj); + Emit(mOnPickupCollected, _player.mObj, _pickup.mObj); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPickupRespawn(Int32 pickup_id) +{ + PickupInst & _pickup = m_Pickups.at(pickup_id); + Emit(_pickup.mOnRespawn); + Emit(mOnPickupRespawn, _pickup.mObj); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitCheckpointEntered(Int32 checkpoint_id, Int32 player_id) +{ + CheckpointInst & _checkpoint = m_Checkpoints.at(checkpoint_id); + PlayerInst & _player = m_Players.at(player_id); + Emit(_checkpoint.mOnEntered, _player.mObj); + Emit(_player.mOnCheckpointEntered, _checkpoint.mObj); + Emit(mOnCheckpointEntered, _player.mObj, _checkpoint.mObj); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitCheckpointExited(Int32 checkpoint_id, Int32 player_id) +{ + CheckpointInst & _checkpoint = m_Checkpoints.at(checkpoint_id); + PlayerInst & _player = m_Players.at(player_id); + Emit(_checkpoint.mOnExited, _player.mObj); + Emit(_player.mOnCheckpointExited, _checkpoint.mObj); + Emit(mOnCheckpointExited, _player.mObj, _checkpoint.mObj); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerHealth(Int32 player_id, Float32 old_health, Float32 new_health) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnHealth, old_health, new_health); + Emit(mOnPlayerHealth, _player.mObj, old_health, new_health); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerArmour(Int32 player_id, Float32 old_armour, Float32 new_armour) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnArmour, old_armour, new_armour); + Emit(mOnPlayerArmour, _player.mObj, old_armour, new_armour); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerWeapon(Int32 player_id, Int32 old_weapon, Int32 new_weapon) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnWeapon, old_weapon, new_weapon); + Emit(mOnPlayerWeapon, _player.mObj, old_weapon, new_weapon); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerHeading(Int32 player_id, Float32 old_heading, Float32 new_heading) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnHeading, old_heading, new_heading); + Emit(mOnPlayerHeading, _player.mObj, old_heading, new_heading); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerPosition(Int32 player_id) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnPosition); + Emit(mOnPlayerPosition, _player.mObj); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerOption(Int32 player_id, Int32 option_id, bool value, + Int32 header, Object & payload) +{ + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnOption, option_id, value, header, payload); + Emit(mOnPlayerOption, _player.mObj, option_id, value, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitVehicleColour(Int32 vehicle_id, Int32 changed) +{ + VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); + Emit(_vehicle.mOnColour, changed); + Emit(mOnVehicleColour, _vehicle.mObj, changed); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitVehicleHealth(Int32 vehicle_id, Float32 old_health, Float32 new_health) +{ + VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); + Emit(_vehicle.mOnHealth, old_health, new_health); + Emit(mOnVehicleHealth, _vehicle.mObj, old_health, new_health); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitVehiclePosition(Int32 vehicle_id) +{ + VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); + Emit(_vehicle.mOnPosition); + Emit(mOnVehiclePosition, _vehicle.mObj); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitVehicleRotation(Int32 vehicle_id) +{ + VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); + Emit(_vehicle.mOnRotation); + Emit(mOnVehicleRotation, _vehicle.mObj); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitVehicleOption(Int32 vehicle_id, Int32 option_id, bool value, + Int32 header, Object & payload) +{ + VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); + Emit(_vehicle.mOnOption, option_id, value, header, payload); + Emit(mOnVehicleOption, _vehicle.mObj, option_id, value, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitServerOption(Int32 option, bool value, Int32 header, Object & payload) +{ + if (m_CircularLocks & CCL_EMIT_SERVER_OPTION) + { + return; // Already inside this event! + } + // Prevent further calls to this event + BitGuardU32 bg(m_CircularLocks, CCL_EMIT_SERVER_OPTION); + // Now forward the event call + Emit(mOnServerOption, option, value, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitScriptReload(Int32 header, Object & payload) +{ + Emit(mOnScriptReload, header, payload); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitScriptLoaded() +{ + Emit(mOnScriptLoaded); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitEntityPool(vcmpEntityPool entity_type, Int32 entity_id, bool is_deleted) +{ + // See what type of change happened in the entity pool + switch (entity_type) + { + case vcmpEntityPoolVehicle: + // Do we even have this vehicle that we're trying to delete? + if (is_deleted && VALID_ENTITY(m_Vehicles[entity_id].mID)) + { + DeallocVehicle(entity_id, false, SQMOD_DESTROY_POOL, NullObject()); + } + // Do we already have this vehicle that we're trying to create? + else if (INVALID_ENTITY(m_Vehicles[entity_id].mID)) + { + AllocVehicle(entity_id, false, SQMOD_CREATE_POOL, NullObject()); + } + break; + case vcmpEntityPoolObject: + // Do we even have this object that we're trying to delete? + if (is_deleted && VALID_ENTITY(m_Objects[entity_id].mID)) + { + DeallocObject(entity_id, false, SQMOD_DESTROY_POOL, NullObject()); + } + // Do we already have this object that we're trying to create? + else if (INVALID_ENTITY(m_Objects[entity_id].mID)) + { + AllocObject(entity_id, false, SQMOD_CREATE_POOL, NullObject()); + } + break; + case vcmpEntityPoolPickup: + // Do we even have this pickup that we're trying to delete? + if (is_deleted && VALID_ENTITY(m_Pickups[entity_id].mID)) + { + DeallocPickup(entity_id, false, SQMOD_DESTROY_POOL, NullObject()); + } + // Do we already have this pickup that we're trying to create? + else if (INVALID_ENTITY(m_Pickups[entity_id].mID)) + { + AllocPickup(entity_id, false, SQMOD_CREATE_POOL, NullObject()); + } + break; + case vcmpEntityPoolRadio: + // @TODO Implement... + break; + case vcmpEntityPoolCheckPoint: + // Do we even have this checkpoint that we're trying to delete? + if (is_deleted && VALID_ENTITY(m_Checkpoints[entity_id].mID)) + { + DeallocCheckpoint(entity_id, false, SQMOD_DESTROY_POOL, NullObject()); + } + // Do we already have this checkpoint that we're trying to create? + else if (INVALID_ENTITY(m_Checkpoints[entity_id].mID)) + { + AllocCheckpoint(entity_id, false, SQMOD_CREATE_POOL, NullObject()); + } + break; + case vcmpEntityPoolBlip: + // Do we even have this blip that we're trying to delete? + if (is_deleted && VALID_ENTITY(m_Blips[entity_id].mID)) + { + DeallocBlip(entity_id, false, SQMOD_DESTROY_POOL, NullObject()); + } + // Do we already have this blip that we're trying to create? + else if (INVALID_ENTITY(m_Blips[entity_id].mID)) + { + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(entity_id, SQMOD_BLIP_POOL)) + { + STHROWF("Cannot allocate blip with invalid identifier: %d", entity_id); + } + // Retrieve the specified entity instance + BlipInst & inst = m_Blips[entity_id]; + // Make sure that the instance isn't already allocated + if (VALID_ENTITY(inst.mID)) + { + STHROWF("Cannot allocate blip that already exists: %d", entity_id); + } + // Information about the blip entity + Int32 world, scale, sprid; + Uint32 color; + Float32 x, y, z; + // Get the blip information from the server + _Func->GetCoordBlipInfo(entity_id, &world, &x, &y, &z, &scale, &color, &sprid); + // Assign the obtain information + inst.mWorld = world; + inst.mScale = scale; + inst.mSprID = sprid; + inst.mColor.SetRGBA(color); + inst.mPosition.Set(x, y, z); + // Now we can try to allocate the instance after we have all the information + AllocBlip(entity_id, false, SQMOD_CREATE_POOL, NullObject()); + } + break; + default: + LogErr("Unknown change in the entity pool of type: %d", entity_type); + } + // Finally, forward the event to the script + Emit(mOnEntityPool, static_cast< Int32 >(entity_type), entity_id, is_deleted); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerUpdate(Int32 player_id, vcmpPlayerUpdate update_type) +{ + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(player_id, SQMOD_PLAYER_POOL)) + { + STHROWF("Cannot update player with invalid identifier: %d", player_id); + } + // Retrieve the associated tracking instance + PlayerInst & inst = m_Players[player_id]; + + // Obtain the current heading of this instance + Float32 heading = _Func->GetPlayerHeading(player_id); + // Did the heading change since the last tracked value? + if (!EpsEq(heading, inst.mLastHeading)) + { + // Trigger the event specific to this change + EmitPlayerHeading(player_id, inst.mLastHeading, heading); + // Update the tracked value + inst.mLastHeading = heading; + } + + Vector3 pos; + // Obtain the current position of this instance + _Func->GetPlayerPosition(player_id, &pos.x, &pos.y, &pos.z); + // Did the position change since the last tracked value? + if (pos != inst.mLastPosition) + { + // Trigger the event specific to this change + EmitPlayerPosition(player_id); + // Update the tracked value + inst.mLastPosition = pos; + } + + // Obtain the current health of this instance + Float32 health = _Func->GetPlayerHealth(player_id); + // Did the health change since the last tracked value? + if (!EpsEq(health, inst.mLastHealth)) + { + // Trigger the event specific to this change + EmitPlayerHealth(player_id, inst.mLastHealth, health); + // Update the tracked value + inst.mLastHealth = health; + } + + // Obtain the current armor of this instance + Float32 armour = _Func->GetPlayerArmour(player_id); + // Did the armor change since the last tracked value? + if (!EpsEq(armour, inst.mLastArmour)) + { + // Trigger the event specific to this change + EmitPlayerArmour(player_id, inst.mLastArmour, armour); + // Update the tracked value + inst.mLastArmour = armour; + } + + // Obtain the current weapon of this instance + Int32 wep = _Func->GetPlayerWeapon(player_id); + // Did the weapon change since the last tracked value? + if (wep != inst.mLastWeapon) + { + // Trigger the event specific to this change + EmitPlayerWeapon(player_id, inst.mLastWeapon, wep); + // Update the tracked value + inst.mLastWeapon = wep; + } + + // Finally, forward the call to the update callback + Emit(inst.mOnUpdate, static_cast< Int32 >(update_type)); + Emit(mOnPlayerUpdate, inst.mObj, static_cast< Int32 >(update_type)); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitVehicleUpdate(Int32 vehicle_id, vcmpVehicleUpdate update_type) +{ + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(vehicle_id, SQMOD_VEHICLE_POOL)) + { + STHROWF("Cannot update vehicle with invalid identifier: %d", vehicle_id); + } + // Retrieve the associated instance + VehicleInst & inst = m_Vehicles[vehicle_id]; + // Identify the update type + switch (update_type) + { + case vcmpVehicleUpdatePosition: + { + // Trigger the event specific to this change + EmitVehiclePosition(vehicle_id); + // Update the tracked value + _Func->GetVehiclePosition(vehicle_id, &inst.mLastPosition.x, + &inst.mLastPosition.y, &inst.mLastPosition.z); + } break; + case vcmpVehicleUpdateHealth: + { + // Obtain the current health of this instance + Float32 health = _Func->GetVehicleHealth(vehicle_id); + // Trigger the event specific to this change + EmitVehicleHealth(vehicle_id, inst.mLastHealth, health); + // Update the tracked value + inst.mLastHealth = health; + } break; + case vcmpVehicleUpdateColour: + { + Int32 primary, secondary; + // Obtain the current colours of this instance + _Func->GetVehicleColour(vehicle_id, &primary, &secondary); + // Which colours changed + Int32 changed = 0; + // Did the primary colour changed? + if (primary != inst.mLastPrimaryColour) + { + changed |= (1<<0); + } + // Did the secondary colour changed? + if (primary != inst.mLastSecondaryColour) + { + changed |= (1<<1); + } + // Trigger the event specific to this change + EmitVehicleColour(vehicle_id, changed); + // Update the tracked value + inst.mLastPrimaryColour = primary; + inst.mLastSecondaryColour = secondary; + } break; + case vcmpVehicleUpdateRotation: + { + Quaternion rot; + // Obtain the current position of this instance + _Func->GetVehicleRotation(vehicle_id, &rot.x, &rot.y, &rot.z, &rot.w); + // Trigger the event specific to this change + EmitVehicleRotation(vehicle_id); + // Update the tracked value + inst.mLastRotation = rot; + } break; + default: + { + // Finally, forward the call to the update callback + Emit(inst.mOnUpdate, static_cast< Int32 >(update_type)); + Emit(mOnVehicleUpdate, inst.mObj, static_cast< Int32 >(update_type)); + } + } +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitClientScriptData(Int32 player_id, const uint8_t * data, size_t size) +{ + // Allocate a buffer with the received size + Buffer b(size); + // Replicate the data to the allocated buffer + b.Write(0, reinterpret_cast< Buffer::ConstPtr >(data), size); + // Wrap the buffer into a script object + Object o = MakeObject(m_VM, BufferWrapper(std::move(b))); + // Forward the event call + PlayerInst & _player = m_Players.at(player_id); + Emit(_player.mOnClientScriptData, o, size); + Emit(mOnClientScriptData, _player.mObj, o, size); +} + +} // Namespace:: SqMod diff --git a/source/CoreUtils.cpp b/source/CoreUtils.cpp new file mode 100644 index 00000000..b443e482 --- /dev/null +++ b/source/CoreUtils.cpp @@ -0,0 +1,587 @@ +// ------------------------------------------------------------------------------------------------ +#include "Core.hpp" + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +// ------------------------------------------------------------------------------------------------ +void Core::ResetInst(BlipInst & inst) +{ + inst.mID = -1; + inst.mFlags = ENF_DEFAULT; + inst.mWorld = -1; + inst.mScale = -1; + inst.mSprID = -1; + inst.mPosition.Clear(); + inst.mColor.Clear(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::ResetInst(CheckpointInst & inst) +{ + inst.mID = -1; + inst.mFlags = ENF_DEFAULT; +} + +// ------------------------------------------------------------------------------------------------ +void Core::ResetInst(KeybindInst & inst) +{ + inst.mID = -1; + inst.mFlags = ENF_DEFAULT; + inst.mFirst = -1; + inst.mSecond = -1; + inst.mThird = -1; + inst.mRelease = -1; +} + +// ------------------------------------------------------------------------------------------------ +void Core::ResetInst(ObjectInst & inst) +{ + inst.mID = -1; + inst.mFlags = ENF_DEFAULT; +} + +// ------------------------------------------------------------------------------------------------ +void Core::ResetInst(PickupInst & inst) +{ + inst.mID = -1; + inst.mFlags = ENF_DEFAULT; +} + +// ------------------------------------------------------------------------------------------------ +void Core::ResetInst(PlayerInst & inst) +{ + inst.mID = -1; + inst.mFlags = ENF_DEFAULT; + inst.mLastWeapon = -1; + inst.mLastHealth = 0.0; + inst.mLastArmour = 0.0; + inst.mLastHeading = 0.0; + inst.mLastPosition.Clear(); + inst.mAuthority = 0; +} + +// ------------------------------------------------------------------------------------------------ +void Core::ResetInst(VehicleInst & inst) +{ + inst.mID = -1; + inst.mFlags = ENF_DEFAULT; + inst.mLastPrimaryColour = -1; + inst.mLastSecondaryColour = -1; + inst.mLastHealth = 0.0; + inst.mLastPosition.Clear(); + inst.mLastRotation.Clear(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::ResetFunc(BlipInst & inst) +{ + inst.mOnDestroyed.ReleaseGently(); + inst.mOnCustom.ReleaseGently(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::ResetFunc(CheckpointInst & inst) +{ + inst.mOnDestroyed.ReleaseGently(); + inst.mOnCustom.ReleaseGently(); + inst.mOnEntered.ReleaseGently(); + inst.mOnExited.ReleaseGently(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::ResetFunc(KeybindInst & inst) +{ + inst.mOnDestroyed.ReleaseGently(); + inst.mOnCustom.ReleaseGently(); + inst.mOnKeyPress.ReleaseGently(); + inst.mOnKeyRelease.ReleaseGently(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::ResetFunc(ObjectInst & inst) +{ + inst.mOnDestroyed.ReleaseGently(); + inst.mOnCustom.ReleaseGently(); + inst.mOnShot.ReleaseGently(); + inst.mOnTouched.ReleaseGently(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::ResetFunc(PickupInst & inst) +{ + inst.mOnDestroyed.ReleaseGently(); + inst.mOnCustom.ReleaseGently(); + inst.mOnRespawn.ReleaseGently(); + inst.mOnClaimed.ReleaseGently(); + inst.mOnCollected.ReleaseGently(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::ResetFunc(PlayerInst & inst) +{ + inst.mOnDestroyed.ReleaseGently(); + inst.mOnCustom.ReleaseGently(); + inst.mOnRequestClass.ReleaseGently(); + inst.mOnRequestSpawn.ReleaseGently(); + inst.mOnSpawn.ReleaseGently(); + inst.mOnWasted.ReleaseGently(); + inst.mOnKilled.ReleaseGently(); + inst.mOnEmbarking.ReleaseGently(); + inst.mOnEmbarked.ReleaseGently(); + inst.mOnDisembark.ReleaseGently(); + inst.mOnRename.ReleaseGently(); + inst.mOnState.ReleaseGently(); + inst.mOnStateNone.ReleaseGently(); + inst.mOnStateNormal.ReleaseGently(); + inst.mOnStateAim.ReleaseGently(); + inst.mOnStateDriver.ReleaseGently(); + inst.mOnStatePassenger.ReleaseGently(); + inst.mOnStateEnterDriver.ReleaseGently(); + inst.mOnStateEnterPassenger.ReleaseGently(); + inst.mOnStateExit.ReleaseGently(); + inst.mOnStateUnspawned.ReleaseGently(); + inst.mOnAction.ReleaseGently(); + inst.mOnActionNone.ReleaseGently(); + inst.mOnActionNormal.ReleaseGently(); + inst.mOnActionAiming.ReleaseGently(); + inst.mOnActionShooting.ReleaseGently(); + inst.mOnActionJumping.ReleaseGently(); + inst.mOnActionLieDown.ReleaseGently(); + inst.mOnActionGettingUp.ReleaseGently(); + inst.mOnActionJumpVehicle.ReleaseGently(); + inst.mOnActionDriving.ReleaseGently(); + inst.mOnActionDying.ReleaseGently(); + inst.mOnActionWasted.ReleaseGently(); + inst.mOnActionEmbarking.ReleaseGently(); + inst.mOnActionDisembarking.ReleaseGently(); + inst.mOnBurning.ReleaseGently(); + inst.mOnCrouching.ReleaseGently(); + inst.mOnGameKeys.ReleaseGently(); + inst.mOnStartTyping.ReleaseGently(); + inst.mOnStopTyping.ReleaseGently(); + inst.mOnAway.ReleaseGently(); + inst.mOnMessage.ReleaseGently(); + inst.mOnCommand.ReleaseGently(); + inst.mOnPrivateMessage.ReleaseGently(); + inst.mOnKeyPress.ReleaseGently(); + inst.mOnKeyRelease.ReleaseGently(); + inst.mOnSpectate.ReleaseGently(); + inst.mOnCrashreport.ReleaseGently(); + inst.mOnObjectShot.ReleaseGently(); + inst.mOnObjectTouched.ReleaseGently(); + inst.mOnPickupClaimed.ReleaseGently(); + inst.mOnPickupCollected.ReleaseGently(); + inst.mOnCheckpointEntered.ReleaseGently(); + inst.mOnCheckpointExited.ReleaseGently(); + inst.mOnClientScriptData.ReleaseGently(); + inst.mOnUpdate.ReleaseGently(); + inst.mOnHealth.ReleaseGently(); + inst.mOnArmour.ReleaseGently(); + inst.mOnWeapon.ReleaseGently(); + inst.mOnHeading.ReleaseGently(); + inst.mOnPosition.ReleaseGently(); + inst.mOnOption.ReleaseGently(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::ResetFunc(VehicleInst & inst) +{ + inst.mOnDestroyed.ReleaseGently(); + inst.mOnCustom.ReleaseGently(); + inst.mOnEmbarking.ReleaseGently(); + inst.mOnEmbarked.ReleaseGently(); + inst.mOnDisembark.ReleaseGently(); + inst.mOnExplode.ReleaseGently(); + inst.mOnRespawn.ReleaseGently(); + inst.mOnUpdate.ReleaseGently(); + inst.mOnColour.ReleaseGently(); + inst.mOnHealth.ReleaseGently(); + inst.mOnPosition.ReleaseGently(); + inst.mOnRotation.ReleaseGently(); + inst.mOnOption.ReleaseGently(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::ResetFunc() +{ + Core::Get().mOnCustomEvent.ReleaseGently(); + Core::Get().mOnBlipCreated.ReleaseGently(); + Core::Get().mOnCheckpointCreated.ReleaseGently(); + Core::Get().mOnKeybindCreated.ReleaseGently(); + Core::Get().mOnObjectCreated.ReleaseGently(); + Core::Get().mOnPickupCreated.ReleaseGently(); + Core::Get().mOnPlayerCreated.ReleaseGently(); + Core::Get().mOnVehicleCreated.ReleaseGently(); + Core::Get().mOnBlipDestroyed.ReleaseGently(); + Core::Get().mOnCheckpointDestroyed.ReleaseGently(); + Core::Get().mOnKeybindDestroyed.ReleaseGently(); + Core::Get().mOnObjectDestroyed.ReleaseGently(); + Core::Get().mOnPickupDestroyed.ReleaseGently(); + Core::Get().mOnPlayerDestroyed.ReleaseGently(); + Core::Get().mOnVehicleDestroyed.ReleaseGently(); + Core::Get().mOnBlipCustom.ReleaseGently(); + Core::Get().mOnCheckpointCustom.ReleaseGently(); + Core::Get().mOnKeybindCustom.ReleaseGently(); + Core::Get().mOnObjectCustom.ReleaseGently(); + Core::Get().mOnPickupCustom.ReleaseGently(); + Core::Get().mOnPlayerCustom.ReleaseGently(); + Core::Get().mOnVehicleCustom.ReleaseGently(); + Core::Get().mOnServerStartup.ReleaseGently(); + Core::Get().mOnServerShutdown.ReleaseGently(); + Core::Get().mOnServerFrame.ReleaseGently(); + Core::Get().mOnIncomingConnection.ReleaseGently(); + Core::Get().mOnPlayerRequestClass.ReleaseGently(); + Core::Get().mOnPlayerRequestSpawn.ReleaseGently(); + Core::Get().mOnPlayerSpawn.ReleaseGently(); + Core::Get().mOnPlayerWasted.ReleaseGently(); + Core::Get().mOnPlayerKilled.ReleaseGently(); + Core::Get().mOnPlayerEmbarking.ReleaseGently(); + Core::Get().mOnPlayerEmbarked.ReleaseGently(); + Core::Get().mOnPlayerDisembark.ReleaseGently(); + Core::Get().mOnPlayerRename.ReleaseGently(); + Core::Get().mOnPlayerState.ReleaseGently(); + Core::Get().mOnStateNone.ReleaseGently(); + Core::Get().mOnStateNormal.ReleaseGently(); + Core::Get().mOnStateAim.ReleaseGently(); + Core::Get().mOnStateDriver.ReleaseGently(); + Core::Get().mOnStatePassenger.ReleaseGently(); + Core::Get().mOnStateEnterDriver.ReleaseGently(); + Core::Get().mOnStateEnterPassenger.ReleaseGently(); + Core::Get().mOnStateExit.ReleaseGently(); + Core::Get().mOnStateUnspawned.ReleaseGently(); + Core::Get().mOnPlayerAction.ReleaseGently(); + Core::Get().mOnActionNone.ReleaseGently(); + Core::Get().mOnActionNormal.ReleaseGently(); + Core::Get().mOnActionAiming.ReleaseGently(); + Core::Get().mOnActionShooting.ReleaseGently(); + Core::Get().mOnActionJumping.ReleaseGently(); + Core::Get().mOnActionLieDown.ReleaseGently(); + Core::Get().mOnActionGettingUp.ReleaseGently(); + Core::Get().mOnActionJumpVehicle.ReleaseGently(); + Core::Get().mOnActionDriving.ReleaseGently(); + Core::Get().mOnActionDying.ReleaseGently(); + Core::Get().mOnActionWasted.ReleaseGently(); + Core::Get().mOnActionEmbarking.ReleaseGently(); + Core::Get().mOnActionDisembarking.ReleaseGently(); + Core::Get().mOnPlayerBurning.ReleaseGently(); + Core::Get().mOnPlayerCrouching.ReleaseGently(); + Core::Get().mOnPlayerGameKeys.ReleaseGently(); + Core::Get().mOnPlayerStartTyping.ReleaseGently(); + Core::Get().mOnPlayerStopTyping.ReleaseGently(); + Core::Get().mOnPlayerAway.ReleaseGently(); + Core::Get().mOnPlayerMessage.ReleaseGently(); + Core::Get().mOnPlayerCommand.ReleaseGently(); + Core::Get().mOnPlayerPrivateMessage.ReleaseGently(); + Core::Get().mOnPlayerKeyPress.ReleaseGently(); + Core::Get().mOnPlayerKeyRelease.ReleaseGently(); + Core::Get().mOnPlayerSpectate.ReleaseGently(); + Core::Get().mOnPlayerCrashreport.ReleaseGently(); + Core::Get().mOnVehicleExplode.ReleaseGently(); + Core::Get().mOnVehicleRespawn.ReleaseGently(); + Core::Get().mOnObjectShot.ReleaseGently(); + Core::Get().mOnObjectTouched.ReleaseGently(); + Core::Get().mOnPickupClaimed.ReleaseGently(); + Core::Get().mOnPickupCollected.ReleaseGently(); + Core::Get().mOnPickupRespawn.ReleaseGently(); + Core::Get().mOnCheckpointEntered.ReleaseGently(); + Core::Get().mOnCheckpointExited.ReleaseGently(); + Core::Get().mOnEntityPool.ReleaseGently(); + Core::Get().mOnClientScriptData.ReleaseGently(); + Core::Get().mOnPlayerUpdate.ReleaseGently(); + Core::Get().mOnVehicleUpdate.ReleaseGently(); + Core::Get().mOnPlayerHealth.ReleaseGently(); + Core::Get().mOnPlayerArmour.ReleaseGently(); + Core::Get().mOnPlayerWeapon.ReleaseGently(); + Core::Get().mOnPlayerHeading.ReleaseGently(); + Core::Get().mOnPlayerPosition.ReleaseGently(); + Core::Get().mOnPlayerOption.ReleaseGently(); + Core::Get().mOnVehicleColour.ReleaseGently(); + Core::Get().mOnVehicleHealth.ReleaseGently(); + Core::Get().mOnVehiclePosition.ReleaseGently(); + Core::Get().mOnVehicleRotation.ReleaseGently(); + Core::Get().mOnVehicleOption.ReleaseGently(); + Core::Get().mOnServerOption.ReleaseGently(); + Core::Get().mOnScriptReload.ReleaseGently(); + Core::Get().mOnScriptLoaded.ReleaseGently(); +} + +// ------------------------------------------------------------------------------------------------ +Function & Core::GetEvent(Int32 evid) +{ + switch (evid) + { + case EVT_CUSTOMEVENT: return mOnCustomEvent; + case EVT_BLIPCREATED: return mOnBlipCreated; + case EVT_CHECKPOINTCREATED: return mOnCheckpointCreated; + case EVT_KEYBINDCREATED: return mOnKeybindCreated; + case EVT_OBJECTCREATED: return mOnObjectCreated; + case EVT_PICKUPCREATED: return mOnPickupCreated; + case EVT_PLAYERCREATED: return mOnPlayerCreated; + case EVT_VEHICLECREATED: return mOnVehicleCreated; + case EVT_BLIPDESTROYED: return mOnBlipDestroyed; + case EVT_CHECKPOINTDESTROYED: return mOnCheckpointDestroyed; + case EVT_KEYBINDDESTROYED: return mOnKeybindDestroyed; + case EVT_OBJECTDESTROYED: return mOnObjectDestroyed; + case EVT_PICKUPDESTROYED: return mOnPickupDestroyed; + case EVT_PLAYERDESTROYED: return mOnPlayerDestroyed; + case EVT_VEHICLEDESTROYED: return mOnVehicleDestroyed; + case EVT_BLIPCUSTOM: return mOnBlipCustom; + case EVT_CHECKPOINTCUSTOM: return mOnCheckpointCustom; + case EVT_KEYBINDCUSTOM: return mOnKeybindCustom; + case EVT_OBJECTCUSTOM: return mOnObjectCustom; + case EVT_PICKUPCUSTOM: return mOnPickupCustom; + case EVT_PLAYERCUSTOM: return mOnPlayerCustom; + case EVT_VEHICLECUSTOM: return mOnVehicleCustom; + case EVT_SERVERSTARTUP: return mOnServerStartup; + case EVT_SERVERSHUTDOWN: return mOnServerShutdown; + case EVT_SERVERFRAME: return mOnServerFrame; + case EVT_INCOMINGCONNECTION: return mOnIncomingConnection; + case EVT_PLAYERREQUESTCLASS: return mOnPlayerRequestClass; + case EVT_PLAYERREQUESTSPAWN: return mOnPlayerRequestSpawn; + case EVT_PLAYERSPAWN: return mOnPlayerSpawn; + case EVT_PLAYERWASTED: return mOnPlayerWasted; + case EVT_PLAYERKILLED: return mOnPlayerKilled; + case EVT_PLAYEREMBARKING: return mOnPlayerEmbarking; + case EVT_PLAYEREMBARKED: return mOnPlayerEmbarked; + case EVT_PLAYERDISEMBARK: return mOnPlayerDisembark; + case EVT_PLAYERRENAME: return mOnPlayerRename; + case EVT_PLAYERSTATE: return mOnPlayerState; + case EVT_STATENONE: return mOnStateNone; + case EVT_STATENORMAL: return mOnStateNormal; + case EVT_STATEAIM: return mOnStateAim; + case EVT_STATEDRIVER: return mOnStateDriver; + case EVT_STATEPASSENGER: return mOnStatePassenger; + case EVT_STATEENTERDRIVER: return mOnStateEnterDriver; + case EVT_STATEENTERPASSENGER: return mOnStateEnterPassenger; + case EVT_STATEEXIT: return mOnStateExit; + case EVT_STATEUNSPAWNED: return mOnStateUnspawned; + case EVT_PLAYERACTION: return mOnPlayerAction; + case EVT_ACTIONNONE: return mOnActionNone; + case EVT_ACTIONNORMAL: return mOnActionNormal; + case EVT_ACTIONAIMING: return mOnActionAiming; + case EVT_ACTIONSHOOTING: return mOnActionShooting; + case EVT_ACTIONJUMPING: return mOnActionJumping; + case EVT_ACTIONLIEDOWN: return mOnActionLieDown; + case EVT_ACTIONGETTINGUP: return mOnActionGettingUp; + case EVT_ACTIONJUMPVEHICLE: return mOnActionJumpVehicle; + case EVT_ACTIONDRIVING: return mOnActionDriving; + case EVT_ACTIONDYING: return mOnActionDying; + case EVT_ACTIONWASTED: return mOnActionWasted; + case EVT_ACTIONEMBARKING: return mOnActionEmbarking; + case EVT_ACTIONDISEMBARKING: return mOnActionDisembarking; + case EVT_PLAYERBURNING: return mOnPlayerBurning; + case EVT_PLAYERCROUCHING: return mOnPlayerCrouching; + case EVT_PLAYERGAMEKEYS: return mOnPlayerGameKeys; + case EVT_PLAYERSTARTTYPING: return mOnPlayerStartTyping; + case EVT_PLAYERSTOPTYPING: return mOnPlayerStopTyping; + case EVT_PLAYERAWAY: return mOnPlayerAway; + case EVT_PLAYERMESSAGE: return mOnPlayerMessage; + case EVT_PLAYERCOMMAND: return mOnPlayerCommand; + case EVT_PLAYERPRIVATEMESSAGE: return mOnPlayerPrivateMessage; + case EVT_PLAYERKEYPRESS: return mOnPlayerKeyPress; + case EVT_PLAYERKEYRELEASE: return mOnPlayerKeyRelease; + case EVT_PLAYERSPECTATE: return mOnPlayerSpectate; + case EVT_PLAYERCRASHREPORT: return mOnPlayerCrashreport; + case EVT_VEHICLEEXPLODE: return mOnVehicleExplode; + case EVT_VEHICLERESPAWN: return mOnVehicleRespawn; + case EVT_OBJECTSHOT: return mOnObjectShot; + case EVT_OBJECTTOUCHED: return mOnObjectTouched; + case EVT_PICKUPCLAIMED: return mOnPickupClaimed; + case EVT_PICKUPCOLLECTED: return mOnPickupCollected; + case EVT_PICKUPRESPAWN: return mOnPickupRespawn; + case EVT_CHECKPOINTENTERED: return mOnCheckpointEntered; + case EVT_CHECKPOINTEXITED: return mOnCheckpointExited; + case EVT_ENTITYPOOL: return mOnEntityPool; + case EVT_CLIENTSCRIPTDATA: return mOnClientScriptData; + case EVT_PLAYERUPDATE: return mOnPlayerUpdate; + case EVT_VEHICLEUPDATE: return mOnVehicleUpdate; + case EVT_PLAYERHEALTH: return mOnPlayerHealth; + case EVT_PLAYERARMOUR: return mOnPlayerArmour; + case EVT_PLAYERWEAPON: return mOnPlayerWeapon; + case EVT_PLAYERHEADING: return mOnPlayerHeading; + case EVT_PLAYERPOSITION: return mOnPlayerPosition; + case EVT_PLAYEROPTION: return mOnPlayerOption; + case EVT_VEHICLECOLOUR: return mOnVehicleColour; + case EVT_VEHICLEHEALTH: return mOnVehicleHealth; + case EVT_VEHICLEPOSITION: return mOnVehiclePosition; + case EVT_VEHICLEROTATION: return mOnVehicleRotation; + case EVT_VEHICLEOPTION: return mOnVehicleOption; + case EVT_SERVEROPTION: return mOnServerOption; + case EVT_SCRIPTRELOAD: return mOnScriptReload; + case EVT_SCRIPTLOADED: return mOnScriptLoaded; + default: return NullFunction(); + } +} + +// ------------------------------------------------------------------------------------------------ +Function & Core::GetBlipEvent(Int32 id, Int32 evid) +{ + BlipInst & inst = m_Blips.at(id); + + switch (evid) + { + case EVT_BLIPDESTROYED: return inst.mOnDestroyed; + case EVT_BLIPCUSTOM: return inst.mOnCustom; + default: return NullFunction(); + } +} + +// ------------------------------------------------------------------------------------------------ +Function & Core::GetCheckpointEvent(Int32 id, Int32 evid) +{ + CheckpointInst & inst = m_Checkpoints.at(id); + + switch (evid) + { + case EVT_CHECKPOINTDESTROYED: return inst.mOnDestroyed; + case EVT_CHECKPOINTCUSTOM: return inst.mOnCustom; + case EVT_CHECKPOINTENTERED: return inst.mOnEntered; + case EVT_CHECKPOINTEXITED: return inst.mOnExited; + default: return NullFunction(); + } +} + + +// ------------------------------------------------------------------------------------------------ +Function & Core::GetKeybindEvent(Int32 id, Int32 evid) +{ + KeybindInst & inst = m_Keybinds.at(id); + + switch (evid) + { + case EVT_KEYBINDDESTROYED: return inst.mOnDestroyed; + case EVT_KEYBINDCUSTOM: return inst.mOnCustom; + case EVT_PLAYERKEYPRESS: return inst.mOnKeyPress; + case EVT_PLAYERKEYRELEASE: return inst.mOnKeyRelease; + default: return NullFunction(); + } +} + +// ------------------------------------------------------------------------------------------------ +Function & Core::GetObjectEvent(Int32 id, Int32 evid) +{ + ObjectInst & inst = m_Objects.at(id); + + switch (evid) + { + case EVT_OBJECTDESTROYED: return inst.mOnDestroyed; + case EVT_OBJECTCUSTOM: return inst.mOnCustom; + case EVT_OBJECTSHOT: return inst.mOnShot; + case EVT_OBJECTTOUCHED: return inst.mOnTouched; + default: return NullFunction(); + } +} + +// ------------------------------------------------------------------------------------------------ +Function & Core::GetPickupEvent(Int32 id, Int32 evid) +{ + PickupInst & inst = m_Pickups.at(id); + + switch (evid) + { + case EVT_PICKUPDESTROYED: return inst.mOnDestroyed; + case EVT_PICKUPCUSTOM: return inst.mOnCustom; + case EVT_PICKUPRESPAWN: return inst.mOnRespawn; + case EVT_PICKUPCLAIMED: return inst.mOnClaimed; + case EVT_PICKUPCOLLECTED: return inst.mOnCollected; + default: return NullFunction(); + } +} + +// ------------------------------------------------------------------------------------------------ +Function & Core::GetPlayerEvent(Int32 id, Int32 evid) +{ + PlayerInst & inst = m_Players.at(id); + + switch (evid) + { + case EVT_PLAYERDESTROYED: return inst.mOnDestroyed; + case EVT_PLAYERCUSTOM: return inst.mOnCustom; + case EVT_PLAYERREQUESTCLASS: return inst.mOnRequestClass; + case EVT_PLAYERREQUESTSPAWN: return inst.mOnRequestSpawn; + case EVT_PLAYERSPAWN: return inst.mOnSpawn; + case EVT_PLAYERWASTED: return inst.mOnWasted; + case EVT_PLAYERKILLED: return inst.mOnKilled; + case EVT_PLAYEREMBARKING: return inst.mOnEmbarking; + case EVT_PLAYEREMBARKED: return inst.mOnEmbarked; + case EVT_PLAYERDISEMBARK: return inst.mOnDisembark; + case EVT_PLAYERRENAME: return inst.mOnRename; + case EVT_PLAYERSTATE: return inst.mOnState; + case EVT_STATENONE: return inst.mOnStateNone; + case EVT_STATENORMAL: return inst.mOnStateNormal; + case EVT_STATEAIM: return inst.mOnStateAim; + case EVT_STATEDRIVER: return inst.mOnStateDriver; + case EVT_STATEPASSENGER: return inst.mOnStatePassenger; + case EVT_STATEENTERDRIVER: return inst.mOnStateEnterDriver; + case EVT_STATEENTERPASSENGER: return inst.mOnStateEnterPassenger; + case EVT_STATEEXIT: return inst.mOnStateExit; + case EVT_STATEUNSPAWNED: return inst.mOnStateUnspawned; + case EVT_PLAYERACTION: return inst.mOnAction; + case EVT_ACTIONNONE: return inst.mOnActionNone; + case EVT_ACTIONNORMAL: return inst.mOnActionNormal; + case EVT_ACTIONAIMING: return inst.mOnActionAiming; + case EVT_ACTIONSHOOTING: return inst.mOnActionShooting; + case EVT_ACTIONJUMPING: return inst.mOnActionJumping; + case EVT_ACTIONLIEDOWN: return inst.mOnActionLieDown; + case EVT_ACTIONGETTINGUP: return inst.mOnActionGettingUp; + case EVT_ACTIONJUMPVEHICLE: return inst.mOnActionJumpVehicle; + case EVT_ACTIONDRIVING: return inst.mOnActionDriving; + case EVT_ACTIONDYING: return inst.mOnActionDying; + case EVT_ACTIONWASTED: return inst.mOnActionWasted; + case EVT_ACTIONEMBARKING: return inst.mOnActionEmbarking; + case EVT_ACTIONDISEMBARKING: return inst.mOnActionDisembarking; + case EVT_PLAYERBURNING: return inst.mOnBurning; + case EVT_PLAYERCROUCHING: return inst.mOnCrouching; + case EVT_PLAYERGAMEKEYS: return inst.mOnGameKeys; + case EVT_PLAYERSTARTTYPING: return inst.mOnStartTyping; + case EVT_PLAYERSTOPTYPING: return inst.mOnStopTyping; + case EVT_PLAYERAWAY: return inst.mOnAway; + case EVT_PLAYERMESSAGE: return inst.mOnMessage; + case EVT_PLAYERCOMMAND: return inst.mOnCommand; + case EVT_PLAYERPRIVATEMESSAGE: return inst.mOnPrivateMessage; + case EVT_PLAYERKEYPRESS: return inst.mOnKeyPress; + case EVT_PLAYERKEYRELEASE: return inst.mOnKeyRelease; + case EVT_PLAYERSPECTATE: return inst.mOnSpectate; + case EVT_PLAYERCRASHREPORT: return inst.mOnCrashreport; + case EVT_OBJECTSHOT: return inst.mOnObjectShot; + case EVT_OBJECTTOUCHED: return inst.mOnObjectTouched; + case EVT_PICKUPCLAIMED: return inst.mOnPickupClaimed; + case EVT_PICKUPCOLLECTED: return inst.mOnPickupCollected; + case EVT_CHECKPOINTENTERED: return inst.mOnCheckpointEntered; + case EVT_CHECKPOINTEXITED: return inst.mOnCheckpointExited; + case EVT_CLIENTSCRIPTDATA: return inst.mOnClientScriptData; + case EVT_PLAYERUPDATE: return inst.mOnUpdate; + case EVT_PLAYERHEALTH: return inst.mOnHealth; + case EVT_PLAYERARMOUR: return inst.mOnArmour; + case EVT_PLAYERWEAPON: return inst.mOnWeapon; + case EVT_PLAYERHEADING: return inst.mOnHeading; + case EVT_PLAYERPOSITION: return inst.mOnPosition; + case EVT_PLAYEROPTION: return inst.mOnOption; + default: return NullFunction(); + } +} + +// ------------------------------------------------------------------------------------------------ +Function & Core::GetVehicleEvent(Int32 id, Int32 evid) +{ + VehicleInst & inst = m_Vehicles.at(id); + + switch (evid) + { + case EVT_PLAYEREMBARKING: return inst.mOnEmbarking; + case EVT_PLAYEREMBARKED: return inst.mOnEmbarked; + case EVT_PLAYERDISEMBARK: return inst.mOnDisembark; + case EVT_VEHICLEEXPLODE: return inst.mOnExplode; + case EVT_VEHICLERESPAWN: return inst.mOnRespawn; + case EVT_VEHICLEUPDATE: return inst.mOnUpdate; + case EVT_VEHICLECOLOUR: return inst.mOnColour; + case EVT_VEHICLEHEALTH: return inst.mOnHealth; + case EVT_VEHICLEPOSITION: return inst.mOnPosition; + case EVT_VEHICLEROTATION: return inst.mOnRotation; + case EVT_VEHICLEOPTION: return inst.mOnOption; + default: return NullFunction(); + } +} + +} // Namespace:: SqMod diff --git a/source/Entity/Blip.cpp b/source/Entity/Blip.cpp index 34b1cd8b..df848431 100644 --- a/source/Entity/Blip.cpp +++ b/source/Entity/Blip.cpp @@ -12,7 +12,7 @@ const Int32 CBlip::Max = SQMOD_BLIP_POOL; // ------------------------------------------------------------------------------------------------ SQInteger CBlip::Typename(HSQUIRRELVM vm) { - static SQChar name[] = _SC("SqBlip"); + static const SQChar name[] = _SC("SqBlip"); sq_pushstring(vm, name, sizeof(name)); return 1; } @@ -35,11 +35,17 @@ CBlip::~CBlip() Int32 CBlip::Cmp(const CBlip & o) const { if (m_ID == o.m_ID) + { return 0; + } else if (m_ID > o.m_ID) + { return 1; + } else + { return -1; + } } // ------------------------------------------------------------------------------------------------ @@ -84,7 +90,7 @@ bool CBlip::Destroy(Int32 header, Object & payload) // Validate the managed identifier Validate(); // Perform the requested operation - return _Core->DelBlip(m_ID, header, payload); + return Core::Get().DelBlip(m_ID, header, payload); } // ------------------------------------------------------------------------------------------------ @@ -93,7 +99,7 @@ void CBlip::BindEvent(Int32 evid, Object & env, Function & func) const // Validate the managed identifier Validate(); // Obtain the function instance called for this event - Function & event = _Core->GetBlipEvent(m_ID, evid); + Function & event = Core::Get().GetBlipEvent(m_ID, evid); // Is the specified callback function null? if (func.IsNull()) { @@ -112,7 +118,7 @@ Int32 CBlip::GetWorld() const // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetBlip(m_ID).mWorld; + return Core::Get().GetBlip(m_ID).mWorld; } // ------------------------------------------------------------------------------------------------ @@ -121,7 +127,7 @@ Int32 CBlip::GetScale() const // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetBlip(m_ID).mScale; + return Core::Get().GetBlip(m_ID).mScale; } // ------------------------------------------------------------------------------------------------ @@ -130,7 +136,7 @@ const Vector3 & CBlip::GetPosition() const // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetBlip(m_ID).mPosition; + return Core::Get().GetBlip(m_ID).mPosition; } // ------------------------------------------------------------------------------------------------ @@ -139,7 +145,7 @@ const Color4 & CBlip::GetColor() const // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetBlip(m_ID).mColor; + return Core::Get().GetBlip(m_ID).mColor; } // ------------------------------------------------------------------------------------------------ @@ -148,34 +154,34 @@ Int32 CBlip::GetSprID() const // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetBlip(m_ID).mSprID; + return Core::Get().GetBlip(m_ID).mSprID; } // ------------------------------------------------------------------------------------------------ -Float32 CBlip::GetPosX() const +Float32 CBlip::GetPositionX() const { // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetBlip(m_ID).mPosition.x; + return Core::Get().GetBlip(m_ID).mPosition.x; } // ------------------------------------------------------------------------------------------------ -Float32 CBlip::GetPosY() const +Float32 CBlip::GetPositionY() const { // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetBlip(m_ID).mPosition.y; + return Core::Get().GetBlip(m_ID).mPosition.y; } // ------------------------------------------------------------------------------------------------ -Float32 CBlip::GetPosZ() const +Float32 CBlip::GetPositionZ() const { // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetBlip(m_ID).mPosition.z; + return Core::Get().GetBlip(m_ID).mPosition.z; } // ------------------------------------------------------------------------------------------------ @@ -184,7 +190,7 @@ Int32 CBlip::GetColorR() const // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetBlip(m_ID).mColor.r; + return Core::Get().GetBlip(m_ID).mColor.r; } // ------------------------------------------------------------------------------------------------ @@ -193,7 +199,7 @@ Int32 CBlip::GetColorG() const // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetBlip(m_ID).mColor.g; + return Core::Get().GetBlip(m_ID).mColor.g; } // ------------------------------------------------------------------------------------------------ @@ -202,7 +208,7 @@ Int32 CBlip::GetColorB() const // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetBlip(m_ID).mColor.b; + return Core::Get().GetBlip(m_ID).mColor.b; } // ------------------------------------------------------------------------------------------------ @@ -211,14 +217,14 @@ Int32 CBlip::GetColorA() const // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetBlip(m_ID).mColor.a; + return Core::Get().GetBlip(m_ID).mColor.a; } // ------------------------------------------------------------------------------------------------ static Object & Blip_CreateEx(Int32 world, Float32 x, Float32 y, Float32 z, Int32 scale, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Int32 sprid) { - return _Core->NewBlip(-1, world, x, y, z, scale, SQMOD_PACK_RGBA(r, g, b, a), sprid, + return Core::Get().NewBlip(-1, world, x, y, z, scale, SQMOD_PACK_RGBA(r, g, b, a), sprid, SQMOD_CREATE_DEFAULT, NullObject()); } @@ -226,7 +232,7 @@ static Object & Blip_CreateEx(Int32 world, Float32 x, Float32 y, Float32 z, Int3 Uint8 r, Uint8 g, Uint8 b, Uint8 a, Int32 sprid, Int32 header, Object & payload) { - return _Core->NewBlip(-1, world, x, y, z, scale, SQMOD_PACK_RGBA(r, g, b, a), sprid, + return Core::Get().NewBlip(-1, world, x, y, z, scale, SQMOD_PACK_RGBA(r, g, b, a), sprid, header, payload); } @@ -234,7 +240,7 @@ static Object & Blip_CreateEx(Int32 world, Float32 x, Float32 y, Float32 z, Int3 static Object & Blip_CreateEx(Int32 index, Int32 world, Float32 x, Float32 y, Float32 z, Int32 scale, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Int32 sprid) { - return _Core->NewBlip(index, world, x, y, z, scale, SQMOD_PACK_RGBA(r, g, b, a), sprid, + return Core::Get().NewBlip(index, world, x, y, z, scale, SQMOD_PACK_RGBA(r, g, b, a), sprid, SQMOD_CREATE_DEFAULT, NullObject()); } @@ -242,7 +248,7 @@ static Object & Blip_CreateEx(Int32 index, Int32 world, Float32 x, Float32 y, Fl Uint8 r, Uint8 g, Uint8 b, Uint8 a, Int32 sprid, Int32 header, Object & payload) { - return _Core->NewBlip(index, world, x, y, z, scale, SQMOD_PACK_RGBA(r, g, b, a), sprid, + return Core::Get().NewBlip(index, world, x, y, z, scale, SQMOD_PACK_RGBA(r, g, b, a), sprid, header, payload); } @@ -250,14 +256,14 @@ static Object & Blip_CreateEx(Int32 index, Int32 world, Float32 x, Float32 y, Fl static Object & Blip_Create(Int32 world, const Vector3 & pos, Int32 scale, const Color4 & color, Int32 sprid) { - return _Core->NewBlip(-1, world, pos.x, pos.y, pos.z, scale, color.GetRGBA(), sprid, + return Core::Get().NewBlip(-1, world, pos.x, pos.y, pos.z, scale, color.GetRGBA(), sprid, SQMOD_CREATE_DEFAULT, NullObject()); } static Object & Blip_Create(Int32 world, const Vector3 & pos, Int32 scale, const Color4 & color, Int32 sprid, Int32 header, Object & payload) { - return _Core->NewBlip(-1, world, pos.x, pos.y, pos.z, scale, color.GetRGBA(), sprid, + return Core::Get().NewBlip(-1, world, pos.x, pos.y, pos.z, scale, color.GetRGBA(), sprid, header, payload); } @@ -265,14 +271,14 @@ static Object & Blip_Create(Int32 world, const Vector3 & pos, Int32 scale, const static Object & Blip_Create(Int32 index, Int32 world, const Vector3 & pos, Int32 scale, const Color4 & color, Int32 sprid) { - return _Core->NewBlip(index, world, pos.x, pos.y, pos.z, scale, color.GetRGBA(), sprid, + return Core::Get().NewBlip(index, world, pos.x, pos.y, pos.z, scale, color.GetRGBA(), sprid, SQMOD_CREATE_DEFAULT, NullObject()); } static Object & Blip_Create(Int32 index, Int32 world, const Vector3 & pos, Int32 scale, const Color4 & color, Int32 sprid, Int32 header, Object & payload) { - return _Core->NewBlip(index, world, pos.x, pos.y, pos.z, scale, color.GetRGBA(), sprid, + return Core::Get().NewBlip(index, world, pos.x, pos.y, pos.z, scale, color.GetRGBA(), sprid, header, payload); } @@ -283,8 +289,8 @@ static const Object & Blip_FindByID(Int32 id) if (INVALID_ENTITYEX(id, SQMOD_BLIP_POOL)) STHROWF("The specified blip identifier is invalid: %d", id); // Obtain the ends of the entity pool - Core::Blips::const_iterator itr = _Core->GetBlips().cbegin(); - Core::Blips::const_iterator end = _Core->GetBlips().cend(); + Core::Blips::const_iterator itr = Core::Get().GetBlips().cbegin(); + Core::Blips::const_iterator end = Core::Get().GetBlips().cend(); // Process each entity in the pool for (; itr != end; ++itr) { @@ -306,8 +312,8 @@ static const Object & Blip_FindByTag(CSStr tag) STHROWF("The specified blip tag is invalid: null/empty"); } // Obtain the ends of the entity pool - Core::Blips::const_iterator itr = _Core->GetBlips().cbegin(); - Core::Blips::const_iterator end = _Core->GetBlips().cend(); + Core::Blips::const_iterator itr = Core::Get().GetBlips().cbegin(); + Core::Blips::const_iterator end = Core::Get().GetBlips().cend(); // Process each entity in the pool for (; itr != end; ++itr) { @@ -330,8 +336,8 @@ static const Object & Blip_FindBySprID(Int32 sprid) STHROWF("The specified sprite identifier is invalid: %d", sprid); } // Obtain the ends of the entity pool - Core::Blips::const_iterator itr = _Core->GetBlips().cbegin(); - Core::Blips::const_iterator end = _Core->GetBlips().cend(); + Core::Blips::const_iterator itr = Core::Get().GetBlips().cbegin(); + Core::Blips::const_iterator end = Core::Get().GetBlips().cend(); // Process each entity in the pool for (; itr != end; ++itr) { @@ -351,8 +357,8 @@ static Array Blip_FindActive() // Remember the initial stack size StackGuard sg; // Obtain the ends of the entity pool - Core::Blips::const_iterator itr = _Core->GetBlips().cbegin(); - Core::Blips::const_iterator end = _Core->GetBlips().cend(); + Core::Blips::const_iterator itr = Core::Get().GetBlips().cbegin(); + Core::Blips::const_iterator end = Core::Get().GetBlips().cend(); // Allocate an empty array on the stack sq_newarray(DefaultVM::Get(), 0); // Process each entity in the pool @@ -403,13 +409,13 @@ void Register_CBlip(HSQUIRRELVM vm) .Prop(_SC("Position"), &CBlip::GetPosition) .Prop(_SC("Color"), &CBlip::GetColor) .Prop(_SC("SprID"), &CBlip::GetSprID) - .Prop(_SC("X"), &CBlip::GetPosX) - .Prop(_SC("Y"), &CBlip::GetPosY) - .Prop(_SC("Z"), &CBlip::GetPosZ) - .Prop(_SC("R"), &CBlip::GetColorR) - .Prop(_SC("G"), &CBlip::GetColorG) - .Prop(_SC("B"), &CBlip::GetColorB) - .Prop(_SC("A"), &CBlip::GetColorA) + .Prop(_SC("PosX"), &CBlip::GetPositionX) + .Prop(_SC("PosY"), &CBlip::GetPositionY) + .Prop(_SC("PosZ"), &CBlip::GetPositionZ) + .Prop(_SC("Red"), &CBlip::GetColorR) + .Prop(_SC("Green"), &CBlip::GetColorG) + .Prop(_SC("Blue"), &CBlip::GetColorB) + .Prop(_SC("Alpha"), &CBlip::GetColorA) // Static Functions .StaticFunc(_SC("FindByID"), &Blip_FindByID) .StaticFunc(_SC("FindByTag"), &Blip_FindByTag) diff --git a/source/Entity/Blip.hpp b/source/Entity/Blip.hpp index cda00584..52727372 100644 --- a/source/Entity/Blip.hpp +++ b/source/Entity/Blip.hpp @@ -185,17 +185,17 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the position on the x axis of the managed blip entity. */ - Float32 GetPosX() const; + Float32 GetPositionX() const; /* -------------------------------------------------------------------------------------------- * Retrieve the position on the y axis of the managed blip entity. */ - Float32 GetPosY() const; + Float32 GetPositionY() const; /* -------------------------------------------------------------------------------------------- * Retrieve the position on the z axis of the managed blip entity. */ - Float32 GetPosZ() const; + Float32 GetPositionZ() const; /* -------------------------------------------------------------------------------------------- * Retrieve the red color of the managed blip entity. diff --git a/source/Entity/Checkpoint.cpp b/source/Entity/Checkpoint.cpp index 8546a141..f41bc8cf 100644 --- a/source/Entity/Checkpoint.cpp +++ b/source/Entity/Checkpoint.cpp @@ -14,10 +14,10 @@ Color4 CCheckpoint::s_Color4; Vector3 CCheckpoint::s_Vector3; // ------------------------------------------------------------------------------------------------ -Uint32 CCheckpoint::s_ColorR; -Uint32 CCheckpoint::s_ColorG; -Uint32 CCheckpoint::s_ColorB; -Uint32 CCheckpoint::s_ColorA; +Int32 CCheckpoint::s_ColorR; +Int32 CCheckpoint::s_ColorG; +Int32 CCheckpoint::s_ColorB; +Int32 CCheckpoint::s_ColorA; // ------------------------------------------------------------------------------------------------ const Int32 CCheckpoint::Max = SQMOD_CHECKPOINT_POOL; @@ -25,7 +25,7 @@ const Int32 CCheckpoint::Max = SQMOD_CHECKPOINT_POOL; // ------------------------------------------------------------------------------------------------ SQInteger CCheckpoint::Typename(HSQUIRRELVM vm) { - static SQChar name[] = _SC("SqCheckpoint"); + static const SQChar name[] = _SC("SqCheckpoint"); sq_pushstring(vm, name, sizeof(name)); return 1; } @@ -48,11 +48,17 @@ CCheckpoint::~CCheckpoint() Int32 CCheckpoint::Cmp(const CCheckpoint & o) const { if (m_ID == o.m_ID) + { return 0; + } else if (m_ID > o.m_ID) + { return 1; + } else + { return -1; + } } // ------------------------------------------------------------------------------------------------ @@ -97,7 +103,7 @@ bool CCheckpoint::Destroy(Int32 header, Object & payload) // Validate the managed identifier Validate(); // Perform the requested operation - return _Core->DelCheckpoint(m_ID, header, payload); + return Core::Get().DelCheckpoint(m_ID, header, payload); } // ------------------------------------------------------------------------------------------------ @@ -106,7 +112,7 @@ void CCheckpoint::BindEvent(Int32 evid, Object & env, Function & func) const // Validate the managed identifier Validate(); // Obtain the function instance called for this event - Function & event = _Core->GetCheckpointEvent(m_ID, evid); + Function & event = Core::Get().GetCheckpointEvent(m_ID, evid); // Is the specified callback function null? if (func.IsNull()) { @@ -130,7 +136,16 @@ bool CCheckpoint::IsStreamedFor(CPlayer & player) const // Validate the managed identifier Validate(); // Return the requested information - return _Func->IsCheckpointStreamedForPlayer(m_ID, player.GetID()); + return _Func->IsCheckPointStreamedForPlayer(m_ID, player.GetID()); +} + +// ------------------------------------------------------------------------------------------------ +bool CCheckpoint::IsSphere() const +{ + // Validate the managed identifier + Validate(); + // Return the requested information + return _Func->IsCheckPointSphere(m_ID); } // ------------------------------------------------------------------------------------------------ @@ -139,7 +154,7 @@ Int32 CCheckpoint::GetWorld() const // Validate the managed identifier Validate(); // Return the requested information - return _Func->GetCheckpointWorld(m_ID); + return _Func->GetCheckPointWorld(m_ID); } // ------------------------------------------------------------------------------------------------ @@ -148,7 +163,7 @@ void CCheckpoint::SetWorld(Int32 world) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetCheckpointWorld(m_ID, world); + _Func->SetCheckPointWorld(m_ID, world); } // ------------------------------------------------------------------------------------------------ @@ -157,9 +172,9 @@ const Color4 & CCheckpoint::GetColor() const // Validate the managed identifier Validate(); // Clear previous color information, if any - s_Color4.Clear(); + s_ColorR = s_ColorG = s_ColorB = s_ColorA = 0; // Query the server for the color values - _Func->GetCheckpointColor(m_ID, &s_ColorR, &s_ColorG, &s_ColorB, &s_ColorA); + _Func->GetCheckPointColour(m_ID, &s_ColorR, &s_ColorG, &s_ColorB, &s_ColorA); // Convert and assign the retrieved values s_Color4.Set(s_ColorR, s_ColorG, s_ColorB, s_ColorA); // Return the requested information @@ -172,7 +187,16 @@ void CCheckpoint::SetColor(const Color4 & col) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetCheckpointColor(m_ID, col.r, col.g, col.b, col.a); + _Func->SetCheckPointColour(m_ID, col.r, col.g, col.b, col.a); +} + +// ------------------------------------------------------------------------------------------------ +void CCheckpoint::SetColorEx(Uint8 r, Uint8 g, Uint8 b) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->SetCheckPointColour(m_ID, r, g, b, 0xFF); } // ------------------------------------------------------------------------------------------------ @@ -181,7 +205,7 @@ void CCheckpoint::SetColorEx(Uint8 r, Uint8 g, Uint8 b, Uint8 a) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetCheckpointColor(m_ID, r, g, b, a); + _Func->SetCheckPointColour(m_ID, r, g, b, a); } // ------------------------------------------------------------------------------------------------ @@ -192,7 +216,7 @@ const Vector3 & CCheckpoint::GetPosition() const // Clear previous position information, if any s_Vector3.Clear(); // Query the server for the position values - _Func->GetCheckpointPos(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); + _Func->GetCheckPointPosition(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); // Return the requested information return s_Vector3; } @@ -203,7 +227,7 @@ void CCheckpoint::SetPosition(const Vector3 & pos) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetCheckpointPos(m_ID, pos.x, pos.y, pos.z); + _Func->SetCheckPointPosition(m_ID, pos.x, pos.y, pos.z); } // ------------------------------------------------------------------------------------------------ @@ -212,7 +236,7 @@ void CCheckpoint::SetPositionEx(Float32 x, Float32 y, Float32 z) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetCheckpointPos(m_ID, x, y, z); + _Func->SetCheckPointPosition(m_ID, x, y, z); } // ------------------------------------------------------------------------------------------------ @@ -221,7 +245,7 @@ Float32 CCheckpoint::GetRadius() const // Validate the managed identifier Validate(); // Return the requested information - return _Func->GetCheckpointRadius(m_ID); + return _Func->GetCheckPointRadius(m_ID); } // ------------------------------------------------------------------------------------------------ @@ -230,7 +254,7 @@ void CCheckpoint::SetRadius(Float32 radius) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetCheckpointRadius(m_ID, radius); + _Func->SetCheckPointRadius(m_ID, radius); } // ------------------------------------------------------------------------------------------------ @@ -239,7 +263,7 @@ Object & CCheckpoint::GetOwner() const // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetPlayer(_Func->GetCheckpointOwner(m_ID)).mObj; + return Core::Get().GetPlayer(_Func->GetCheckPointOwner(m_ID)).mObj; } // ------------------------------------------------------------------------------------------------ @@ -248,205 +272,208 @@ Int32 CCheckpoint::GetOwnerID() const // Validate the managed identifier Validate(); // Return the requested information - return _Func->GetCheckpointOwner(m_ID); + return _Func->GetCheckPointOwner(m_ID); } // ------------------------------------------------------------------------------------------------ -Float32 CCheckpoint::GetPosX() const +Float32 CCheckpoint::GetPositionX() const { // Validate the managed identifier Validate(); // Clear previous position information, if any s_Vector3.x = 0; // Query the server for the requested component value - _Func->GetCheckpointPos(m_ID, &s_Vector3.x, NULL, NULL); + _Func->GetCheckPointPosition(m_ID, &s_Vector3.x, nullptr, nullptr); // Return the requested information return s_Vector3.x; } // ------------------------------------------------------------------------------------------------ -Float32 CCheckpoint::GetPosY() const +Float32 CCheckpoint::GetPositionY() const { // Validate the managed identifier Validate(); // Clear previous position information, if any s_Vector3.y = 0; // Query the server for the requested component value - _Func->GetCheckpointPos(m_ID, NULL, &s_Vector3.y, NULL); + _Func->GetCheckPointPosition(m_ID, nullptr, &s_Vector3.y, nullptr); // Return the requested information return s_Vector3.y; } // ------------------------------------------------------------------------------------------------ -Float32 CCheckpoint::GetPosZ() const +Float32 CCheckpoint::GetPositionZ() const { // Validate the managed identifier Validate(); // Clear previous position information, if any s_Vector3.z = 0; // Query the server for the requested component value - _Func->GetCheckpointPos(m_ID, NULL, NULL, &s_Vector3.z); + _Func->GetCheckPointPosition(m_ID, nullptr, nullptr, &s_Vector3.z); // Return the requested information return s_Vector3.z; } // ------------------------------------------------------------------------------------------------ -void CCheckpoint::SetPosX(Float32 x) const +void CCheckpoint::SetPositionX(Float32 x) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetCheckpointPos(m_ID, NULL, &s_Vector3.y, &s_Vector3.z); + _Func->GetCheckPointPosition(m_ID, nullptr, &s_Vector3.y, &s_Vector3.z); // Perform the requested operation - _Func->SetCheckpointPos(m_ID, x, s_Vector3.y, s_Vector3.z); + _Func->SetCheckPointPosition(m_ID, x, s_Vector3.y, s_Vector3.z); } // ------------------------------------------------------------------------------------------------ -void CCheckpoint::SetPosY(Float32 y) const +void CCheckpoint::SetPositionY(Float32 y) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetCheckpointPos(m_ID, &s_Vector3.x, NULL, &s_Vector3.z); + _Func->GetCheckPointPosition(m_ID, &s_Vector3.x, nullptr, &s_Vector3.z); // Perform the requested operation - _Func->SetCheckpointPos(m_ID, s_Vector3.x, y, s_Vector3.z); + _Func->SetCheckPointPosition(m_ID, s_Vector3.x, y, s_Vector3.z); } // ------------------------------------------------------------------------------------------------ -void CCheckpoint::SetPosZ(Float32 z) const +void CCheckpoint::SetPositionZ(Float32 z) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetCheckpointPos(m_ID, &s_Vector3.x, &s_Vector3.y, NULL); + _Func->GetCheckPointPosition(m_ID, &s_Vector3.x, &s_Vector3.y, nullptr); // Perform the requested operation - _Func->SetCheckpointPos(m_ID, s_Vector3.z, s_Vector3.y, z); + _Func->SetCheckPointPosition(m_ID, s_Vector3.z, s_Vector3.y, z); } // ------------------------------------------------------------------------------------------------ -Uint32 CCheckpoint::GetColR() const +Int32 CCheckpoint::GetColorR() const { // Validate the managed identifier Validate(); // Clear previous color information, if any s_ColorR = 0; // Query the server for the requested component value - _Func->GetCheckpointColor(m_ID, &s_ColorR, NULL, NULL, NULL); + _Func->GetCheckPointColour(m_ID, &s_ColorR, NULL, NULL, NULL); // Return the requested information return s_ColorR; } // ------------------------------------------------------------------------------------------------ -Uint32 CCheckpoint::GetColG() const +Int32 CCheckpoint::GetColorG() const { // Validate the managed identifier Validate(); // Clear previous color information, if any s_ColorG = 0; // Query the server for the requested component value - _Func->GetCheckpointColor(m_ID, NULL, &s_ColorG, NULL, NULL); + _Func->GetCheckPointColour(m_ID, NULL, &s_ColorG, NULL, NULL); // Return the requested information return s_ColorG; } // ------------------------------------------------------------------------------------------------ -Uint32 CCheckpoint::GetColB() const +Int32 CCheckpoint::GetColorB() const { // Validate the managed identifier Validate(); // Clear previous color information, if any s_ColorB = 0; // Query the server for the requested component value - _Func->GetCheckpointColor(m_ID, NULL, NULL, &s_ColorB, NULL); + _Func->GetCheckPointColour(m_ID, NULL, NULL, &s_ColorB, NULL); // Return the requested information return s_ColorB; } // ------------------------------------------------------------------------------------------------ -Uint32 CCheckpoint::GetColA() const +Int32 CCheckpoint::GetColorA() const { // Validate the managed identifier Validate(); // Clear previous color information, if any s_ColorA = 0; // Query the server for the requested component value - _Func->GetCheckpointColor(m_ID, NULL, NULL, NULL, &s_ColorA); + _Func->GetCheckPointColour(m_ID, NULL, NULL, NULL, &s_ColorA); // Return the requested information return s_ColorA; } // ------------------------------------------------------------------------------------------------ -void CCheckpoint::SetColR(Uint32 r) const +void CCheckpoint::SetColorR(Int32 r) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetCheckpointColor(m_ID, NULL, &s_ColorG, &s_ColorB, &s_ColorA); + _Func->GetCheckPointColour(m_ID, NULL, &s_ColorG, &s_ColorB, &s_ColorA); // Perform the requested operation - _Func->SetCheckpointColor(m_ID, r, s_ColorG, s_ColorB, s_ColorA); + _Func->SetCheckPointColour(m_ID, r, s_ColorG, s_ColorB, s_ColorA); } // ------------------------------------------------------------------------------------------------ -void CCheckpoint::SetColG(Uint32 g) const +void CCheckpoint::SetColorG(Int32 g) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetCheckpointColor(m_ID, &s_ColorR, NULL, &s_ColorB, &s_ColorA); + _Func->GetCheckPointColour(m_ID, &s_ColorR, NULL, &s_ColorB, &s_ColorA); // Perform the requested operation - _Func->SetCheckpointColor(m_ID, s_ColorR, g, s_ColorB, s_ColorA); + _Func->SetCheckPointColour(m_ID, s_ColorR, g, s_ColorB, s_ColorA); } // ------------------------------------------------------------------------------------------------ -void CCheckpoint::SetColB(Uint32 b) const +void CCheckpoint::SetColorB(Int32 b) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetCheckpointColor(m_ID, &s_ColorB, &s_ColorG, NULL, &s_ColorA); + _Func->GetCheckPointColour(m_ID, &s_ColorB, &s_ColorG, NULL, &s_ColorA); // Perform the requested operation - _Func->SetCheckpointColor(m_ID, s_ColorB, s_ColorG, b, s_ColorA); + _Func->SetCheckPointColour(m_ID, s_ColorB, s_ColorG, b, s_ColorA); } // ------------------------------------------------------------------------------------------------ -void CCheckpoint::SetColA(Uint32 a) const +void CCheckpoint::SetColorA(Int32 a) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetCheckpointColor(m_ID, &s_ColorA, &s_ColorG, &s_ColorB, NULL); + _Func->GetCheckPointColour(m_ID, &s_ColorA, &s_ColorG, &s_ColorB, NULL); // Perform the requested operation - _Func->SetCheckpointColor(m_ID, s_ColorA, s_ColorG, s_ColorB, a); + _Func->SetCheckPointColour(m_ID, s_ColorA, s_ColorG, s_ColorB, a); } // ------------------------------------------------------------------------------------------------ -static Object & Checkpoint_CreateEx(CPlayer & player, Int32 world, Float32 x, Float32 y, Float32 z, +static Object & Checkpoint_CreateEx(CPlayer & player, Int32 world, bool sphere, + Float32 x, Float32 y, Float32 z, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Float32 radius) { - return _Core->NewCheckpoint(player.GetID(), world, x, y, z, r, g, b, a, radius, + return Core::Get().NewCheckpoint(player.GetID(), world, sphere, x, y, z, r, g, b, a, radius, SQMOD_CREATE_DEFAULT, NullObject()); } -static Object & Checkpoint_CreateEx(CPlayer & player, Int32 world, Float32 x, Float32 y, Float32 z, +static Object & Checkpoint_CreateEx(CPlayer & player, Int32 world, bool sphere, + Float32 x, Float32 y, Float32 z, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Float32 radius, Int32 header, Object & payload) { - return _Core->NewCheckpoint(player.GetID(), world, x, y, z, r, g, b, a, radius, header, payload); + return Core::Get().NewCheckpoint(player.GetID(), world, sphere, x, y, z, r, g, b, a, + radius, header, payload); } // ------------------------------------------------------------------------------------------------ -static Object & Checkpoint_Create(CPlayer & player, Int32 world, const Vector3 & pos, +static Object & Checkpoint_Create(CPlayer & player, Int32 world, bool sphere, const Vector3 & pos, const Color4 & color, Float32 radius) { - return _Core->NewCheckpoint(player.GetID(), world, pos.x, pos.y, pos.z, + return Core::Get().NewCheckpoint(player.GetID(), world, sphere, pos.x, pos.y, pos.z, color.r, color.g, color.b, color.a, radius, SQMOD_CREATE_DEFAULT, NullObject()); } -static Object & Checkpoint_Create(CPlayer & player, Int32 world, const Vector3 & pos, +static Object & Checkpoint_Create(CPlayer & player, Int32 world, bool sphere, const Vector3 & pos, const Color4 & color, Float32 radius, Int32 header, Object & payload) { - return _Core->NewCheckpoint(player.GetID(), world, pos.x, pos.y, pos.z, + return Core::Get().NewCheckpoint(player.GetID(), world, sphere, pos.x, pos.y, pos.z, color.r, color.g, color.b, color.a, radius, header, payload); } @@ -459,8 +486,8 @@ static const Object & Checkpoint_FindByID(Int32 id) STHROWF("The specified checkpoint identifier is invalid: %d", id); } // Obtain the ends of the entity pool - Core::Checkpoints::const_iterator itr = _Core->GetCheckpoints().cbegin(); - Core::Checkpoints::const_iterator end = _Core->GetCheckpoints().cend(); + Core::Checkpoints::const_iterator itr = Core::Get().GetCheckpoints().cbegin(); + Core::Checkpoints::const_iterator end = Core::Get().GetCheckpoints().cend(); // Process each entity in the pool for (; itr != end; ++itr) { @@ -483,8 +510,8 @@ static const Object & Checkpoint_FindByTag(CSStr tag) STHROWF("The specified checkpoint tag is invalid: null/empty"); } // Obtain the ends of the entity pool - Core::Checkpoints::const_iterator itr = _Core->GetCheckpoints().cbegin(); - Core::Checkpoints::const_iterator end = _Core->GetCheckpoints().cend(); + Core::Checkpoints::const_iterator itr = Core::Get().GetCheckpoints().cbegin(); + Core::Checkpoints::const_iterator end = Core::Get().GetCheckpoints().cend(); // Process each entity in the pool for (; itr != end; ++itr) { @@ -504,8 +531,8 @@ static Array Checkpoint_FindActive() // Remember the initial stack size StackGuard sg; // Obtain the ends of the entity pool - Core::Checkpoints::const_iterator itr = _Core->GetCheckpoints().cbegin(); - Core::Checkpoints::const_iterator end = _Core->GetCheckpoints().cend(); + Core::Checkpoints::const_iterator itr = Core::Get().GetCheckpoints().cbegin(); + Core::Checkpoints::const_iterator end = Core::Get().GetCheckpoints().cend(); // Allocate an empty array on the stack sq_newarray(DefaultVM::Get(), 0); // Process each entity in the pool @@ -550,6 +577,7 @@ void Register_CCheckpoint(HSQUIRRELVM vm) .Overload< bool (CCheckpoint::*)(Int32) >(_SC("Destroy"), &CCheckpoint::Destroy) .Overload< bool (CCheckpoint::*)(Int32, Object &) >(_SC("Destroy"), &CCheckpoint::Destroy) // Properties + .Prop(_SC("Sphere"), &CCheckpoint::IsSphere) .Prop(_SC("World"), &CCheckpoint::GetWorld, &CCheckpoint::SetWorld) .Prop(_SC("Color"), &CCheckpoint::GetColor, &CCheckpoint::SetColor) .Prop(_SC("Pos"), &CCheckpoint::GetPosition, &CCheckpoint::SetPosition) @@ -557,30 +585,34 @@ void Register_CCheckpoint(HSQUIRRELVM vm) .Prop(_SC("Radius"), &CCheckpoint::GetRadius, &CCheckpoint::SetRadius) .Prop(_SC("Owner"), &CCheckpoint::GetOwner) .Prop(_SC("OwnerID"), &CCheckpoint::GetOwnerID) - .Prop(_SC("X"), &CCheckpoint::GetPosX, &CCheckpoint::SetPosX) - .Prop(_SC("Y"), &CCheckpoint::GetPosY, &CCheckpoint::SetPosY) - .Prop(_SC("Z"), &CCheckpoint::GetPosZ, &CCheckpoint::SetPosZ) - .Prop(_SC("R"), &CCheckpoint::GetColR, &CCheckpoint::SetColR) - .Prop(_SC("G"), &CCheckpoint::GetColG, &CCheckpoint::SetColG) - .Prop(_SC("B"), &CCheckpoint::GetColB, &CCheckpoint::SetColB) - .Prop(_SC("A"), &CCheckpoint::GetColA, &CCheckpoint::SetColA) + .Prop(_SC("PosX"), &CCheckpoint::GetPositionX, &CCheckpoint::SetPositionX) + .Prop(_SC("PosY"), &CCheckpoint::GetPositionY, &CCheckpoint::SetPositionY) + .Prop(_SC("PosZ"), &CCheckpoint::GetPositionZ, &CCheckpoint::SetPositionZ) + .Prop(_SC("Red"), &CCheckpoint::GetColorR, &CCheckpoint::SetColorR) + .Prop(_SC("Green"), &CCheckpoint::GetColorG, &CCheckpoint::SetColorG) + .Prop(_SC("Blue"), &CCheckpoint::GetColorB, &CCheckpoint::SetColorB) + .Prop(_SC("Alpha"), &CCheckpoint::GetColorA, &CCheckpoint::SetColorA) // Member Methods .Func(_SC("StreamedFor"), &CCheckpoint::IsStreamedFor) - .Func(_SC("SetColor"), &CCheckpoint::SetColorEx) .Func(_SC("SetPos"), &CCheckpoint::SetPositionEx) .Func(_SC("SetPosition"), &CCheckpoint::SetPositionEx) + // Member Overloads + .Overload< void (CCheckpoint::*)(Uint8, Uint8, Uint8) const > + (_SC("SetColor"), &CCheckpoint::SetColorEx) + .Overload< void (CCheckpoint::*)(Uint8, Uint8, Uint8, Uint8) const > + (_SC("SetColor"), &CCheckpoint::SetColorEx) // Static Functions .StaticFunc(_SC("FindByID"), &Checkpoint_FindByID) .StaticFunc(_SC("FindByTag"), &Checkpoint_FindByTag) .StaticFunc(_SC("FindActive"), &Checkpoint_FindActive) // Static Overloads - .StaticOverload< Object & (*)(CPlayer &, Int32, Float32, Float32, Float32, Uint8, Uint8, Uint8, Uint8, Float32) > + .StaticOverload< Object & (*)(CPlayer &, Int32, bool, Float32, Float32, Float32, Uint8, Uint8, Uint8, Uint8, Float32) > (_SC("CreateEx"), &Checkpoint_CreateEx) - .StaticOverload< Object & (*)(CPlayer &, Int32, Float32, Float32, Float32, Uint8, Uint8, Uint8, Uint8, Float32, Int32, Object &) > + .StaticOverload< Object & (*)(CPlayer &, Int32, bool, Float32, Float32, Float32, Uint8, Uint8, Uint8, Uint8, Float32, Int32, Object &) > (_SC("CreateEx"), &Checkpoint_CreateEx) - .StaticOverload< Object & (*)(CPlayer &, Int32, const Vector3 &, const Color4 &, Float32) > + .StaticOverload< Object & (*)(CPlayer &, Int32, bool, const Vector3 &, const Color4 &, Float32) > (_SC("Create"), &Checkpoint_Create) - .StaticOverload< Object & (*)(CPlayer &, Int32, const Vector3 &, const Color4 &, Float32, Int32, Object &) > + .StaticOverload< Object & (*)(CPlayer &, Int32, bool, const Vector3 &, const Color4 &, Float32, Int32, Object &) > (_SC("Create"), &Checkpoint_Create) ); } diff --git a/source/Entity/Checkpoint.hpp b/source/Entity/Checkpoint.hpp index 09386600..29872e00 100644 --- a/source/Entity/Checkpoint.hpp +++ b/source/Entity/Checkpoint.hpp @@ -22,7 +22,7 @@ private: static Vector3 s_Vector3; // -------------------------------------------------------------------------------------------- - static Uint32 s_ColorR, s_ColorG, s_ColorB, s_ColorA; + static Int32 s_ColorR, s_ColorG, s_ColorB, s_ColorA; /* -------------------------------------------------------------------------------------------- * Identifier of the managed entity. @@ -169,6 +169,11 @@ public: */ bool IsStreamedFor(CPlayer & player) const; + /* -------------------------------------------------------------------------------------------- + * See if the managed checkpoint entity of sphere type. + */ + bool IsSphere() const; + /* -------------------------------------------------------------------------------------------- * Retrieve the world in which the managed checkpoint entity exists. */ @@ -189,6 +194,11 @@ public: */ void SetColor(const Color4 & col) const; + /* -------------------------------------------------------------------------------------------- + * Modify the color of the managed checkpoint entity. + */ + void SetColorEx(Uint8 r, Uint8 g, Uint8 b) const; + /* -------------------------------------------------------------------------------------------- * Modify the color of the managed checkpoint entity. */ @@ -232,72 +242,72 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the position on the x axis of the managed checkpoint entity. */ - Float32 GetPosX() const; + Float32 GetPositionX() const; /* -------------------------------------------------------------------------------------------- * Retrieve the position on the y axis of the managed checkpoint entity. */ - Float32 GetPosY() const; + Float32 GetPositionY() const; /* -------------------------------------------------------------------------------------------- * Retrieve the position on the z axis of the managed checkpoint entity. */ - Float32 GetPosZ() const; + Float32 GetPositionZ() const; /* -------------------------------------------------------------------------------------------- * Modify the position on the x axis of the managed checkpoint entity. */ - void SetPosX(Float32 x) const; + void SetPositionX(Float32 x) const; /* -------------------------------------------------------------------------------------------- * Modify the position on the y axis of the managed checkpoint entity. */ - void SetPosY(Float32 y) const; + void SetPositionY(Float32 y) const; /* -------------------------------------------------------------------------------------------- * Modify the position on the z axis of the managed checkpoint entity. */ - void SetPosZ(Float32 z) const; + void SetPositionZ(Float32 z) const; /* -------------------------------------------------------------------------------------------- * Retrieve the red color of the managed checkpoint entity. */ - Uint32 GetColR() const; + Int32 GetColorR() const; /* -------------------------------------------------------------------------------------------- * Retrieve the green color of the managed checkpoint entity. */ - Uint32 GetColG() const; + Int32 GetColorG() const; /* -------------------------------------------------------------------------------------------- * Retrieve the blue color of the managed checkpoint entity. */ - Uint32 GetColB() const; + Int32 GetColorB() const; /* -------------------------------------------------------------------------------------------- * Retrieve the alpha transparency of the managed checkpoint entity. */ - Uint32 GetColA() const; + Int32 GetColorA() const; /* -------------------------------------------------------------------------------------------- * Modify the red color of the managed checkpoint entity. */ - void SetColR(Uint32 r) const; + void SetColorR(Int32 r) const; /* -------------------------------------------------------------------------------------------- * Modify the green color of the managed checkpoint entity. */ - void SetColG(Uint32 g) const; + void SetColorG(Int32 g) const; /* -------------------------------------------------------------------------------------------- * Modify the blue color of the managed checkpoint entity. */ - void SetColB(Uint32 b) const; + void SetColorB(Int32 b) const; /* -------------------------------------------------------------------------------------------- * Modify the alpha transparency of the managed checkpoint entity. */ - void SetColA(Uint32 a) const; + void SetColorA(Int32 a) const; }; } // Namespace:: SqMod diff --git a/source/Entity/Forcefield.cpp b/source/Entity/Forcefield.cpp deleted file mode 100644 index 4b69115b..00000000 --- a/source/Entity/Forcefield.cpp +++ /dev/null @@ -1,561 +0,0 @@ -// ------------------------------------------------------------------------------------------------ -#include "Entity/Forcefield.hpp" -#include "Entity/Player.hpp" -#include "Base/Color3.hpp" -#include "Base/Vector3.hpp" -#include "Base/Stack.hpp" -#include "Core.hpp" - -// ------------------------------------------------------------------------------------------------ -namespace SqMod { - -// ------------------------------------------------------------------------------------------------ -Color3 CForcefield::s_Color3; -Vector3 CForcefield::s_Vector3; - -// ------------------------------------------------------------------------------------------------ -Uint32 CForcefield::s_ColorR; -Uint32 CForcefield::s_ColorG; -Uint32 CForcefield::s_ColorB; - -// ------------------------------------------------------------------------------------------------ -const Int32 CForcefield::Max = SQMOD_FORCEFIELD_POOL; - -// ------------------------------------------------------------------------------------------------ -SQInteger CForcefield::Typename(HSQUIRRELVM vm) -{ - static SQChar name[] = _SC("SqForcefield"); - sq_pushstring(vm, name, sizeof(name)); - return 1; -} - -// ------------------------------------------------------------------------------------------------ -CForcefield::CForcefield(Int32 id) - : m_ID(VALID_ENTITYGETEX(id, SQMOD_FORCEFIELD_POOL)) - , m_Tag(ToStrF("%d", id)) -{ - /* ... */ -} - -// ------------------------------------------------------------------------------------------------ -CForcefield::~CForcefield() -{ - /* ... */ -} - -// ------------------------------------------------------------------------------------------------ -Int32 CForcefield::Cmp(const CForcefield & o) const -{ - if (m_ID == o.m_ID) - return 0; - else if (m_ID > o.m_ID) - return 1; - else - return -1; -} - -// ------------------------------------------------------------------------------------------------ -const String & CForcefield::ToString() const -{ - return m_Tag; -} - -// ------------------------------------------------------------------------------------------------ -const String & CForcefield::GetTag() const -{ - return m_Tag; -} - -// ------------------------------------------------------------------------------------------------ -void CForcefield::SetTag(CSStr tag) -{ - m_Tag.assign(tag); -} - -// ------------------------------------------------------------------------------------------------ -Object & CForcefield::GetData() -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return m_Data; -} - -// ------------------------------------------------------------------------------------------------ -void CForcefield::SetData(Object & data) -{ - // Validate the managed identifier - Validate(); - // Apply the specified value - m_Data = data; -} - -// ------------------------------------------------------------------------------------------------ -bool CForcefield::Destroy(Int32 header, Object & payload) -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - return _Core->DelForcefield(m_ID, header, payload); -} - -// ------------------------------------------------------------------------------------------------ -void CForcefield::BindEvent(Int32 evid, Object & env, Function & func) const -{ - // Validate the managed identifier - Validate(); - // Obtain the function instance called for this event - Function & event = _Core->GetForcefieldEvent(m_ID, evid); - // Is the specified callback function null? - if (func.IsNull()) - { - event.Release(); // Then release the current callback - } - // Assign the specified environment and function - else - { - event = Function(env.GetVM(), env, func.GetFunc()); - } -} - -// ------------------------------------------------------------------------------------------------ -bool CForcefield::IsStreamedFor(CPlayer & player) const -{ - // Is the specified player even valid? - if (!player.IsActive()) - { - STHROWF("Invalid player argument: null"); - } - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->IsSphereStreamedForPlayer(m_ID, player.GetID()); -} - -// ------------------------------------------------------------------------------------------------ -Int32 CForcefield::GetWorld() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->GetSphereWorld(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -void CForcefield::SetWorld(Int32 world) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->SetSphereWorld(m_ID, world); -} - -// ------------------------------------------------------------------------------------------------ -const Color3 & CForcefield::GetColor() const -{ - // Validate the managed identifier - Validate(); - // Clear previous color information, if any - s_Color3.Clear(); - // Query the server for the color values - _Func->GetSphereColor(m_ID, &s_ColorR, &s_ColorG, &s_ColorB); - // Convert and assign the retrieved values - s_Color3.Set(s_ColorR, s_ColorG, s_ColorB); - // Return the requested information - return s_Color3; -} - -// ------------------------------------------------------------------------------------------------ -void CForcefield::SetColor(const Color3 & col) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->SetSphereColor(m_ID, col.r, col.g, col.b); -} - -// ------------------------------------------------------------------------------------------------ -void CForcefield::SetColorEx(Uint8 r, Uint8 g, Uint8 b) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->SetSphereColor(m_ID, r, g, b); -} - -// ------------------------------------------------------------------------------------------------ -const Vector3 & CForcefield::GetPosition() const -{ - // Validate the managed identifier - Validate(); - // Clear previous position information, if any - s_Vector3.Clear(); - // Query the server for the position values - _Func->GetSpherePos(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); - // Return the requested information - return s_Vector3; -} - -// ------------------------------------------------------------------------------------------------ -void CForcefield::SetPosition(const Vector3 & pos) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->SetSpherePos(m_ID, pos.x, pos.y, pos.z); -} - -// ------------------------------------------------------------------------------------------------ -void CForcefield::SetPositionEx(Float32 x, Float32 y, Float32 z) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->SetSpherePos(m_ID, x, y, z); -} - -// ------------------------------------------------------------------------------------------------ -Float32 CForcefield::GetRadius() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->GetSphereRadius(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -void CForcefield::SetRadius(Float32 radius) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->SetSphereRadius(m_ID, radius); -} - -// ------------------------------------------------------------------------------------------------ -Object & CForcefield::GetOwner() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Core->GetPlayer(_Func->GetSphereOwner(m_ID)).mObj; -} - -// ------------------------------------------------------------------------------------------------ -Int32 CForcefield::GetOwnerID() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->GetSphereOwner(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -Float32 CForcefield::GetPosX() const -{ - // Validate the managed identifier - Validate(); - // Clear previous position information, if any - s_Vector3.x = 0; - // Query the server for the requested component value - _Func->GetSpherePos(m_ID, &s_Vector3.x, NULL, NULL); - // Return the requested information - return s_Vector3.x; -} - -// ------------------------------------------------------------------------------------------------ -Float32 CForcefield::GetPosY() const -{ - // Validate the managed identifier - Validate(); - // Clear previous position information, if any - s_Vector3.y = 0; - // Query the server for the requested component value - _Func->GetSpherePos(m_ID, NULL, &s_Vector3.y, NULL); - // Return the requested information - return s_Vector3.y; -} - -// ------------------------------------------------------------------------------------------------ -Float32 CForcefield::GetPosZ() const -{ - // Validate the managed identifier - Validate(); - // Clear previous position information, if any - s_Vector3.z = 0; - // Query the server for the requested component value - _Func->GetSpherePos(m_ID, NULL, NULL, &s_Vector3.z); - // Return the requested information - return s_Vector3.z; -} - -// ------------------------------------------------------------------------------------------------ -void CForcefield::SetPosX(Float32 x) const -{ - // Validate the managed identifier - Validate(); - // Retrieve the current values for unchanged components - _Func->GetSpherePos(m_ID, NULL, &s_Vector3.y, &s_Vector3.z); - // Perform the requested operation - _Func->SetSpherePos(m_ID, x, s_Vector3.y, s_Vector3.z); -} - -// ------------------------------------------------------------------------------------------------ -void CForcefield::SetPosY(Float32 y) const -{ - // Validate the managed identifier - Validate(); - // Retrieve the current values for unchanged components - _Func->GetSpherePos(m_ID, &s_Vector3.x, NULL, &s_Vector3.z); - // Perform the requested operation - _Func->SetSpherePos(m_ID, s_Vector3.x, y, s_Vector3.z); -} - -// ------------------------------------------------------------------------------------------------ -void CForcefield::SetPosZ(Float32 z) const -{ - // Validate the managed identifier - Validate(); - // Retrieve the current values for unchanged components - _Func->GetSpherePos(m_ID, &s_Vector3.x, &s_Vector3.y, NULL); - // Perform the requested operation - _Func->SetSpherePos(m_ID, s_Vector3.z, s_Vector3.y, z); -} - -// ------------------------------------------------------------------------------------------------ -Uint32 CForcefield::GetColR() const -{ - // Validate the managed identifier - Validate(); - // Clear previous color information, if any - s_ColorR = 0; - // Query the server for the requested component value - _Func->GetSphereColor(m_ID, &s_ColorR, NULL, NULL); - // Return the requested information - return s_ColorR; -} - -// ------------------------------------------------------------------------------------------------ -Uint32 CForcefield::GetColG() const -{ - // Validate the managed identifier - Validate(); - // Query the server for the requested component value - s_ColorG = 0; - // Query the server for the requested component value - _Func->GetSphereColor(m_ID, NULL, &s_ColorG, NULL); - // Return the requested information - return s_ColorG; -} - -// ------------------------------------------------------------------------------------------------ -Uint32 CForcefield::GetColB() const -{ - // Validate the managed identifier - Validate(); - // Query the server for the requested component value - s_ColorB = 0; - // Query the server for the requested component value - _Func->GetSphereColor(m_ID, NULL, NULL, &s_ColorB); - // Return the requested information - return s_ColorB; -} - -// ------------------------------------------------------------------------------------------------ -void CForcefield::SetColR(Uint32 r) const -{ - // Validate the managed identifier - Validate(); - // Retrieve the current values for unchanged components - _Func->GetSphereColor(m_ID, NULL, &s_ColorG, &s_ColorB); - // Perform the requested operation - _Func->SetSphereColor(m_ID, r, s_ColorG, s_ColorB); -} - -// ------------------------------------------------------------------------------------------------ -void CForcefield::SetColG(Uint32 g) const -{ - // Validate the managed identifier - Validate(); - // Retrieve the current values for unchanged components - _Func->GetSphereColor(m_ID, &s_ColorR, NULL, &s_ColorB); - // Perform the requested operation - _Func->SetSphereColor(m_ID, s_ColorR, g, s_ColorB); -} - -// ------------------------------------------------------------------------------------------------ -void CForcefield::SetColB(Uint32 b) const -{ - // Validate the managed identifier - Validate(); - // Retrieve the current values for unchanged components - _Func->GetSphereColor(m_ID, &s_ColorB, &s_ColorG, NULL); - // Perform the requested operation - _Func->SetSphereColor(m_ID, s_ColorB, s_ColorG, b); -} - -// ------------------------------------------------------------------------------------------------ -static Object & Forcefield_CreateEx(CPlayer & player, Int32 world, Float32 x, Float32 y, Float32 z, - Uint8 r, Uint8 g, Uint8 b, Float32 radius) -{ - return _Core->NewForcefield(player.GetID(), world, x, y, z, r, g, b, radius, - SQMOD_CREATE_DEFAULT, NullObject()); -} - -static Object & Forcefield_CreateEx(CPlayer & player, Int32 world, Float32 x, Float32 y, Float32 z, - Uint8 r, Uint8 g, Uint8 b, Float32 radius, - Int32 header, Object & payload) -{ - return _Core->NewForcefield(player.GetID(), world, x, y, z, r, g, b, radius, header, payload); -} - -// ------------------------------------------------------------------------------------------------ -static Object & Forcefield_Create(CPlayer & player, Int32 world, const Vector3 & pos, - const Color3 & color, Float32 radius) -{ - return _Core->NewForcefield(player.GetID(), world, pos.x, pos.y, pos.z, color.r, color.g, color.b, radius, - SQMOD_CREATE_DEFAULT, NullObject()); -} - -static Object & Forcefield_Create(CPlayer & player, Int32 world, const Vector3 & pos, - const Color3 & color, Float32 radius, Int32 header, Object & payload) -{ - return _Core->NewForcefield(player.GetID(), world, pos.x, pos.y, pos.z, color.r, color.g, color.b, radius, - header, payload); -} - -// ------------------------------------------------------------------------------------------------ -static const Object & Forcefield_FindByID(Int32 id) -{ - // Perform a range check on the specified identifier - if (INVALID_ENTITYEX(id, SQMOD_FORCEFIELD_POOL)) - { - STHROWF("The specified forcefield identifier is invalid: %d", id); - } - // Obtain the ends of the entity pool - Core::Forcefields::const_iterator itr = _Core->GetForcefields().cbegin(); - Core::Forcefields::const_iterator end = _Core->GetForcefields().cend(); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Does the identifier match the specified one? - if (itr->mID == id) - { - return itr->mObj; // Stop searching and return this entity - } - } - // Unable to locate a forcefield matching the specified identifier - return NullObject(); -} - -// ------------------------------------------------------------------------------------------------ -static const Object & Forcefield_FindByTag(CSStr tag) -{ - // Perform a validity check on the specified tag - if (!tag || *tag == '\0') - { - STHROWF("The specified forcefield tag is invalid: null/empty"); - } - // Obtain the ends of the entity pool - Core::Forcefields::const_iterator itr = _Core->GetForcefields().cbegin(); - Core::Forcefields::const_iterator end = _Core->GetForcefields().cend(); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Does this entity even exist and does the tag match the specified one? - if (itr->mInst != nullptr && itr->mInst->GetTag().compare(tag) == 0) - { - return itr->mObj; // Stop searching and return this entity - } - } - // Unable to locate a forcefield matching the specified tag - return NullObject(); -} - -// ------------------------------------------------------------------------------------------------ -static Array Forcefield_FindActive() -{ - // Remember the initial stack size - StackGuard sg; - // Obtain the ends of the entity pool - Core::Forcefields::const_iterator itr = _Core->GetForcefields().cbegin(); - Core::Forcefields::const_iterator end = _Core->GetForcefields().cend(); - // Allocate an empty array on the stack - sq_newarray(DefaultVM::Get(), 0); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Is this entity instance active? - if (VALID_ENTITY(itr->mID)) - { - // Push the script object on the stack - sq_pushobject(DefaultVM::Get(), (HSQOBJECT &)((*itr).mObj)); - // Append the object at the back of the array - if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -1))) - { - STHROWF("Unable to append entity instance to the list"); - } - } - } - // Return the array at the top of the stack - return Var< Array >(DefaultVM::Get(), -1).value; -} - -// ================================================================================================ -void Register_CForcefield(HSQUIRRELVM vm) -{ - RootTable(vm).Bind(_SC("SqForcefield"), - Class< CForcefield, NoConstructor< CForcefield > >(vm, _SC("SqForcefield")) - // Metamethods - .Func(_SC("_cmp"), &CForcefield::Cmp) - .SquirrelFunc(_SC("_typename"), &CForcefield::Typename) - .Func(_SC("_tostring"), &CForcefield::ToString) - // Static Values - .SetStaticValue(_SC("MaxID"), CForcefield::Max) - // Core Properties - .Prop(_SC("ID"), &CForcefield::GetID) - .Prop(_SC("Tag"), &CForcefield::GetTag, &CForcefield::SetTag) - .Prop(_SC("Data"), &CForcefield::GetData, &CForcefield::SetData) - .Prop(_SC("Active"), &CForcefield::IsActive) - // Core Methods - .Func(_SC("Bind"), &CForcefield::BindEvent) - // Core Overloads - .Overload< bool (CForcefield::*)(void) >(_SC("Destroy"), &CForcefield::Destroy) - .Overload< bool (CForcefield::*)(Int32) >(_SC("Destroy"), &CForcefield::Destroy) - .Overload< bool (CForcefield::*)(Int32, Object &) >(_SC("Destroy"), &CForcefield::Destroy) - // Properties - .Prop(_SC("World"), &CForcefield::GetWorld, &CForcefield::SetWorld) - .Prop(_SC("Color"), &CForcefield::GetColor, &CForcefield::SetColor) - .Prop(_SC("Pos"), &CForcefield::GetPosition, &CForcefield::SetPosition) - .Prop(_SC("Position"), &CForcefield::GetPosition, &CForcefield::SetPosition) - .Prop(_SC("Radius"), &CForcefield::GetRadius, &CForcefield::SetRadius) - .Prop(_SC("Owner"), &CForcefield::GetOwner) - .Prop(_SC("OwnerID"), &CForcefield::GetOwnerID) - .Prop(_SC("X"), &CForcefield::GetPosX, &CForcefield::SetPosX) - .Prop(_SC("Y"), &CForcefield::GetPosY, &CForcefield::SetPosY) - .Prop(_SC("Z"), &CForcefield::GetPosZ, &CForcefield::SetPosZ) - .Prop(_SC("R"), &CForcefield::GetColR, &CForcefield::SetColR) - .Prop(_SC("G"), &CForcefield::GetColG, &CForcefield::SetColG) - .Prop(_SC("B"), &CForcefield::GetColB, &CForcefield::SetColB) - // Member Methods - .Func(_SC("StreamedFor"), &CForcefield::IsStreamedFor) - .Func(_SC("SetColor"), &CForcefield::SetColorEx) - .Func(_SC("SetPos"), &CForcefield::SetPositionEx) - .Func(_SC("SetPosition"), &CForcefield::SetPositionEx) - // Static Functions - .StaticFunc(_SC("FindByID"), &Forcefield_FindByID) - .StaticFunc(_SC("FindByTag"), &Forcefield_FindByTag) - .StaticFunc(_SC("FindActive"), &Forcefield_FindActive) - // Static Overloads - .StaticOverload< Object & (*)(CPlayer &, Int32, Float32, Float32, Float32, Uint8, Uint8, Uint8, Float32) > - (_SC("CreateEx"), &Forcefield_CreateEx) - .StaticOverload< Object & (*)(CPlayer &, Int32, Float32, Float32, Float32, Uint8, Uint8, Uint8, Float32, Int32, Object &) > - (_SC("CreateEx"), &Forcefield_CreateEx) - .StaticOverload< Object & (*)(CPlayer &, Int32, const Vector3 &, const Color3 &, Float32) > - (_SC("Create"), &Forcefield_Create) - .StaticOverload< Object & (*)(CPlayer &, Int32, const Vector3 &, const Color3 &, Float32, Int32, Object &) > - (_SC("Create"), &Forcefield_Create) - ); -} - -} // Namespace:: SqMod diff --git a/source/Entity/Forcefield.hpp b/source/Entity/Forcefield.hpp deleted file mode 100644 index 285e643a..00000000 --- a/source/Entity/Forcefield.hpp +++ /dev/null @@ -1,295 +0,0 @@ -#ifndef _ENTITY_FORCEFIELD_HPP_ -#define _ENTITY_FORCEFIELD_HPP_ - -// ------------------------------------------------------------------------------------------------ -#include "Base/Shared.hpp" - -// ------------------------------------------------------------------------------------------------ -namespace SqMod { - -/* ------------------------------------------------------------------------------------------------ - * Manages a single forcefield entity. -*/ -class CForcefield -{ - // -------------------------------------------------------------------------------------------- - friend class Core; - -private: - - // -------------------------------------------------------------------------------------------- - static Color3 s_Color3; - static Vector3 s_Vector3; - - // -------------------------------------------------------------------------------------------- - static Uint32 s_ColorR, s_ColorG, s_ColorB; - - /* -------------------------------------------------------------------------------------------- - * Identifier of the managed entity. - */ - Int32 m_ID; - - /* -------------------------------------------------------------------------------------------- - * User tag associated with this instance. - */ - String m_Tag; - - /* -------------------------------------------------------------------------------------------- - * User data associated with this instance. - */ - Object m_Data; - - /* -------------------------------------------------------------------------------------------- - * Base constructor. - */ - CForcefield(Int32 id); - -public: - - /* -------------------------------------------------------------------------------------------- - * Maximum possible number that could represent an identifier for this entity type. - */ - static const Int32 Max; - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. (disabled) - */ - CForcefield(const CForcefield &) = delete; - - /* -------------------------------------------------------------------------------------------- - * Move constructor. (disabled) - */ - CForcefield(CForcefield &&) = delete; - - /* -------------------------------------------------------------------------------------------- - * Destructor. - */ - ~CForcefield(); - - /* -------------------------------------------------------------------------------------------- - * Copy assignment operator. (disabled) - */ - CForcefield & operator = (const CForcefield &) = delete; - - /* -------------------------------------------------------------------------------------------- - * Move assignment operator. (disabled) - */ - CForcefield & operator = (CForcefield &&) = delete; - - /* -------------------------------------------------------------------------------------------- - * See whether this instance manages a valid entity otherwise throw an exception. - */ - void Validate() const - { - if (INVALID_ENTITY(m_ID)) - { - STHROWF("Invalid forcefield reference [%s]", m_Tag.c_str()); - } - } - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to compare two instances of this type. - */ - Int32 Cmp(const CForcefield & o) const; - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to convert an instance of this type to a string. - */ - const String & ToString() const; - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to retrieve the name from instances of this type. - */ - static SQInteger Typename(HSQUIRRELVM vm); - - /* -------------------------------------------------------------------------------------------- - * Retrieve the identifier of the entity managed by this instance. - */ - Int32 GetID() const - { - return m_ID; - } - - /* -------------------------------------------------------------------------------------------- - * Check whether this instance manages a valid entity. - */ - bool IsActive() const - { - return VALID_ENTITY(m_ID); - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated user tag. - */ - const String & GetTag() const; - - /* -------------------------------------------------------------------------------------------- - * Modify the associated user tag. - */ - void SetTag(CSStr tag); - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated user data. - */ - Object & GetData(); - - /* -------------------------------------------------------------------------------------------- - * Modify the associated user data. - */ - void SetData(Object & data); - - /* -------------------------------------------------------------------------------------------- - * Destroy the managed forcefield entity. - */ - bool Destroy() - { - return Destroy(0, NullObject()); - } - - /* -------------------------------------------------------------------------------------------- - * Destroy the managed forcefield entity. - */ - bool Destroy(Int32 header) - { - return Destroy(header, NullObject()); - } - - /* -------------------------------------------------------------------------------------------- - * Destroy the managed forcefield entity. - */ - bool Destroy(Int32 header, Object & payload); - - /* -------------------------------------------------------------------------------------------- - * Bind to an event supported by this entity type. - */ - void BindEvent(Int32 evid, Object & env, Function & func) const; - - /* -------------------------------------------------------------------------------------------- - * See if the managed forcefield entity is streamed for the specified player. - */ - bool IsStreamedFor(CPlayer & player) const; - - /* -------------------------------------------------------------------------------------------- - * Retrieve the world in which the managed forcefield entity exists. - */ - Int32 GetWorld() const; - - /* -------------------------------------------------------------------------------------------- - * Modify the world in which the managed forcefield entity exists. - */ - void SetWorld(Int32 world) const; - - /* -------------------------------------------------------------------------------------------- - * Retrieve the color of the managed forcefield entity. - */ - const Color3 & GetColor() const; - - /* -------------------------------------------------------------------------------------------- - * Modify the color of the managed forcefield entity. - */ - void SetColor(const Color3 & col) const; - - /* -------------------------------------------------------------------------------------------- - * Modify the color of the managed forcefield entity. - */ - void SetColorEx(Uint8 r, Uint8 g, Uint8 b) const; - - /* -------------------------------------------------------------------------------------------- - * Retrieve the position of the managed forcefield entity. - */ - const Vector3 & GetPosition() const; - - /* -------------------------------------------------------------------------------------------- - * Modify the position of the managed forcefield entity. - */ - void SetPosition(const Vector3 & pos) const; - - /* -------------------------------------------------------------------------------------------- - * Modify the position of the managed forcefield entity. - */ - void SetPositionEx(Float32 x, Float32 y, Float32 z) const; - - /* -------------------------------------------------------------------------------------------- - * Retrieve the radius of the managed forcefield entity. - */ - Float32 GetRadius() const; - - /* -------------------------------------------------------------------------------------------- - * Modify the radius of the managed forcefield entity. - */ - void SetRadius(Float32 radius) const; - - /* -------------------------------------------------------------------------------------------- - * Retrieve the owner of the managed forcefield entity. - */ - Object & GetOwner() const; - - /* -------------------------------------------------------------------------------------------- - * Retrieve the owner identifier of the managed forcefield entity. - */ - Int32 GetOwnerID() const; - - /* -------------------------------------------------------------------------------------------- - * Retrieve the position on the x axis of the managed forcefield entity. - */ - Float32 GetPosX() const; - - /* -------------------------------------------------------------------------------------------- - * Retrieve the position on the y axis of the managed forcefield entity. - */ - Float32 GetPosY() const; - - /* -------------------------------------------------------------------------------------------- - * Retrieve the position on the z axis of the managed forcefield entity. - */ - Float32 GetPosZ() const; - - /* -------------------------------------------------------------------------------------------- - * Modify the position on the x axis of the managed forcefield entity. - */ - void SetPosX(Float32 x) const; - - /* -------------------------------------------------------------------------------------------- - * Modify the position on the y axis of the managed forcefield entity. - */ - void SetPosY(Float32 y) const; - - /* -------------------------------------------------------------------------------------------- - * Modify the position on the z axis of the managed forcefield entity. - */ - void SetPosZ(Float32 z) const; - - /* -------------------------------------------------------------------------------------------- - * Retrieve the red color of the managed forcefield entity. - */ - Uint32 GetColR() const; - - /* -------------------------------------------------------------------------------------------- - * Retrieve the green color of the managed forcefield entity. - */ - Uint32 GetColG() const; - - /* -------------------------------------------------------------------------------------------- - * Retrieve the blue color of the managed forcefield entity. - */ - Uint32 GetColB() const; - - /* -------------------------------------------------------------------------------------------- - * Modify the red color of the managed forcefield entity. - */ - void SetColR(Uint32 r) const; - - /* -------------------------------------------------------------------------------------------- - * Modify the green color of the managed forcefield entity. - */ - void SetColG(Uint32 g) const; - - /* -------------------------------------------------------------------------------------------- - * Modify the blue color of the managed forcefield entity. - */ - void SetColB(Uint32 b) const; -}; - -} // Namespace:: SqMod - -#endif // _ENTITY_FORCEFIELD_HPP_ \ No newline at end of file diff --git a/source/Entity/Keybind.cpp b/source/Entity/Keybind.cpp index 208e79e7..92cdaab2 100644 --- a/source/Entity/Keybind.cpp +++ b/source/Entity/Keybind.cpp @@ -12,7 +12,7 @@ const Int32 CKeybind::Max = SQMOD_KEYBIND_POOL; // ------------------------------------------------------------------------------------------------ SQInteger CKeybind::Typename(HSQUIRRELVM vm) { - static SQChar name[] = _SC("SqKeybind"); + static const SQChar name[] = _SC("SqKeybind"); sq_pushstring(vm, name, sizeof(name)); return 1; } @@ -35,11 +35,17 @@ CKeybind::~CKeybind() Int32 CKeybind::Cmp(const CKeybind & o) const { if (m_ID == o.m_ID) + { return 0; + } else if (m_ID > o.m_ID) + { return 1; + } else + { return -1; + } } // ------------------------------------------------------------------------------------------------ @@ -84,7 +90,7 @@ bool CKeybind::Destroy(Int32 header, Object & payload) // Validate the managed identifier Validate(); // Perform the requested operation - return _Core->DelKeybind(m_ID, header, payload); + return Core::Get().DelKeybind(m_ID, header, payload); } // ------------------------------------------------------------------------------------------------ @@ -93,7 +99,7 @@ void CKeybind::BindEvent(Int32 evid, Object & env, Function & func) const // Validate the managed identifier Validate(); // Obtain the function instance called for this event - Function & event = _Core->GetKeybindEvent(m_ID, evid); + Function & event = Core::Get().GetKeybindEvent(m_ID, evid); // Is the specified callback function null? if (func.IsNull()) { @@ -112,7 +118,7 @@ Int32 CKeybind::GetFirst() const // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetKeybind(m_ID).mFirst; + return Core::Get().GetKeybind(m_ID).mFirst; } // ------------------------------------------------------------------------------------------------ @@ -121,7 +127,7 @@ Int32 CKeybind::GetSecond() const // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetKeybind(m_ID).mSecond; + return Core::Get().GetKeybind(m_ID).mSecond; } // ------------------------------------------------------------------------------------------------ @@ -130,7 +136,7 @@ Int32 CKeybind::GetThird() const // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetKeybind(m_ID).mThird; + return Core::Get().GetKeybind(m_ID).mThird; } // ------------------------------------------------------------------------------------------------ @@ -139,34 +145,34 @@ bool CKeybind::IsRelease() const // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetKeybind(m_ID).mRelease; + return Core::Get().GetKeybind(m_ID).mRelease; } // ------------------------------------------------------------------------------------------------ static Object & Keybind_CreateEx(Int32 slot, bool release, Int32 primary, Int32 secondary, Int32 alternative) { - return _Core->NewKeybind(slot, release, primary, secondary, alternative, + return Core::Get().NewKeybind(slot, release, primary, secondary, alternative, SQMOD_CREATE_DEFAULT, NullObject()); } static Object & Keybind_CreateEx(Int32 slot, bool release, Int32 primary, Int32 secondary, Int32 alternative, Int32 header, Object & payload) { - return _Core->NewKeybind(slot, release, primary, secondary, alternative, header, payload); + return Core::Get().NewKeybind(slot, release, primary, secondary, alternative, header, payload); } // ------------------------------------------------------------------------------------------------ static Object & Keybind_Create(bool release, Int32 primary, Int32 secondary, Int32 alternative) { - return _Core->NewKeybind(-1, release, primary, secondary, alternative, + return Core::Get().NewKeybind(-1, release, primary, secondary, alternative, SQMOD_CREATE_DEFAULT, NullObject()); } static Object & Keybind_Create(bool release, Int32 primary, Int32 secondary, Int32 alternative, Int32 header, Object & payload) { - return _Core->NewKeybind(-1, release, primary, secondary, alternative, header, payload); + return Core::Get().NewKeybind(-1, release, primary, secondary, alternative, header, payload); } // ------------------------------------------------------------------------------------------------ @@ -178,8 +184,8 @@ static const Object & Keybind_FindByID(Int32 id) STHROWF("The specified keybind identifier is invalid: %d", id); } // Obtain the ends of the entity pool - Core::Keybinds::const_iterator itr = _Core->GetKeybinds().cbegin(); - Core::Keybinds::const_iterator end = _Core->GetKeybinds().cend(); + Core::Keybinds::const_iterator itr = Core::Get().GetKeybinds().cbegin(); + Core::Keybinds::const_iterator end = Core::Get().GetKeybinds().cend(); // Process each entity in the pool for (; itr != end; ++itr) { @@ -202,8 +208,8 @@ static const Object & Keybind_FindByTag(CSStr tag) STHROWF("The specified keybind tag is invalid: null/empty"); } // Obtain the ends of the entity pool - Core::Keybinds::const_iterator itr = _Core->GetKeybinds().cbegin(); - Core::Keybinds::const_iterator end = _Core->GetKeybinds().cend(); + Core::Keybinds::const_iterator itr = Core::Get().GetKeybinds().cbegin(); + Core::Keybinds::const_iterator end = Core::Get().GetKeybinds().cend(); // Process each entity in the pool for (; itr != end; ++itr) { @@ -223,8 +229,8 @@ static Array Keybind_FindActive() // Remember the initial stack size StackGuard sg; // Obtain the ends of the entity pool - Core::Keybinds::const_iterator itr = _Core->GetKeybinds().cbegin(); - Core::Keybinds::const_iterator end = _Core->GetKeybinds().cend(); + Core::Keybinds::const_iterator itr = Core::Get().GetKeybinds().cbegin(); + Core::Keybinds::const_iterator end = Core::Get().GetKeybinds().cend(); // Allocate an empty array on the stack sq_newarray(DefaultVM::Get(), 0); // Process each entity in the pool diff --git a/source/Entity/Object.cpp b/source/Entity/Object.cpp index 4c430b0b..ce5bcf44 100644 --- a/source/Entity/Object.cpp +++ b/source/Entity/Object.cpp @@ -19,7 +19,7 @@ const Int32 CObject::Max = SQMOD_OBJECT_POOL; // ------------------------------------------------------------------------------------------------ SQInteger CObject::Typename(HSQUIRRELVM vm) { - static SQChar name[] = _SC("SqObject"); + static const SQChar name[] = _SC("SqObject"); sq_pushstring(vm, name, sizeof(name)); return 1; } @@ -27,7 +27,13 @@ SQInteger CObject::Typename(HSQUIRRELVM vm) // ------------------------------------------------------------------------------------------------ CObject::CObject(Int32 id) : m_ID(VALID_ENTITYGETEX(id, SQMOD_OBJECT_POOL)) - , m_Tag(ToStrF("%d", id)) + , m_Tag(ToStrF("%d", id)), m_Data() + , mMoveToDuration(0) + , mMoveByDuration(0) + , mRotateToDuration(0) + , mRotateByDuration(0) + , mRotateToEulerDuration(0) + , mRotateByEulerDuration(0) { /* ... */ } @@ -42,11 +48,17 @@ CObject::~CObject() Int32 CObject::Cmp(const CObject & o) const { if (m_ID == o.m_ID) + { return 0; + } else if (m_ID > o.m_ID) + { return 1; + } else + { return -1; + } } // ------------------------------------------------------------------------------------------------ @@ -91,7 +103,7 @@ bool CObject::Destroy(Int32 header, Object & payload) // Validate the managed identifier Validate(); // Perform the requested operation - return _Core->DelObject(m_ID, header, payload); + return Core::Get().DelObject(m_ID, header, payload); } // ------------------------------------------------------------------------------------------------ @@ -100,7 +112,7 @@ void CObject::BindEvent(Int32 evid, Object & env, Function & func) const // Validate the managed identifier Validate(); // Obtain the function instance called for this event - Function & event = _Core->GetObjectEvent(m_ID, evid); + Function & event = Core::Get().GetObjectEvent(m_ID, evid); // Is the specified callback function null? if (func.IsNull()) { @@ -173,7 +185,7 @@ void CObject::SetAlpha(Int32 alpha) const } // ------------------------------------------------------------------------------------------------ -void CObject::SetAlphaEx(Int32 alpha, Int32 time) const +void CObject::SetAlphaEx(Int32 alpha, Uint32 time) const { // Validate the managed identifier Validate(); @@ -182,7 +194,7 @@ void CObject::SetAlphaEx(Int32 alpha, Int32 time) const } // ------------------------------------------------------------------------------------------------ -void CObject::MoveTo(const Vector3 & pos, Int32 time) const +void CObject::MoveTo(const Vector3 & pos, Uint32 time) const { // Validate the managed identifier Validate(); @@ -191,7 +203,7 @@ void CObject::MoveTo(const Vector3 & pos, Int32 time) const } // ------------------------------------------------------------------------------------------------ -void CObject::MoveToEx(Float32 x, Float32 y, Float32 z, Int32 time) const +void CObject::MoveToEx(Float32 x, Float32 y, Float32 z, Uint32 time) const { // Validate the managed identifier Validate(); @@ -200,7 +212,7 @@ void CObject::MoveToEx(Float32 x, Float32 y, Float32 z, Int32 time) const } // ------------------------------------------------------------------------------------------------ -void CObject::MoveBy(const Vector3 & pos, Int32 time) const +void CObject::MoveBy(const Vector3 & pos, Uint32 time) const { // Validate the managed identifier Validate(); @@ -209,7 +221,7 @@ void CObject::MoveBy(const Vector3 & pos, Int32 time) const } // ------------------------------------------------------------------------------------------------ -void CObject::MoveByEx(Float32 x, Float32 y, Float32 z, Int32 time) const +void CObject::MoveByEx(Float32 x, Float32 y, Float32 z, Uint32 time) const { // Validate the managed identifier Validate(); @@ -222,10 +234,10 @@ const Vector3 & CObject::GetPosition() { // Validate the managed identifier Validate(); - // Clear previous position information + // Clear previous information, if any s_Vector3.Clear(); - // Query the server for the position values - _Func->GetObjectPos(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); + // Query the server for the values + _Func->GetObjectPosition(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); // Return the requested information return s_Vector3; } @@ -236,7 +248,7 @@ void CObject::SetPosition(const Vector3 & pos) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetObjectPos(m_ID, pos.x, pos.y, pos.z); + _Func->SetObjectPosition(m_ID, pos.x, pos.y, pos.z); } // ------------------------------------------------------------------------------------------------ @@ -245,79 +257,79 @@ void CObject::SetPositionEx(Float32 x, Float32 y, Float32 z) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetObjectPos(m_ID, x, y, z); + _Func->SetObjectPosition(m_ID, x, y, z); } // ------------------------------------------------------------------------------------------------ -void CObject::RotateTo(const Quaternion & rot, Int32 time) const +void CObject::RotateTo(const Quaternion & rot, Uint32 time) const { // Validate the managed identifier Validate(); // Perform the requested operation - _Func->RotObjectTo(m_ID, rot.x, rot.y, rot.z, rot.w, time); + _Func->RotateObjectTo(m_ID, rot.x, rot.y, rot.z, rot.w, time); } // ------------------------------------------------------------------------------------------------ -void CObject::RotateToEx(Float32 x, Float32 y, Float32 z, Float32 w, Int32 time) const +void CObject::RotateToEx(Float32 x, Float32 y, Float32 z, Float32 w, Uint32 time) const { // Validate the managed identifier Validate(); // Perform the requested operation - _Func->RotObjectTo(m_ID, x, y, z, w, time); + _Func->RotateObjectTo(m_ID, x, y, z, w, time); } // ------------------------------------------------------------------------------------------------ -void CObject::RotateToEuler(const Vector3 & rot, Int32 time) const +void CObject::RotateToEuler(const Vector3 & rot, Uint32 time) const { // Validate the managed identifier Validate(); // Perform the requested operation - _Func->RotObjectToEuler(m_ID, rot.x, rot.y, rot.z, time); + _Func->RotateObjectToEuler(m_ID, rot.x, rot.y, rot.z, time); } // ------------------------------------------------------------------------------------------------ -void CObject::RotateToEulerEx(Float32 x, Float32 y, Float32 z, Int32 time) const +void CObject::RotateToEulerEx(Float32 x, Float32 y, Float32 z, Uint32 time) const { // Validate the managed identifier Validate(); // Perform the requested operation - _Func->RotObjectToEuler(m_ID, x, y, z, time); + _Func->RotateObjectToEuler(m_ID, x, y, z, time); } // ------------------------------------------------------------------------------------------------ -void CObject::RotateBy(const Quaternion & rot, Int32 time) const +void CObject::RotateBy(const Quaternion & rot, Uint32 time) const { // Validate the managed identifier Validate(); // Perform the requested operation - _Func->RotObjectBy(m_ID, rot.x, rot.y, rot.z, rot.w, time); + _Func->RotateObjectBy(m_ID, rot.x, rot.y, rot.z, rot.w, time); } // ------------------------------------------------------------------------------------------------ -void CObject::RotateByEx(Float32 x, Float32 y, Float32 z, Float32 w, Int32 time) const +void CObject::RotateByEx(Float32 x, Float32 y, Float32 z, Float32 w, Uint32 time) const { // Validate the managed identifier Validate(); // Perform the requested operation - _Func->RotObjectBy(m_ID, x, y, z, w, time); + _Func->RotateObjectBy(m_ID, x, y, z, w, time); } // ------------------------------------------------------------------------------------------------ -void CObject::RotateByEuler(const Vector3 & rot, Int32 time) const +void CObject::RotateByEuler(const Vector3 & rot, Uint32 time) const { // Validate the managed identifier Validate(); // Perform the requested operation - _Func->RotObjectByEuler(m_ID, rot.x, rot.y, rot.z, time); + _Func->RotateObjectByEuler(m_ID, rot.x, rot.y, rot.z, time); } // ------------------------------------------------------------------------------------------------ -void CObject::RotateByEulerEx(Float32 x, Float32 y, Float32 z, Int32 time) const +void CObject::RotateByEulerEx(Float32 x, Float32 y, Float32 z, Uint32 time) const { // Validate the managed identifier Validate(); // Perform the requested operation - _Func->RotObjectByEuler(m_ID, x, y, z, time); + _Func->RotateObjectByEuler(m_ID, x, y, z, time); } // ------------------------------------------------------------------------------------------------ @@ -325,10 +337,10 @@ const Quaternion & CObject::GetRotation() { // Validate the managed identifier Validate(); - // Clear previous rotation information + // Clear previous information, if any s_Quaternion.Clear(); - // Query the server for the rotation values - _Func->GetObjectRot(m_ID, &s_Quaternion.x, &s_Quaternion.y, &s_Quaternion.z, &s_Quaternion.w); + // Query the server for the values + _Func->GetObjectRotation(m_ID, &s_Quaternion.x, &s_Quaternion.y, &s_Quaternion.z, &s_Quaternion.w); // Return the requested information return s_Quaternion; } @@ -338,10 +350,10 @@ const Vector3 & CObject::GetRotationEuler() { // Validate the managed identifier Validate(); - // Clear previous rotation information + // Clear previous information, if any s_Vector3.Clear(); - // Query the server for the rotation values - _Func->GetObjectRotEuler(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); + // Query the server for the values + _Func->GetObjectRotationEuler(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); // Return the requested information return s_Vector3; } @@ -352,7 +364,7 @@ bool CObject::GetShotReport() const // Validate the managed identifier Validate(); // Return the requested information - return _Func->IsObjectShotReport(m_ID); + return _Func->IsObjectShotReportEnabled(m_ID); } // ------------------------------------------------------------------------------------------------ @@ -361,214 +373,434 @@ void CObject::SetShotReport(bool toggle) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetObjectShotReport(m_ID, toggle); + _Func->SetObjectShotReportEnabled(m_ID, toggle); } // ------------------------------------------------------------------------------------------------ -bool CObject::GetBumpReport() const +bool CObject::GetTouchedReport() const { // Validate the managed identifier Validate(); // Return the requested information - return _Func->IsObjectBumpReport(m_ID); + return _Func->IsObjectTouchedReportEnabled(m_ID); } // ------------------------------------------------------------------------------------------------ -void CObject::SetBumpReport(bool toggle) const +void CObject::SetTouchedReport(bool toggle) const { // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetObjectBumpReport(m_ID, toggle); + _Func->SetObjectTouchedReportEnabled(m_ID, toggle); } // ------------------------------------------------------------------------------------------------ -Float32 CObject::GetPosX() const +Float32 CObject::GetPositionX() const { // Validate the managed identifier Validate(); - // Clear previous position information, if any - s_Vector3.x = 0; + // Clear previous information, if any + s_Vector3.x = 0.0f; // Query the server for the requested component value - _Func->GetObjectPos(m_ID, &s_Vector3.x, NULL, NULL); + _Func->GetObjectPosition(m_ID, &s_Vector3.x, nullptr, nullptr); // Return the requested information return s_Vector3.x; } // ------------------------------------------------------------------------------------------------ -Float32 CObject::GetPosY() const +Float32 CObject::GetPositionY() const { // Validate the managed identifier Validate(); - // Clear previous position information, if any - s_Vector3.y = 0; + // Clear previous information, if any + s_Vector3.y = 0.0f; // Query the server for the requested component value - _Func->GetObjectPos(m_ID, NULL, &s_Vector3.y, NULL); + _Func->GetObjectPosition(m_ID, nullptr, &s_Vector3.y, nullptr); // Return the requested information return s_Vector3.y; } // ------------------------------------------------------------------------------------------------ -Float32 CObject::GetPosZ() const +Float32 CObject::GetPositionZ() const { // Validate the managed identifier Validate(); - // Clear previous position information, if any - s_Vector3.z = 0; + // Clear previous information, if any + s_Vector3.z = 0.0f; // Query the server for the requested component value - _Func->GetObjectPos(m_ID, NULL, NULL, &s_Vector3.z); + _Func->GetObjectPosition(m_ID, nullptr, nullptr, &s_Vector3.z); // Return the requested information return s_Vector3.z; } // ------------------------------------------------------------------------------------------------ -void CObject::SetPosX(Float32 x) const +void CObject::SetPositionX(Float32 x) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetObjectPos(m_ID, NULL, &s_Vector3.y, &s_Vector3.z); + _Func->GetObjectPosition(m_ID, nullptr, &s_Vector3.y, &s_Vector3.z); // Perform the requested operation - _Func->SetObjectPos(m_ID, x, s_Vector3.y, s_Vector3.z); + _Func->SetObjectPosition(m_ID, x, s_Vector3.y, s_Vector3.z); } // ------------------------------------------------------------------------------------------------ -void CObject::SetPosY(Float32 y) const +void CObject::SetPositionY(Float32 y) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetObjectPos(m_ID, &s_Vector3.x, NULL, &s_Vector3.z); + _Func->GetObjectPosition(m_ID, &s_Vector3.x, nullptr, &s_Vector3.z); // Perform the requested operation - _Func->SetObjectPos(m_ID, s_Vector3.x, y, s_Vector3.z); + _Func->SetObjectPosition(m_ID, s_Vector3.x, y, s_Vector3.z); } // ------------------------------------------------------------------------------------------------ -void CObject::SetPosZ(Float32 z) const +void CObject::SetPositionZ(Float32 z) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetObjectPos(m_ID, &s_Vector3.x, &s_Vector3.y, NULL); + _Func->GetObjectPosition(m_ID, &s_Vector3.x, &s_Vector3.y, nullptr); // Perform the requested operation - _Func->SetObjectPos(m_ID, s_Vector3.z, s_Vector3.y, z); + _Func->SetObjectPosition(m_ID, s_Vector3.z, s_Vector3.y, z); } // ------------------------------------------------------------------------------------------------ -Float32 CObject::GetRotX() const +Float32 CObject::GetRotationX() const { // Validate the managed identifier Validate(); - // Clear previous rotation information, if any - s_Quaternion.x = 0; + // Clear previous information, if any + s_Quaternion.x = 0.0f; // Query the server for the requested component value - _Func->GetObjectRot(m_ID, &s_Quaternion.x, NULL, NULL, NULL); + _Func->GetObjectRotation(m_ID, &s_Quaternion.x, nullptr, nullptr, nullptr); // Return the requested information return s_Quaternion.x; } // ------------------------------------------------------------------------------------------------ -Float32 CObject::GetRotY() const +Float32 CObject::GetRotationY() const { // Validate the managed identifier Validate(); - // Clear previous rotation information, if any - s_Quaternion.y = 0; + // Clear previous information, if any + s_Quaternion.y = 0.0f; // Query the server for the requested component value - _Func->GetObjectRot(m_ID, NULL, &s_Quaternion.y, NULL, NULL); + _Func->GetObjectRotation(m_ID, nullptr, &s_Quaternion.y, nullptr, nullptr); // Return the requested information return s_Quaternion.y; } // ------------------------------------------------------------------------------------------------ -Float32 CObject::GetRotZ() const +Float32 CObject::GetRotationZ() const { // Validate the managed identifier Validate(); - // Clear previous rotation information, if any - s_Quaternion.z = 0; + // Clear previous information, if any + s_Quaternion.z = 0.0f; // Query the server for the requested component value - _Func->GetObjectRot(m_ID, NULL, NULL, &s_Quaternion.z, NULL); + _Func->GetObjectRotation(m_ID, nullptr, nullptr, &s_Quaternion.z, nullptr); // Return the requested information return s_Quaternion.z; } // ------------------------------------------------------------------------------------------------ -Float32 CObject::GetRotW() const +Float32 CObject::GetRotationW() const { // Validate the managed identifier Validate(); - // Clear previous rotation information, if any - s_Quaternion.w = 0; + // Clear previous information, if any + s_Quaternion.w = 0.0f; // Query the server for the requested component value - _Func->GetObjectRot(m_ID, NULL, NULL, NULL, &s_Quaternion.w); + _Func->GetObjectRotation(m_ID, nullptr, nullptr, nullptr, &s_Quaternion.w); // Return the requested information return s_Quaternion.w; } // ------------------------------------------------------------------------------------------------ -Float32 CObject::GetERotX() const +Float32 CObject::GetEulerRotationX() const { // Validate the managed identifier Validate(); - // Clear previous rotation information, if any - s_Vector3.x = 0; + // Clear previous information, if any + s_Vector3.x = 0.0f; // Query the server for the requested component value - _Func->GetObjectRotEuler(m_ID, &s_Vector3.x, NULL, NULL); + _Func->GetObjectRotationEuler(m_ID, &s_Vector3.x, nullptr, nullptr); // Return the requested information return s_Vector3.x; } // ------------------------------------------------------------------------------------------------ -Float32 CObject::GetERotY() const +Float32 CObject::GetEulerRotationY() const { // Validate the managed identifier Validate(); - // Clear previous rotation information, if any - s_Vector3.y = 0; + // Clear previous information, if any + s_Vector3.y = 0.0f; // Query the server for the requested component value - _Func->GetObjectRotEuler(m_ID, NULL, &s_Vector3.y, NULL); + _Func->GetObjectRotationEuler(m_ID, nullptr, &s_Vector3.y, nullptr); // Return the requested information return s_Vector3.y; } // ------------------------------------------------------------------------------------------------ -Float32 CObject::GetERotZ() const +Float32 CObject::GetEulerRotationZ() const { // Validate the managed identifier Validate(); - // Clear previous rotation information, if any - s_Vector3.z = 0; + // Clear previous information, if any + s_Vector3.z = 0.0f; // Query the server for the requested component value - _Func->GetObjectRotEuler(m_ID, NULL, NULL, &s_Vector3.z); + _Func->GetObjectRotationEuler(m_ID, nullptr, nullptr, &s_Vector3.z); // Return the requested information return s_Vector3.z; } +// ------------------------------------------------------------------------------------------------ +void CObject::MoveToX(Float32 x) const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Vector3.Clear(); + // Retrieve the current values for unchanged components + _Func->GetObjectPosition(m_ID, nullptr, &s_Vector3.y, &s_Vector3.z); + // Perform the requested operation + _Func->MoveObjectTo(m_ID, x, s_Vector3.y, s_Vector3.z, mMoveToDuration); +} + +// ------------------------------------------------------------------------------------------------ +void CObject::MoveToY(Float32 y) const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Vector3.Clear(); + // Retrieve the current values for unchanged components + _Func->GetObjectPosition(m_ID, &s_Vector3.x, nullptr, &s_Vector3.z); + // Perform the requested operation + _Func->MoveObjectTo(m_ID, s_Vector3.x, y, s_Vector3.z, mMoveToDuration); +} + +// ------------------------------------------------------------------------------------------------ +void CObject::MoveToZ(Float32 z) const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Vector3.Clear(); + // Retrieve the current values for unchanged components + _Func->GetObjectPosition(m_ID, &s_Vector3.x, &s_Vector3.y, nullptr); + // Perform the requested operation + _Func->MoveObjectTo(m_ID, s_Vector3.z, s_Vector3.y, z, mMoveToDuration); +} + +// ------------------------------------------------------------------------------------------------ +void CObject::MoveByX(Float32 x) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->MoveObjectBy(m_ID, x, 0.0f, 0.0f, mMoveByDuration); +} + +// ------------------------------------------------------------------------------------------------ +void CObject::MoveByY(Float32 y) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->MoveObjectBy(m_ID, 0.0f, y, 0.0f, mMoveByDuration); +} + +// ------------------------------------------------------------------------------------------------ +void CObject::MoveByZ(Float32 z) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->MoveObjectBy(m_ID, 0.0f, 0.0f, z, mMoveByDuration); +} + +// ------------------------------------------------------------------------------------------------ +void CObject::RotateToX(Float32 x) const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Quaternion.Clear(); + // Retrieve the current values for unchanged components + _Func->GetObjectRotation(m_ID, nullptr, &s_Quaternion.y, &s_Quaternion.z, &s_Quaternion.w); + // Perform the requested operation + _Func->RotateObjectTo(m_ID, x, s_Quaternion.y, s_Quaternion.z, s_Quaternion.w, mRotateToDuration); +} + +// ------------------------------------------------------------------------------------------------ +void CObject::RotateToY(Float32 y) const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Quaternion.Clear(); + // Retrieve the current values for unchanged components + _Func->GetObjectRotation(m_ID, &s_Quaternion.x, nullptr, &s_Quaternion.z, &s_Quaternion.w); + // Perform the requested operation + _Func->RotateObjectTo(m_ID, s_Quaternion.x, y, s_Quaternion.z, s_Quaternion.w, mRotateToDuration); +} + +// ------------------------------------------------------------------------------------------------ +void CObject::RotateToZ(Float32 z) const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Quaternion.Clear(); + // Retrieve the current values for unchanged components + _Func->GetObjectRotation(m_ID, &s_Quaternion.x, &s_Quaternion.y, nullptr, &s_Quaternion.w); + // Perform the requested operation + _Func->RotateObjectTo(m_ID, s_Quaternion.x, s_Quaternion.y, z, s_Quaternion.w, mRotateToDuration); +} + +// ------------------------------------------------------------------------------------------------ +void CObject::RotateToW(Float32 w) const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Quaternion.Clear(); + // Retrieve the current values for unchanged components + _Func->GetObjectRotation(m_ID, &s_Quaternion.x, &s_Quaternion.y, &s_Quaternion.z, nullptr); + // Perform the requested operation + _Func->RotateObjectTo(m_ID, s_Quaternion.x, s_Quaternion.y, s_Quaternion.z, w, mRotateToDuration); +} + +// ------------------------------------------------------------------------------------------------ +void CObject::RotateByX(Float32 x) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->RotateObjectBy(m_ID, x, 0.0f, 0.0f, 0.0f, mRotateByDuration); +} + +// ------------------------------------------------------------------------------------------------ +void CObject::RotateByY(Float32 y) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->RotateObjectBy(m_ID, 0.0f, y, 0.0f, 0.0f, mRotateByDuration); +} + +// ------------------------------------------------------------------------------------------------ +void CObject::RotateByZ(Float32 z) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->RotateObjectBy(m_ID, 0.0f, 0.0f, z, 0.0f, mRotateByDuration); +} + +// ------------------------------------------------------------------------------------------------ +void CObject::RotateByW(Float32 w) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->RotateObjectBy(m_ID, 0.0f, 0.0f, 0.0f, w, mRotateByDuration); +} + +// ------------------------------------------------------------------------------------------------ +void CObject::RotateToEulerX(Float32 x) const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Vector3.Clear(); + // Retrieve the current values for unchanged components + _Func->GetObjectRotationEuler(m_ID, nullptr, &s_Vector3.y, &s_Vector3.z); + // Perform the requested operation + _Func->RotateObjectToEuler(m_ID, x, s_Vector3.y, s_Vector3.z, mRotateToEulerDuration); +} + +// ------------------------------------------------------------------------------------------------ +void CObject::RotateToEulerY(Float32 y) const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Vector3.Clear(); + // Retrieve the current values for unchanged components + _Func->GetObjectRotationEuler(m_ID, &s_Vector3.x, nullptr, &s_Vector3.z); + // Perform the requested operation + _Func->RotateObjectToEuler(m_ID, s_Vector3.x, y, s_Vector3.z, mRotateToEulerDuration); +} + +// ------------------------------------------------------------------------------------------------ +void CObject::RotateToEulerZ(Float32 z) const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Vector3.Clear(); + // Retrieve the current values for unchanged components + _Func->GetObjectRotationEuler(m_ID, &s_Vector3.x, &s_Vector3.y, nullptr); + // Perform the requested operation + _Func->RotateObjectToEuler(m_ID, s_Vector3.z, s_Vector3.y, z, mRotateToEulerDuration); +} + +// ------------------------------------------------------------------------------------------------ +void CObject::RotateByEulerX(Float32 x) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->RotateObjectByEuler(m_ID, x, 0.0f, 0.0f, mRotateByEulerDuration); +} + +// ------------------------------------------------------------------------------------------------ +void CObject::RotateByEulerY(Float32 y) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->RotateObjectByEuler(m_ID, 0.0f, y, 0.0f, mRotateByEulerDuration); +} + +// ------------------------------------------------------------------------------------------------ +void CObject::RotateByEulerZ(Float32 z) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->RotateObjectByEuler(m_ID, 0.0f, 0.0f, z, mRotateByEulerDuration); +} + // ------------------------------------------------------------------------------------------------ static Object & Object_CreateEx(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, Int32 alpha) { - return _Core->NewObject(model, world, x, y, z, alpha, SQMOD_CREATE_DEFAULT, NullObject()); + return Core::Get().NewObject(model, world, x, y, z, alpha, SQMOD_CREATE_DEFAULT, NullObject()); } static Object & Object_CreateEx(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, Int32 alpha, Int32 header, Object & payload) { - return _Core->NewObject(model, world, x, y, z, alpha, header, payload); + return Core::Get().NewObject(model, world, x, y, z, alpha, header, payload); } // ------------------------------------------------------------------------------------------------ static Object & Object_Create(Int32 model, Int32 world, const Vector3 & pos, Int32 alpha) { - return _Core->NewObject(model, world, pos.x, pos.y, pos.z, alpha, + return Core::Get().NewObject(model, world, pos.x, pos.y, pos.z, alpha, SQMOD_CREATE_DEFAULT, NullObject()); } static Object & Object_Create(Int32 model, Int32 world, const Vector3 & pos, Int32 alpha, Int32 header, Object & payload) { - return _Core->NewObject(model, world, pos.x, pos.y, pos.z, alpha, header, payload); + return Core::Get().NewObject(model, world, pos.x, pos.y, pos.z, alpha, header, payload); } // ------------------------------------------------------------------------------------------------ @@ -580,8 +812,8 @@ static const Object & Object_FindByID(Int32 id) STHROWF("The specified object identifier is invalid: %d", id); } // Obtain the ends of the entity pool - Core::Objects::const_iterator itr = _Core->GetObjects().cbegin(); - Core::Objects::const_iterator end = _Core->GetObjects().cend(); + Core::Objects::const_iterator itr = Core::Get().GetObjects().cbegin(); + Core::Objects::const_iterator end = Core::Get().GetObjects().cend(); // Process each entity in the pool for (; itr != end; ++itr) { @@ -602,8 +834,8 @@ static const Object & Object_FindByTag(CSStr tag) if (!tag || *tag == '\0') STHROWF("The specified object tag is invalid: null/empty"); // Obtain the ends of the entity pool - Core::Objects::const_iterator itr = _Core->GetObjects().cbegin(); - Core::Objects::const_iterator end = _Core->GetObjects().cend(); + Core::Objects::const_iterator itr = Core::Get().GetObjects().cbegin(); + Core::Objects::const_iterator end = Core::Get().GetObjects().cend(); // Process each entity in the pool for (; itr != end; ++itr) { @@ -623,8 +855,8 @@ static Array Object_FindActive() // Remember the initial stack size StackGuard sg; // Obtain the ends of the entity pool - Core::Objects::const_iterator itr = _Core->GetObjects().cbegin(); - Core::Objects::const_iterator end = _Core->GetObjects().cend(); + Core::Objects::const_iterator itr = Core::Get().GetObjects().cbegin(); + Core::Objects::const_iterator end = Core::Get().GetObjects().cend(); // Allocate an empty array on the stack sq_newarray(DefaultVM::Get(), 0); // Process each entity in the pool @@ -657,6 +889,13 @@ void Register_CObject(HSQUIRRELVM vm) .Func(_SC("_tostring"), &CObject::ToString) // Static Values .SetStaticValue(_SC("MaxID"), CObject::Max) + // Member Variables + .Var(_SC("MoveToDuration"), &CObject::mMoveToDuration) + .Var(_SC("MoveByDuration"), &CObject::mMoveByDuration) + .Var(_SC("RotateToDuration"), &CObject::mRotateToDuration) + .Var(_SC("RotateByDuration"), &CObject::mRotateByDuration) + .Var(_SC("RotateToEulerDuration"), &CObject::mRotateToEulerDuration) + .Var(_SC("RotateByEulerDuration"), &CObject::mRotateByEulerDuration) // Core Properties .Prop(_SC("ID"), &CObject::GetID) .Prop(_SC("Tag"), &CObject::GetTag, &CObject::SetTag) @@ -674,49 +913,71 @@ void Register_CObject(HSQUIRRELVM vm) .Prop(_SC("Alpha"), &CObject::GetAlpha, &CObject::SetAlpha) .Prop(_SC("Pos"), &CObject::GetPosition, &CObject::SetPosition) .Prop(_SC("Position"), &CObject::GetPosition, &CObject::SetPosition) - .Prop(_SC("ERot"), &CObject::GetRotation) + .Prop(_SC("Rot"), &CObject::GetRotation) .Prop(_SC("Rotation"), &CObject::GetRotation) - .Prop(_SC("RotationEuler"), &CObject::GetRotationEuler) + .Prop(_SC("EulerRot"), &CObject::GetRotationEuler) + .Prop(_SC("EulerRotation"), &CObject::GetRotationEuler) .Prop(_SC("ShotReport"), &CObject::GetShotReport, &CObject::SetShotReport) - .Prop(_SC("BumpReport"), &CObject::GetBumpReport, &CObject::SetBumpReport) - .Prop(_SC("X"), &CObject::GetPosX, &CObject::SetPosX) - .Prop(_SC("Y"), &CObject::GetPosY, &CObject::SetPosY) - .Prop(_SC("Z"), &CObject::GetPosZ, &CObject::SetPosZ) - .Prop(_SC("RX"), &CObject::GetRotX) - .Prop(_SC("RY"), &CObject::GetRotY) - .Prop(_SC("RZ"), &CObject::GetRotZ) - .Prop(_SC("RW"), &CObject::GetRotW) - .Prop(_SC("EX"), &CObject::GetERotX) - .Prop(_SC("EY"), &CObject::GetERotY) - .Prop(_SC("EZ"), &CObject::GetERotZ) + .Prop(_SC("BumpReport"), &CObject::GetTouchedReport, &CObject::SetTouchedReport) + .Prop(_SC("TouchedReport"), &CObject::GetTouchedReport, &CObject::SetTouchedReport) + .Prop(_SC("PosX"), &CObject::GetPositionX, &CObject::SetPositionX) + .Prop(_SC("PosY"), &CObject::GetPositionY, &CObject::SetPositionY) + .Prop(_SC("PosZ"), &CObject::GetPositionZ, &CObject::SetPositionZ) + .Prop(_SC("RotX"), &CObject::GetRotationX) + .Prop(_SC("RotY"), &CObject::GetRotationY) + .Prop(_SC("RotZ"), &CObject::GetRotationZ) + .Prop(_SC("RotW"), &CObject::GetRotationW) + .Prop(_SC("EulerRotX"), &CObject::GetEulerRotationX) + .Prop(_SC("EulerRotY"), &CObject::GetEulerRotationY) + .Prop(_SC("EulerRotZ"), &CObject::GetEulerRotationZ) + .Prop(_SC("MoveToX"), &CObject::GetPositionX, &CObject::MoveToX) + .Prop(_SC("MoveToY"), &CObject::GetPositionY, &CObject::MoveToY) + .Prop(_SC("MoveToZ"), &CObject::GetPositionZ, &CObject::MoveToZ) + .Prop(_SC("MoveByX"), &CObject::GetPositionX, &CObject::MoveByX) + .Prop(_SC("MoveByY"), &CObject::GetPositionY, &CObject::MoveByY) + .Prop(_SC("MoveByZ"), &CObject::GetPositionZ, &CObject::MoveByZ) + .Prop(_SC("RotateToX"), &CObject::GetRotationX, &CObject::RotateToX) + .Prop(_SC("RotateToY"), &CObject::GetRotationY, &CObject::RotateToY) + .Prop(_SC("RotateToZ"), &CObject::GetRotationZ, &CObject::RotateToZ) + .Prop(_SC("RotateToW"), &CObject::GetRotationW, &CObject::RotateToW) + .Prop(_SC("RotateByX"), &CObject::GetRotationX, &CObject::RotateByX) + .Prop(_SC("RotateByY"), &CObject::GetRotationY, &CObject::RotateByY) + .Prop(_SC("RotateByZ"), &CObject::GetRotationZ, &CObject::RotateByZ) + .Prop(_SC("RotateByW"), &CObject::GetRotationW, &CObject::RotateByW) + .Prop(_SC("RotateToEulerX"), &CObject::GetEulerRotationX, &CObject::RotateToEulerX) + .Prop(_SC("RotateToEulerY"), &CObject::GetEulerRotationY, &CObject::RotateToEulerY) + .Prop(_SC("RotateToEulerZ"), &CObject::GetEulerRotationZ, &CObject::RotateToEulerZ) + .Prop(_SC("RotateByEulerX"), &CObject::GetEulerRotationX, &CObject::RotateByEulerX) + .Prop(_SC("RotateByEulerY"), &CObject::GetEulerRotationY, &CObject::RotateByEulerY) + .Prop(_SC("RotateByEulerZ"), &CObject::GetEulerRotationZ, &CObject::RotateByEulerZ) // Member Methods .Func(_SC("StreamedFor"), &CObject::IsStreamedFor) .Func(_SC("SetAlpha"), &CObject::SetAlphaEx) .Func(_SC("SetPosition"), &CObject::SetPositionEx) // Member Overloads - .Overload< void (CObject::*)(const Vector3 &, Int32) const > + .Overload< void (CObject::*)(const Vector3 &, Uint32) const > (_SC("MoveTo"), &CObject::MoveTo) - .Overload< void (CObject::*)(Float32, Float32, Float32, Int32) const > + .Overload< void (CObject::*)(Float32, Float32, Float32, Uint32) const > (_SC("MoveTo"), &CObject::MoveToEx) - .Overload< void (CObject::*)(const Vector3 &, Int32) const > + .Overload< void (CObject::*)(const Vector3 &, Uint32) const > (_SC("MoveBy"), &CObject::MoveBy) - .Overload< void (CObject::*)(Float32, Float32, Float32, Int32) const > + .Overload< void (CObject::*)(Float32, Float32, Float32, Uint32) const > (_SC("MoveBy"), &CObject::MoveByEx) - .Overload< void (CObject::*)(const Quaternion &, Int32) const > + .Overload< void (CObject::*)(const Quaternion &, Uint32) const > (_SC("RotateTo"), &CObject::RotateTo) - .Overload< void (CObject::*)(Float32, Float32, Float32, Float32, Int32) const > + .Overload< void (CObject::*)(Float32, Float32, Float32, Float32, Uint32) const > (_SC("RotateTo"), &CObject::RotateToEx) - .Overload< void (CObject::*)(const Vector3 &, Int32) const > + .Overload< void (CObject::*)(const Vector3 &, Uint32) const > (_SC("RotateToEuler"), &CObject::RotateToEuler) - .Overload< void (CObject::*)(Float32, Float32, Float32, Int32) const > + .Overload< void (CObject::*)(Float32, Float32, Float32, Uint32) const > (_SC("RotateToEuler"), &CObject::RotateToEulerEx) - .Overload< void (CObject::*)(const Quaternion &, Int32) const > + .Overload< void (CObject::*)(const Quaternion &, Uint32) const > (_SC("RotateBy"), &CObject::RotateBy) - .Overload< void (CObject::*)(Float32, Float32, Float32, Float32, Int32) const > + .Overload< void (CObject::*)(Float32, Float32, Float32, Float32, Uint32) const > (_SC("RotateBy"), &CObject::RotateByEx) - .Overload< void (CObject::*)(const Vector3 &, Int32) const > + .Overload< void (CObject::*)(const Vector3 &, Uint32) const > (_SC("RotateByEuler"), &CObject::RotateByEuler) - .Overload< void (CObject::*)(Float32, Float32, Float32, Int32) const > + .Overload< void (CObject::*)(Float32, Float32, Float32, Uint32) const > (_SC("RotateByEuler"), &CObject::RotateByEulerEx) // Static Functions .StaticFunc(_SC("FindByID"), &Object_FindByID) diff --git a/source/Entity/Object.hpp b/source/Entity/Object.hpp index fc671184..652f5543 100644 --- a/source/Entity/Object.hpp +++ b/source/Entity/Object.hpp @@ -43,6 +43,24 @@ private: public: + /* -------------------------------------------------------------------------------------------- + * The default duration to use when moving the object. + */ + Uint32 mMoveToDuration; + Uint32 mMoveByDuration; + + /* -------------------------------------------------------------------------------------------- + * The default duration to use when rotating the object to Quaternion. + */ + Uint32 mRotateToDuration; + Uint32 mRotateByDuration; + + /* -------------------------------------------------------------------------------------------- + * The default duration to use when rotating the object to Euler. + */ + Uint32 mRotateToEulerDuration; + Uint32 mRotateByEulerDuration; + /* -------------------------------------------------------------------------------------------- * Maximum possible number that could represent an identifier for this entity type. */ @@ -194,27 +212,27 @@ public: /* -------------------------------------------------------------------------------------------- * Modify the alpha of the managed object entity over the specified time. */ - void SetAlphaEx(Int32 alpha, Int32 time) const; + void SetAlphaEx(Int32 alpha, Uint32 time) const; /* -------------------------------------------------------------------------------------------- * Move the managed object entity to the specified position over the specified time. */ - void MoveTo(const Vector3 & pos, Int32 time) const; + void MoveTo(const Vector3 & pos, Uint32 time) const; /* -------------------------------------------------------------------------------------------- * Move the managed object entity to the specified position over the specified time. */ - void MoveToEx(Float32 x, Float32 y, Float32 z, Int32 time) const; + void MoveToEx(Float32 x, Float32 y, Float32 z, Uint32 time) const; /* -------------------------------------------------------------------------------------------- * Move the managed object entity by the specified position over the specified time. */ - void MoveBy(const Vector3 & pos, Int32 time) const; + void MoveBy(const Vector3 & pos, Uint32 time) const; /* -------------------------------------------------------------------------------------------- * Move the managed object entity by the specified position over the specified time. */ - void MoveByEx(Float32 x, Float32 y, Float32 z, Int32 time) const; + void MoveByEx(Float32 x, Float32 y, Float32 z, Uint32 time) const; /* -------------------------------------------------------------------------------------------- * Retrieve the position of the managed object entity. @@ -234,42 +252,42 @@ public: /* -------------------------------------------------------------------------------------------- * Rotate the managed object entity to the specified rotation over the specified time. */ - void RotateTo(const Quaternion & rot, Int32 time) const; + void RotateTo(const Quaternion & rot, Uint32 time) const; /* -------------------------------------------------------------------------------------------- * Rotate the managed object entity to the specified rotation over the specified time. */ - void RotateToEx(Float32 x, Float32 y, Float32 z, Float32 w, Int32 time) const; + void RotateToEx(Float32 x, Float32 y, Float32 z, Float32 w, Uint32 time) const; /* -------------------------------------------------------------------------------------------- - * Rotate the managed object entity to the specified euler rotation over the specified time. + * Rotate the managed object entity to the specified Euler rotation over the specified time. */ - void RotateToEuler(const Vector3 & rot, Int32 time) const; + void RotateToEuler(const Vector3 & rot, Uint32 time) const; /* -------------------------------------------------------------------------------------------- - * Rotate the managed object entity to the specified euler rotation over the specified time. + * Rotate the managed object entity to the specified Euler rotation over the specified time. */ - void RotateToEulerEx(Float32 x, Float32 y, Float32 z, Int32 time) const; + void RotateToEulerEx(Float32 x, Float32 y, Float32 z, Uint32 time) const; /* -------------------------------------------------------------------------------------------- * Rotate the managed object entity by the specified rotation over the specified time. */ - void RotateBy(const Quaternion & rot, Int32 time) const; + void RotateBy(const Quaternion & rot, Uint32 time) const; /* -------------------------------------------------------------------------------------------- * Rotate the managed object entity by the specified rotation over the specified time. */ - void RotateByEx(Float32 x, Float32 y, Float32 z, Float32 w, Int32 time) const; + void RotateByEx(Float32 x, Float32 y, Float32 z, Float32 w, Uint32 time) const; /* -------------------------------------------------------------------------------------------- - * Rotate the managed object entity by the specified euler rotation over the specified time. + * Rotate the managed object entity by the specified Euler rotation over the specified time. */ - void RotateByEuler(const Vector3 & rot, Int32 time) const; + void RotateByEuler(const Vector3 & rot, Uint32 time) const; /* -------------------------------------------------------------------------------------------- - * Rotate the managed object entity by the specified euler rotation over the specified time. + * Rotate the managed object entity by the specified Euler rotation over the specified time. */ - void RotateByEulerEx(Float32 x, Float32 y, Float32 z, Int32 time) const; + void RotateByEulerEx(Float32 x, Float32 y, Float32 z, Uint32 time) const; /* -------------------------------------------------------------------------------------------- * Retrieve the rotation of the managed object entity. @@ -277,7 +295,7 @@ public: const Quaternion & GetRotation(); /* -------------------------------------------------------------------------------------------- - * Retrieve the euler rotation of the managed object entity. + * Retrieve the Euler rotation of the managed object entity. */ const Vector3 & GetRotationEuler(); @@ -294,77 +312,177 @@ public: /* -------------------------------------------------------------------------------------------- * See whether the managed object entity reports player bumps. */ - bool GetBumpReport() const; + bool GetTouchedReport() const; /* -------------------------------------------------------------------------------------------- * Set whether the managed object entity reports player bumps. */ - void SetBumpReport(bool toggle) const; + void SetTouchedReport(bool toggle) const; /* -------------------------------------------------------------------------------------------- * Retrieve the position on the x axis of the managed object entity. */ - Float32 GetPosX() const; + Float32 GetPositionX() const; /* -------------------------------------------------------------------------------------------- * Retrieve the position on the y axis of the managed object entity. */ - Float32 GetPosY() const; + Float32 GetPositionY() const; /* -------------------------------------------------------------------------------------------- * Retrieve the position on the z axis of the managed object entity. */ - Float32 GetPosZ() const; + Float32 GetPositionZ() const; /* -------------------------------------------------------------------------------------------- * Modify the position on the x axis of the managed object entity. */ - void SetPosX(Float32 x) const; + void SetPositionX(Float32 x) const; /* -------------------------------------------------------------------------------------------- * Modify the position on the y axis of the managed object entity. */ - void SetPosY(Float32 y) const; + void SetPositionY(Float32 y) const; /* -------------------------------------------------------------------------------------------- * Modify the position on the z axis of the managed object entity. */ - void SetPosZ(Float32 z) const; + void SetPositionZ(Float32 z) const; /* -------------------------------------------------------------------------------------------- * Retrieve the rotation on the x axis of the managed object entity. */ - Float32 GetRotX() const; + Float32 GetRotationX() const; /* -------------------------------------------------------------------------------------------- * Retrieve the rotation on the y axis of the managed object entity. */ - Float32 GetRotY() const; + Float32 GetRotationY() const; /* -------------------------------------------------------------------------------------------- * Retrieve the rotation on the z axis of the managed object entity. */ - Float32 GetRotZ() const; + Float32 GetRotationZ() const; /* -------------------------------------------------------------------------------------------- * Retrieve the rotation amount of the managed object entity. */ - Float32 GetRotW() const; + Float32 GetRotationW() const; /* -------------------------------------------------------------------------------------------- - * Retrieve the euler rotation on the x axis of the managed object entity. + * Retrieve the Euler rotation on the x axis of the managed object entity. */ - Float32 GetERotX() const; + Float32 GetEulerRotationX() const; /* -------------------------------------------------------------------------------------------- - * Retrieve the euler rotation on the y axis of the managed object entity. + * Retrieve the Euler rotation on the y axis of the managed object entity. */ - Float32 GetERotY() const; + Float32 GetEulerRotationY() const; /* -------------------------------------------------------------------------------------------- - * Retrieve the euler rotation on the z axis of the managed object entity. + * Retrieve the Euler rotation on the z axis of the managed object entity. */ - Float32 GetERotZ() const; + Float32 GetEulerRotationZ() const; + + /* -------------------------------------------------------------------------------------------- + * Modify the position on the x axis of the managed object entity. + */ + void MoveToX(Float32 x) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the position on the y axis of the managed object entity. + */ + void MoveToY(Float32 y) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the position on the z axis of the managed object entity. + */ + void MoveToZ(Float32 z) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the position on the x axis of the managed object entity. + */ + void MoveByX(Float32 x) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the position on the y axis of the managed object entity. + */ + void MoveByY(Float32 y) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the position on the z axis of the managed object entity. + */ + void MoveByZ(Float32 z) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the rotation on the x axis of the managed object entity. + */ + void RotateToX(Float32 x) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the rotation on the y axis of the managed object entity. + */ + void RotateToY(Float32 y) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the rotation on the z axis of the managed object entity. + */ + void RotateToZ(Float32 z) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the rotation on the w axis of the managed object entity. + */ + void RotateToW(Float32 w) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the rotation on the x axis of the managed object entity. + */ + void RotateByX(Float32 x) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the rotation on the y axis of the managed object entity. + */ + void RotateByY(Float32 y) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the rotation on the z axis of the managed object entity. + */ + void RotateByZ(Float32 z) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the rotation on the w axis of the managed object entity. + */ + void RotateByW(Float32 w) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the rotation on the x axis of the managed object entity. + */ + void RotateToEulerX(Float32 x) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the rotation on the y axis of the managed object entity. + */ + void RotateToEulerY(Float32 y) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the rotation on the z axis of the managed object entity. + */ + void RotateToEulerZ(Float32 z) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the rotation on the x axis of the managed object entity. + */ + void RotateByEulerX(Float32 x) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the rotation on the y axis of the managed object entity. + */ + void RotateByEulerY(Float32 y) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the rotation on the z axis of the managed object entity. + */ + void RotateByEulerZ(Float32 z) const; }; } // Namespace:: SqMod diff --git a/source/Entity/Pickup.cpp b/source/Entity/Pickup.cpp index c91c24ff..7fa58fd1 100644 --- a/source/Entity/Pickup.cpp +++ b/source/Entity/Pickup.cpp @@ -17,7 +17,7 @@ const Int32 CPickup::Max = SQMOD_PICKUP_POOL; // ------------------------------------------------------------------------------------------------ SQInteger CPickup::Typename(HSQUIRRELVM vm) { - static SQChar name[] = _SC("SqPickup"); + static const SQChar name[] = _SC("SqPickup"); sq_pushstring(vm, name, sizeof(name)); return 1; } @@ -40,11 +40,17 @@ CPickup::~CPickup() Int32 CPickup::Cmp(const CPickup & o) const { if (m_ID == o.m_ID) + { return 0; + } else if (m_ID > o.m_ID) + { return 1; + } else + { return -1; + } } // ------------------------------------------------------------------------------------------------ @@ -89,7 +95,7 @@ bool CPickup::Destroy(Int32 header, Object & payload) // Validate the managed identifier Validate(); // Perform the requested operation - return _Core->DelPickup(m_ID, header, payload); + return Core::Get().DelPickup(m_ID, header, payload); } // ------------------------------------------------------------------------------------------------ @@ -98,7 +104,7 @@ void CPickup::BindEvent(Int32 evid, Object & env, Function & func) const // Validate the managed identifier Validate(); // Obtain the function instance called for this event - Function & event = _Core->GetPickupEvent(m_ID, evid); + Function & event = Core::Get().GetPickupEvent(m_ID, evid); // Is the specified callback function null? if (func.IsNull()) { @@ -125,15 +131,6 @@ bool CPickup::IsStreamedFor(CPlayer & player) const return _Func->IsPickupStreamedForPlayer(m_ID, player.GetID()); } -// ------------------------------------------------------------------------------------------------ -Int32 CPickup::GetModel() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->PickupGetModel(m_ID); -} - // ------------------------------------------------------------------------------------------------ Int32 CPickup::GetWorld() const { @@ -158,7 +155,7 @@ Int32 CPickup::GetAlpha() const // Validate the managed identifier Validate(); // Return the requested information - return _Func->GetVehicleModel(m_ID); + return _Func->GetPickupAlpha(m_ID); } // ------------------------------------------------------------------------------------------------ @@ -167,7 +164,7 @@ void CPickup::SetAlpha(Int32 alpha) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->PickupSetAlpha(m_ID, alpha); + _Func->SetPickupAlpha(m_ID, alpha); } // ------------------------------------------------------------------------------------------------ @@ -176,7 +173,7 @@ bool CPickup::GetAutomatic() const // Validate the managed identifier Validate(); // Return the requested information - return _Func->PickupIsAutomatic(m_ID); + return _Func->IsPickupAutomatic(m_ID); } // ------------------------------------------------------------------------------------------------ @@ -185,7 +182,7 @@ void CPickup::SetAutomatic(bool toggle) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->PickupSetAutomatic(m_ID, toggle); + _Func->SetPickupIsAutomatic(m_ID, toggle); } // ------------------------------------------------------------------------------------------------ @@ -212,7 +209,7 @@ void CPickup::Refresh() const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->PickupRefresh(m_ID); + _Func->RefreshPickup(m_ID); } // ------------------------------------------------------------------------------------------------ @@ -223,7 +220,7 @@ const Vector3 & CPickup::GetPosition() // Clear previous position information, if any s_Vector3.Clear(); // Query the server for the position values - _Func->PickupGetPos(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); + _Func->GetPickupPosition(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); // Return the requested information return s_Vector3; } @@ -234,7 +231,7 @@ void CPickup::SetPosition(const Vector3 & pos) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->PickupSetPos(m_ID, pos.x, pos.y, pos.z); + _Func->SetPickupPosition(m_ID, pos.x, pos.y, pos.z); } // ------------------------------------------------------------------------------------------------ @@ -243,7 +240,16 @@ void CPickup::SetPositionEx(Float32 x, Float32 y, Float32 z) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->PickupSetPos(m_ID, x, y, z); + _Func->SetPickupPosition(m_ID, x, y, z); +} + +// ------------------------------------------------------------------------------------------------ +Int32 CPickup::GetModel() const +{ + // Validate the managed identifier + Validate(); + // Return the requested information + return _Func->GetPickupModel(m_ID); } // ------------------------------------------------------------------------------------------------ @@ -252,86 +258,86 @@ Int32 CPickup::GetQuantity() const // Validate the managed identifier Validate(); // Return the requested information - return _Func->PickupGetQuantity(m_ID); + return _Func->GetPickupQuantity(m_ID); } // ------------------------------------------------------------------------------------------------ -Float32 CPickup::GetPosX() const +Float32 CPickup::GetPositionX() const { // Validate the managed identifier Validate(); // Clear previous position information, if any s_Vector3.x = 0; // Query the server for the requested component value - _Func->PickupGetPos(m_ID, &s_Vector3.x, NULL, NULL); + _Func->GetPickupPosition(m_ID, &s_Vector3.x, NULL, NULL); // Return the requested information return s_Vector3.x; } // ------------------------------------------------------------------------------------------------ -Float32 CPickup::GetPosY() const +Float32 CPickup::GetPositionY() const { // Validate the managed identifier Validate(); // Clear previous position information, if any s_Vector3.y = 0; // Query the server for the requested component value - _Func->PickupGetPos(m_ID, NULL, &s_Vector3.y, NULL); + _Func->GetPickupPosition(m_ID, NULL, &s_Vector3.y, NULL); // Return the requested information return s_Vector3.y; } // ------------------------------------------------------------------------------------------------ -Float32 CPickup::GetPosZ() const +Float32 CPickup::GetPositionZ() const { // Validate the managed identifier Validate(); // Clear previous position information, if any s_Vector3.z = 0; // Query the server for the requested component value - _Func->PickupGetPos(m_ID, NULL, NULL, &s_Vector3.z); + _Func->GetPickupPosition(m_ID, NULL, NULL, &s_Vector3.z); // Return the requested information return s_Vector3.z; } // ------------------------------------------------------------------------------------------------ -void CPickup::SetPosX(Float32 x) const +void CPickup::SetPositionX(Float32 x) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->PickupGetPos(m_ID, NULL, &s_Vector3.y, &s_Vector3.z); + _Func->GetPickupPosition(m_ID, NULL, &s_Vector3.y, &s_Vector3.z); // Perform the requested operation - _Func->PickupSetPos(m_ID, x, s_Vector3.y, s_Vector3.z); + _Func->SetPickupPosition(m_ID, x, s_Vector3.y, s_Vector3.z); } // ------------------------------------------------------------------------------------------------ -void CPickup::SetPosY(Float32 y) const +void CPickup::SetPositionY(Float32 y) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->PickupGetPos(m_ID, &s_Vector3.x, NULL, &s_Vector3.z); + _Func->GetPickupPosition(m_ID, &s_Vector3.x, NULL, &s_Vector3.z); // Perform the requested operation - _Func->PickupSetPos(m_ID, s_Vector3.x, y, s_Vector3.z); + _Func->SetPickupPosition(m_ID, s_Vector3.x, y, s_Vector3.z); } // ------------------------------------------------------------------------------------------------ -void CPickup::SetPosZ(Float32 z) const +void CPickup::SetPositionZ(Float32 z) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->PickupGetPos(m_ID, &s_Vector3.x, &s_Vector3.y, NULL); + _Func->GetPickupPosition(m_ID, &s_Vector3.x, &s_Vector3.y, NULL); // Perform the requested operation - _Func->PickupSetPos(m_ID, s_Vector3.z, s_Vector3.y, z); + _Func->SetPickupPosition(m_ID, s_Vector3.z, s_Vector3.y, z); } // ------------------------------------------------------------------------------------------------ static Object & Pickup_CreateEx(Int32 model, Int32 world, Int32 quantity, Float32 x, Float32 y, Float32 z, Int32 alpha, bool automatic) { - return _Core->NewPickup(model, world, quantity, x, y, z, alpha, automatic, + return Core::Get().NewPickup(model, world, quantity, x, y, z, alpha, automatic, SQMOD_CREATE_DEFAULT, NullObject()); } @@ -339,21 +345,21 @@ static Object & Pickup_CreateEx(Int32 model, Int32 world, Int32 quantity, Float32 x, Float32 y, Float32 z, Int32 alpha, bool automatic, Int32 header, Object & payload) { - return _Core->NewPickup(model, world, quantity, x, y, z, alpha, automatic, header, payload); + return Core::Get().NewPickup(model, world, quantity, x, y, z, alpha, automatic, header, payload); } // ------------------------------------------------------------------------------------------------ static Object & Pickup_Create(Int32 model, Int32 world, Int32 quantity, const Vector3 & pos, Int32 alpha, bool automatic) { - return _Core->NewPickup(model, world, quantity, pos.x, pos.y, pos.z, alpha, automatic, + return Core::Get().NewPickup(model, world, quantity, pos.x, pos.y, pos.z, alpha, automatic, SQMOD_CREATE_DEFAULT, NullObject()); } static Object & Pickup_Create(Int32 model, Int32 world, Int32 quantity, const Vector3 & pos, Int32 alpha, bool automatic, Int32 header, Object & payload) { - return _Core->NewPickup(model, world, quantity, pos.x, pos.y, pos.z, alpha, automatic, + return Core::Get().NewPickup(model, world, quantity, pos.x, pos.y, pos.z, alpha, automatic, header, payload); } @@ -366,8 +372,8 @@ static const Object & Pickup_FindByID(Int32 id) STHROWF("The specified pickup identifier is invalid: %d", id); } // Obtain the ends of the entity pool - Core::Pickups::const_iterator itr = _Core->GetPickups().cbegin(); - Core::Pickups::const_iterator end = _Core->GetPickups().cend(); + Core::Pickups::const_iterator itr = Core::Get().GetPickups().cbegin(); + Core::Pickups::const_iterator end = Core::Get().GetPickups().cend(); // Process each entity in the pool for (; itr != end; ++itr) { @@ -390,8 +396,8 @@ static const Object & Pickup_FindByTag(CSStr tag) STHROWF("The specified pickup tag is invalid: null/empty"); } // Obtain the ends of the entity pool - Core::Pickups::const_iterator itr = _Core->GetPickups().cbegin(); - Core::Pickups::const_iterator end = _Core->GetPickups().cend(); + Core::Pickups::const_iterator itr = Core::Get().GetPickups().cbegin(); + Core::Pickups::const_iterator end = Core::Get().GetPickups().cend(); // Process each entity in the pool for (; itr != end; ++itr) { @@ -411,8 +417,8 @@ static Array Pickup_FindActive() // Remember the initial stack size StackGuard sg; // Obtain the ends of the entity pool - Core::Pickups::const_iterator itr = _Core->GetPickups().cbegin(); - Core::Pickups::const_iterator end = _Core->GetPickups().cend(); + Core::Pickups::const_iterator itr = Core::Get().GetPickups().cbegin(); + Core::Pickups::const_iterator end = Core::Get().GetPickups().cend(); // Allocate an empty array on the stack sq_newarray(DefaultVM::Get(), 0); // Process each entity in the pool @@ -467,9 +473,9 @@ void Register_CPickup(HSQUIRRELVM vm) .Prop(_SC("Pos"), &CPickup::GetPosition, &CPickup::SetPosition) .Prop(_SC("Position"), &CPickup::GetPosition, &CPickup::SetPosition) .Prop(_SC("Quantity"), &CPickup::GetQuantity) - .Prop(_SC("X"), &CPickup::GetPosX, &CPickup::SetPosX) - .Prop(_SC("Y"), &CPickup::GetPosY, &CPickup::SetPosY) - .Prop(_SC("Z"), &CPickup::GetPosZ, &CPickup::SetPosZ) + .Prop(_SC("PosX"), &CPickup::GetPositionX, &CPickup::SetPositionX) + .Prop(_SC("PosY"), &CPickup::GetPositionY, &CPickup::SetPositionY) + .Prop(_SC("PosZ"), &CPickup::GetPositionZ, &CPickup::SetPositionZ) // Member Methods .Func(_SC("StreamedFor"), &CPickup::IsStreamedFor) .Func(_SC("Refresh"), &CPickup::Refresh) diff --git a/source/Entity/Pickup.hpp b/source/Entity/Pickup.hpp index 834335d8..71387574 100644 --- a/source/Entity/Pickup.hpp +++ b/source/Entity/Pickup.hpp @@ -165,11 +165,6 @@ public: */ bool IsStreamedFor(CPlayer & player) const; - /* -------------------------------------------------------------------------------------------- - * Retrieve the model of the managed pickup entity. - */ - Int32 GetModel() const; - /* -------------------------------------------------------------------------------------------- * Retrieve the world in which the managed pickup entity exists. */ @@ -230,6 +225,11 @@ public: */ void SetPositionEx(Float32 x, Float32 y, Float32 z) const; + /* -------------------------------------------------------------------------------------------- + * Retrieve the model of the managed pickup entity. + */ + Int32 GetModel() const; + /* -------------------------------------------------------------------------------------------- * Retrieve the quantity of the managed pickup entity. */ @@ -238,32 +238,32 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the position on the x axis of the managed pickup entity. */ - Float32 GetPosX() const; + Float32 GetPositionX() const; /* -------------------------------------------------------------------------------------------- * Retrieve the position on the y axis of the managed pickup entity. */ - Float32 GetPosY() const; + Float32 GetPositionY() const; /* -------------------------------------------------------------------------------------------- * Retrieve the position on the z axis of the managed pickup entity. */ - Float32 GetPosZ() const; + Float32 GetPositionZ() const; /* -------------------------------------------------------------------------------------------- * Modify the position on the x axis of the managed pickup entity. */ - void SetPosX(Float32 x) const; + void SetPositionX(Float32 x) const; /* -------------------------------------------------------------------------------------------- * Modify the position on the y axis of the managed pickup entity. */ - void SetPosY(Float32 y) const; + void SetPositionY(Float32 y) const; /* -------------------------------------------------------------------------------------------- * Modify the position on the z axis of the managed pickup entity. */ - void SetPosZ(Float32 z) const; + void SetPositionZ(Float32 z) const; }; } // Namespace:: SqMod diff --git a/source/Entity/Player.cpp b/source/Entity/Player.cpp index b06832f4..92093809 100644 --- a/source/Entity/Player.cpp +++ b/source/Entity/Player.cpp @@ -4,8 +4,12 @@ #include "Base/Color3.hpp" #include "Base/Vector3.hpp" #include "Base/Stack.hpp" +#include "Library/Utils/BufferWrapper.hpp" #include "Core.hpp" +// ------------------------------------------------------------------------------------------------ +#include + // ------------------------------------------------------------------------------------------------ #include @@ -13,11 +17,11 @@ namespace SqMod { // ------------------------------------------------------------------------------------------------ -Color3 CPlayer::s_Color3; -Vector3 CPlayer::s_Vector3; +Color3 CPlayer::s_Color3; +Vector3 CPlayer::s_Vector3; // ------------------------------------------------------------------------------------------------ -SQChar CPlayer::s_Buffer[SQMOD_PLAYER_TMP_BUFFER]; +SQChar CPlayer::s_Buffer[SQMOD_PLAYER_TMP_BUFFER]; // ------------------------------------------------------------------------------------------------ const Int32 CPlayer::Max = SQMOD_PLAYER_POOL; @@ -25,7 +29,7 @@ const Int32 CPlayer::Max = SQMOD_PLAYER_POOL; // ------------------------------------------------------------------------------------------------ SQInteger CPlayer::Typename(HSQUIRRELVM vm) { - static SQChar name[] = _SC("SqPlayer"); + static const SQChar name[] = _SC("SqPlayer"); sq_pushstring(vm, name, sizeof(name)); return 1; } @@ -33,9 +37,23 @@ SQInteger CPlayer::Typename(HSQUIRRELVM vm) // ------------------------------------------------------------------------------------------------ CPlayer::CPlayer(Int32 id) : m_ID(VALID_ENTITYGETEX(id, SQMOD_PLAYER_POOL)) - , m_Tag(ToStrF("%d", id)) + , m_Tag(ToStrF("%d", id)), m_Data(), m_Buffer(256), m_CircularLocks(0) + , mBufferInitSize(256) + , mMessageColor(0x6599FFFF) + , mAnnounceStyle(1) + , mDefaultAmmo(0) + , mMessagePrefix(_SC("")) + , mMessagePostfix(_SC("")) + , mAnnouncePrefix(_SC("")) + , mAnnouncePostfix(_SC("")) + , mMessagePrefixes() + , mLimitPrefixPostfixMessage(true) { - /* ... */ + // Reset message prefixes + for (unsigned n = 0; n < SQMOD_PLAYER_MSG_PREFIXES; ++n) + { + mMessagePrefixes[n].assign(_SC("")); + } } // ------------------------------------------------------------------------------------------------ @@ -48,11 +66,17 @@ CPlayer::~CPlayer() Int32 CPlayer::Cmp(const CPlayer & o) const { if (m_ID == o.m_ID) + { return 0; + } else if (m_ID > o.m_ID) + { return 1; + } else + { return -1; + } } // ------------------------------------------------------------------------------------------------ @@ -97,7 +121,7 @@ void CPlayer::BindEvent(Int32 evid, Object & env, Function & func) const // Validate the managed identifier Validate(); // Obtain the function instance called for this event - Function & event = _Core->GetPlayerEvent(m_ID, evid); + Function & event = Core::Get().GetPlayerEvent(m_ID, evid); // Is the specified callback function null? if (func.IsNull()) { @@ -110,27 +134,26 @@ void CPlayer::BindEvent(Int32 evid, Object & env, Function & func) const } } +// ------------------------------------------------------------------------------------------------ +bool CPlayer::IsConnected() const +{ + return _Func->IsPlayerConnected(m_ID); +} + // ------------------------------------------------------------------------------------------------ bool CPlayer::IsStreamedFor(CPlayer & player) const { // Is the specified player even valid? if (!player.IsActive()) + { STHROWF("Invalid player argument: null"); + } // Validate the managed identifier Validate(); // Return the requested information return _Func->IsPlayerStreamedForPlayer(m_ID, player.GetID()); } -// ------------------------------------------------------------------------------------------------ -Int32 CPlayer::GetClass() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->GetPlayerClass(m_ID); -} - // ------------------------------------------------------------------------------------------------ bool CPlayer::GetAdmin() const { @@ -154,12 +177,45 @@ CSStr CPlayer::GetIP() const { // Validate the managed identifier Validate(); - // Clear any previous string - s_Buffer[0] = 0; - // The server doesn't include the null terminator in the string (yet) - memset(s_Buffer, 0, sizeof(s_Buffer)); + // Clear any previous string (just in case) + s_Buffer[0] = '\0'; // Query the server for the ip of the managed player - _Func->GetPlayerIP(m_ID, s_Buffer, sizeof(s_Buffer)); + if (_Func->GetPlayerIP(m_ID, s_Buffer, sizeof(s_Buffer)) == vcmpErrorBufferTooSmall) + { + STHROWF("The available buffer was too small to contain the ip address"); + } + // Return the requested information + return s_Buffer; +} + +// ------------------------------------------------------------------------------------------------ +CSStr CPlayer::GetUID() const +{ + // Validate the managed identifier + Validate(); + // Clear any previous string (just in case) + s_Buffer[0] = '\0'; + // Query the server for the uid of the managed player + if (_Func->GetPlayerUID(m_ID, s_Buffer, sizeof(s_Buffer)) == vcmpErrorBufferTooSmall) + { + STHROWF("The available buffer was too small to contain the unique id"); + } + // Return the requested information + return s_Buffer; +} + +// ------------------------------------------------------------------------------------------------ +CSStr CPlayer::GetUID2() const +{ + // Validate the managed identifier + Validate(); + // Clear any previous string (just in case) + s_Buffer[0] = '\0'; + // Query the server for the uid2 of the managed player + if (_Func->GetPlayerUID2(m_ID, s_Buffer, sizeof(s_Buffer)) == vcmpErrorBufferTooSmall) + { + STHROWF("The available buffer was too small to contain the unique idv2"); + } // Return the requested information return s_Buffer; } @@ -182,21 +238,6 @@ void CPlayer::Ban() const _Func->BanPlayer(m_ID); } -// ------------------------------------------------------------------------------------------------ -bool CPlayer::IsConnected() const -{ - return _Func->IsPlayerConnected(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -bool CPlayer::IsSpawned() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->IsPlayerSpawned(m_ID); -} - // ------------------------------------------------------------------------------------------------ Uint32 CPlayer::GetKey() const { @@ -206,6 +247,91 @@ Uint32 CPlayer::GetKey() const return _Func->GetPlayerKey(m_ID); } +// ------------------------------------------------------------------------------------------------ +CSStr CPlayer::GetName() const +{ + // Validate the managed identifier + Validate(); + // Clear any previous string (just in case) + s_Buffer[0] = '\0'; + // Query the server for the name of the managed player + if (_Func->GetPlayerName(m_ID, s_Buffer, sizeof(s_Buffer)) == vcmpErrorBufferTooSmall) + { + STHROWF("The available buffer was too small to contain the nickname"); + } + // Return the requested information + return s_Buffer; +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::SetName(CSStr name) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->SetPlayerName(m_ID, name); +} + +// ------------------------------------------------------------------------------------------------ +Int32 CPlayer::GetState() const +{ + // Validate the managed identifier + Validate(); + // Return the requested information + return _Func->GetPlayerState(m_ID); +} + +// ------------------------------------------------------------------------------------------------ +Int32 CPlayer::GetOption(Int32 option_id) const +{ + // Attempt to obtain the current value of the specified option + const bool value = _Func->GetPlayerOption(m_ID, static_cast< vcmpPlayerOption >(option_id)); + // Check for errors + if (_Func->GetLastError() == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Invalid option identifier: %d", option_id); + } + // Return the requested value + return value; +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::SetOption(Int32 option_id, bool toggle) +{ + // Attempt to obtain the current value of the specified option + const bool value = _Func->GetPlayerOption(m_ID, static_cast< vcmpPlayerOption >(option_id)); + // Attempt to modify the current value of the specified option + if (_Func->SetPlayerOption(m_ID, static_cast< vcmpPlayerOption >(option_id), + toggle) == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Invalid option identifier: %d", option_id); + } + else if (!(m_CircularLocks & PCL_EMIT_PLAYER_OPTION)) + { + Core::Get().EmitPlayerOption(m_ID, option_id, value, 0, NullObject()); + } +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::SetOptionEx(Int32 option_id, bool toggle, Int32 header, Object & payload) +{ + // Attempt to obtain the current value of the specified option + const bool value = _Func->GetPlayerOption(m_ID, static_cast< vcmpPlayerOption >(option_id)); + // Attempt to modify the current value of the specified option + if (_Func->SetPlayerOption(m_ID, static_cast< vcmpPlayerOption >(option_id), + toggle) == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Invalid option identifier: %d", option_id); + } + else if (!(m_CircularLocks & PCL_EMIT_PLAYER_OPTION)) + { + // Prevent this event from triggering while executed + BitGuardU32 bg(m_CircularLocks, PCL_EMIT_PLAYER_OPTION); + // Now forard the evnet call + Core::Get().EmitPlayerOption(m_ID, option_id, value, header, payload); + } +} + // ------------------------------------------------------------------------------------------------ Int32 CPlayer::GetWorld() const { @@ -225,21 +351,21 @@ void CPlayer::SetWorld(Int32 world) const } // ------------------------------------------------------------------------------------------------ -Int32 CPlayer::GetSecWorld() const +Int32 CPlayer::GetSecondaryWorld() const { // Validate the managed identifier Validate(); // Return the requested information - return _Func->GetPlayerSecWorld(m_ID); + return _Func->GetPlayerSecondaryWorld(m_ID); } // ------------------------------------------------------------------------------------------------ -void CPlayer::SetSecWorld(Int32 world) const +void CPlayer::SetSecondaryWorld(Int32 world) const { // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetPlayerSecWorld(m_ID, world); + _Func->SetPlayerSecondaryWorld(m_ID, world); } // ------------------------------------------------------------------------------------------------ @@ -261,27 +387,12 @@ bool CPlayer::IsWorldCompatible(Int32 world) const } // ------------------------------------------------------------------------------------------------ -CSStr CPlayer::GetName() const +Int32 CPlayer::GetClass() const { // Validate the managed identifier Validate(); - // Clear any previous string - s_Buffer[0] = 0; - // The server doesn't include the null terminator in the string (yet) - memset(s_Buffer, 0, sizeof(s_Buffer)); - // Query the server for the name of the managed player - _Func->GetPlayerName(m_ID, s_Buffer, sizeof(s_Buffer)); // Return the requested information - return s_Buffer; -} - -// ------------------------------------------------------------------------------------------------ -void CPlayer::SetName(CSStr name) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->SetPlayerName(m_ID, static_cast< CCStr >(name)); + return _Func->GetPlayerClass(m_ID); } // ------------------------------------------------------------------------------------------------ @@ -299,7 +410,10 @@ void CPlayer::SetTeam(Int32 team) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetPlayerTeam(m_ID, team); + if (_Func->SetPlayerTeam(m_ID, team) == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Invalid team identifier: %d", team); + } } // ------------------------------------------------------------------------------------------------ @@ -317,7 +431,10 @@ void CPlayer::SetSkin(Int32 skin) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetPlayerSkin(m_ID, skin); + if (_Func->SetPlayerSkin(m_ID, skin) == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Invalid skin identifier: %d", skin); + } } // ------------------------------------------------------------------------------------------------ @@ -351,6 +468,15 @@ void CPlayer::SetColorEx(Uint8 r, Uint8 g, Uint8 b) const _Func->SetPlayerColour(m_ID, SQMOD_PACK_RGB(r, g, b)); } +// ------------------------------------------------------------------------------------------------ +bool CPlayer::IsSpawned() const +{ + // Validate the managed identifier + Validate(); + // Return the requested information + return _Func->IsPlayerSpawned(m_ID); +} + // ------------------------------------------------------------------------------------------------ void CPlayer::ForceSpawn() const { @@ -369,6 +495,15 @@ void CPlayer::ForceSelect() const _Func->ForcePlayerSelect(m_ID); } +// ------------------------------------------------------------------------------------------------ +bool CPlayer::IsTyping() const +{ + // Validate the managed identifier + Validate(); + // Return the requested information + return _Func->IsPlayerTyping(m_ID); +} + // ------------------------------------------------------------------------------------------------ Int32 CPlayer::GetMoney() const { @@ -414,6 +549,24 @@ void CPlayer::SetScore(Int32 score) const _Func->SetPlayerScore(m_ID, score); } +// ------------------------------------------------------------------------------------------------ +Int32 CPlayer::GetWantedLevel() const +{ + // Validate the managed identifier + Validate(); + // Return the requested information + return _Func->GetPlayerWantedLevel(m_ID); +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::SetWantedLevel(Int32 level) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->SetPlayerWantedLevel(m_ID, level); +} + // ------------------------------------------------------------------------------------------------ Int32 CPlayer::GetPing() const { @@ -432,45 +585,6 @@ Float32 CPlayer::GetFPS() const return _Func->GetPlayerFPS(m_ID); } -// ------------------------------------------------------------------------------------------------ -bool CPlayer::IsTyping() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->IsPlayerTyping(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -CSStr CPlayer::GetUID() const -{ - // Validate the managed identifier - Validate(); - // Clear any previous string - s_Buffer[0] = 0; - // The server doesn't include the null terminator in the string (yet) - memset(s_Buffer, 0, sizeof(s_Buffer)); - // Query the server for the uid of the managed player - _Func->GetPlayerUID(m_ID, s_Buffer, sizeof(s_Buffer)); - // Return the requested information - return s_Buffer; -} - -// ------------------------------------------------------------------------------------------------ -CSStr CPlayer::GetUID2() const -{ - // Validate the managed identifier - Validate(); - // Clear any previous string - s_Buffer[0] = 0; - // The server doesn't include the null terminator in the string (yet) - memset(s_Buffer, 0, sizeof(s_Buffer)); - // Query the server for the uid2 of the managed player - _Func->GetPlayerUID2(m_ID, s_Buffer, sizeof(s_Buffer)); - // Return the requested information - return s_Buffer; -} - // ------------------------------------------------------------------------------------------------ Float32 CPlayer::GetHealth() const { @@ -530,10 +644,10 @@ const Vector3 & CPlayer::GetPosition() const { // Validate the managed identifier Validate(); - // Clear previous position information, if any + // Clear previous information, if any s_Vector3.Clear(); - // Query the server for the position values - _Func->GetPlayerPos(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); + // Query the server for the values + _Func->GetPlayerPosition(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); // Return the requested information return s_Vector3; } @@ -544,7 +658,7 @@ void CPlayer::SetPosition(const Vector3 & pos) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetPlayerPos(m_ID, pos.x, pos.y, pos.z); + _Func->SetPlayerPosition(m_ID, pos.x, pos.y, pos.z); } // ------------------------------------------------------------------------------------------------ @@ -553,7 +667,7 @@ void CPlayer::SetPositionEx(Float32 x, Float32 y, Float32 z) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetPlayerPos(m_ID, x, y, z); + _Func->SetPlayerPosition(m_ID, x, y, z); } // ------------------------------------------------------------------------------------------------ @@ -641,6 +755,107 @@ void CPlayer::SetAlpha(Int32 alpha, Int32 fade) const _Func->SetPlayerAlpha(m_ID, alpha, fade); } +// ------------------------------------------------------------------------------------------------ +const Vector3 & CPlayer::GetAimPosition() const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Vector3.Clear(); + // Query the server for the values + _Func->GetPlayerAimPosition(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); + // Return the requested information + return s_Vector3; +} + +// ------------------------------------------------------------------------------------------------ +const Vector3 & CPlayer::GetAimDirection() const +{ + // Validate the managed identifier + Validate(); + // Clear previous direction information, if any + s_Vector3.Clear(); + // Query the server for the direction values + _Func->GetPlayerAimDirection(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); + // Return the requested information + return s_Vector3; +} + +// ------------------------------------------------------------------------------------------------ +bool CPlayer::IsBurning() const +{ + // Validate the managed identifier + Validate(); + // Return the requested information + return _Func->IsPlayerOnFire(m_ID); +} + +// ------------------------------------------------------------------------------------------------ +bool CPlayer::IsCrouched() const +{ + // Validate the managed identifier + Validate(); + // Return the requested information + return _Func->IsPlayerCrouching(m_ID); +} + +// ------------------------------------------------------------------------------------------------ +Int32 CPlayer::GetAction() const +{ + // Validate the managed identifier + Validate(); + // Return the requested information + return _Func->GetPlayerAction(m_ID); +} + +// ------------------------------------------------------------------------------------------------ +Int32 CPlayer::GetGameKeys() const +{ + // Validate the managed identifier + Validate(); + // Return the requested information + return _Func->GetPlayerGameKeys(m_ID); +} + +// ------------------------------------------------------------------------------------------------ +bool CPlayer::Embark(CVehicle & vehicle) const +{ + // Is the specified vehicle even valid? + if (!vehicle.IsActive()) + { + STHROWF("Invalid vehicle argument: null"); + } + // Validate the managed identifier + Validate(); + // Perform the requested operation + return (_Func->PutPlayerInVehicle(m_ID, vehicle.GetID(), 0, true, true) + != vcmpErrorRequestDenied); +} + +// ------------------------------------------------------------------------------------------------ +bool CPlayer::Embark(CVehicle & vehicle, Int32 slot, bool allocate, bool warp) const +{ + // Is the specified vehicle even valid? + if (!vehicle.IsActive()) + { + STHROWF("Invalid vehicle argument: null"); + } + // Validate the managed identifier + Validate(); + // Perform the requested operation + return (_Func->PutPlayerInVehicle(m_ID, vehicle.GetID(), slot, allocate, warp) + != vcmpErrorRequestDenied); +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::Disembark() const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->RemovePlayerFromVehicle(m_ID); +} + // ------------------------------------------------------------------------------------------------ Int32 CPlayer::GetVehicleStatus() const { @@ -651,7 +866,7 @@ Int32 CPlayer::GetVehicleStatus() const } // ------------------------------------------------------------------------------------------------ -Int32 CPlayer::GetOccupiedSlot() const +Int32 CPlayer::GetVehicleSlot() const { // Validate the managed identifier Validate(); @@ -665,7 +880,7 @@ Object & CPlayer::GetVehicle() const // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetVehicle(_Func->GetPlayerVehicleID(m_ID)).mObj; + return Core::Get().GetVehicle(_Func->GetPlayerVehicleId(m_ID)).mObj; } // ------------------------------------------------------------------------------------------------ @@ -674,187 +889,7 @@ Int32 CPlayer::GetVehicleID() const // Validate the managed identifier Validate(); // Return the requested information - return _Func->GetPlayerVehicleID(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -bool CPlayer::GetControllable() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->EnabledPlayerControllable(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -void CPlayer::SetControllable(bool toggle) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->TogglePlayerControllable(m_ID, toggle); -} - -// ------------------------------------------------------------------------------------------------ -bool CPlayer::GetDriveby() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->EnabledPlayerDriveby(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -void CPlayer::SetDriveby(bool toggle) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->TogglePlayerDriveby(m_ID, toggle); -} - -// ------------------------------------------------------------------------------------------------ -bool CPlayer::GetWhiteScanlines() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->EnabledPlayerWhiteScanlines(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -void CPlayer::SetWhiteScanlines(bool toggle) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->TogglePlayerWhiteScanlines(m_ID, toggle); -} - -// ------------------------------------------------------------------------------------------------ -bool CPlayer::GetGreenScanlines() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->EnabledPlayerGreenScanlines(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -void CPlayer::SetGreenScanlines(bool toggle) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->TogglePlayerGreenScanlines(m_ID, toggle); -} - -// ------------------------------------------------------------------------------------------------ -bool CPlayer::GetWidescreen() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->EnabledPlayerWidescreen(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -void CPlayer::SetWidescreen(bool toggle) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->TogglePlayerWidescreen(m_ID, toggle); -} - -// ------------------------------------------------------------------------------------------------ -bool CPlayer::GetShowMarkers() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->EnabledPlayerShowMarkers(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -void CPlayer::SetShowMarkers(bool toggle) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->TogglePlayerShowMarkers(m_ID, toggle); -} - -// ------------------------------------------------------------------------------------------------ -bool CPlayer::GetAttackPriv() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->EnabledPlayerAttackPriv(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -void CPlayer::SetAttackPriv(bool toggle) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->TogglePlayerAttackPriv(m_ID, toggle); -} - -// ------------------------------------------------------------------------------------------------ -bool CPlayer::GetHasMarker() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->EnabledPlayerHasMarker(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -void CPlayer::SetHasMarker(bool toggle) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->TogglePlayerHasMarker(m_ID, toggle); -} - -// ------------------------------------------------------------------------------------------------ -bool CPlayer::GetChatTags() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->EnabledPlayerChatTags(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -void CPlayer::SetChatTags(bool toggle) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->TogglePlayerChatTagsEnabled(m_ID, toggle); -} - -// ------------------------------------------------------------------------------------------------ -bool CPlayer::GetDrunkEffects() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->EnabledPlayerDrunkEffects(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -void CPlayer::SetDrunkEffects(bool toggle) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->TogglePlayerDrunkEffects(m_ID, toggle); + return _Func->GetPlayerVehicleId(m_ID); } // ------------------------------------------------------------------------------------------------ @@ -867,12 +902,27 @@ Int32 CPlayer::GetWeapon() const } // ------------------------------------------------------------------------------------------------ -void CPlayer::SetWeapon(Int32 wep, Int32 ammo) const +void CPlayer::SetWeapon(Int32 wep) const { // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetPlayerWeapon(m_ID, wep, ammo); + if (_Func->SetPlayerWeapon(m_ID, wep, mDefaultAmmo) == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Invalid weapon identifier: %d", wep); + } +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::SetWeaponEx(Int32 wep, Int32 ammo) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + if (_Func->SetPlayerWeapon(m_ID, wep, ammo) == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Invalid weapon ammo: %d", ammo); + } } // ------------------------------------------------------------------------------------------------ @@ -881,7 +931,77 @@ void CPlayer::GiveWeapon(Int32 wep, Int32 ammo) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->GivePlayerWeapon(m_ID, wep, ammo); + if (_Func->GivePlayerWeapon(m_ID, wep, ammo) == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Invalid weapon ammo: %d", ammo); + } +} + +// ------------------------------------------------------------------------------------------------ +Int32 CPlayer::GetAmmo() const +{ + // Validate the managed identifier + Validate(); + // Return the requested information + return _Func->GetPlayerWeaponAmmo(m_ID); +} + +// ------------------------------------------------------------------------------------------------ +Int32 CPlayer::GetWeaponSlot() const +{ + // Validate the managed identifier + Validate(); + // Return the requested information + return _Func->GetPlayerWeaponSlot(m_ID); +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::SetWeaponSlot(Int32 slot) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + if (_Func->SetPlayerWeaponSlot(m_ID, slot) == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Invalid weapon slot: %d", slot); + } +} + +// ------------------------------------------------------------------------------------------------ +Int32 CPlayer::GetWeaponAtSlot(Int32 slot) const +{ + // Attempt to obtain the weapon identifier of the specified slot + const Int32 id = _Func->GetPlayerWeaponAtSlot(m_ID, slot); + // Check for errors + if (_Func->GetLastError() == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Invalid weapon slot: %d", slot); + } + // Return the requested information + return id; +} + +// ------------------------------------------------------------------------------------------------ +Int32 CPlayer::GetAmmoAtSlot(Int32 slot) const +{ + // Attempt to obtain the weapon ammo of the specified slot + const Int32 ammo = _Func->GetPlayerAmmoAtSlot(m_ID, slot); + // Check for errors + if (_Func->GetLastError() == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Invalid weapon slot: %d", slot); + } + // Return the requested information + return ammo; +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::RemoveWeapon(Int32 wep) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->RemovePlayerWeapon(m_ID, wep); } // ------------------------------------------------------------------------------------------------ @@ -938,31 +1058,13 @@ void CPlayer::SetAnimation(Int32 group, Int32 anim) const _Func->SetPlayerAnimation(m_ID, group, anim); } -// ------------------------------------------------------------------------------------------------ -Int32 CPlayer::GetWantedLevel() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->GetPlayerWantedLevel(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -void CPlayer::SetWantedLevel(Int32 level) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->SetPlayerWantedLevel(m_ID, level); -} - // ------------------------------------------------------------------------------------------------ Object & CPlayer::StandingOnVehicle() const { // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetVehicle(_Func->GetPlayerStandingOnVehicle(m_ID)).mObj; + return Core::Get().GetVehicle(_Func->GetPlayerStandingOnVehicle(m_ID)).mObj; } // ------------------------------------------------------------------------------------------------ @@ -971,7 +1073,7 @@ Object & CPlayer::StandingOnObject() const // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetObject(_Func->GetPlayerStandingOnObject(m_ID)).mObj; + return Core::Get().GetObject(_Func->GetPlayerStandingOnObject(m_ID)).mObj; } // ------------------------------------------------------------------------------------------------ @@ -989,7 +1091,7 @@ Object & CPlayer::GetSpectator() const // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetPlayer(_Func->GetPlayerSpectateTarget(m_ID)).mObj; + return Core::Get().GetPlayer(_Func->GetPlayerSpectateTarget(m_ID)).mObj; } // ------------------------------------------------------------------------------------------------ @@ -1007,120 +1109,16 @@ void CPlayer::SetSpectator(CPlayer & target) const } // ------------------------------------------------------------------------------------------------ -bool CPlayer::IsBurning() const +void CPlayer::Redirect(CSStr ip, Uint32 port, CSStr nick, CSStr server_pass, CSStr user_pass) { // Validate the managed identifier Validate(); // Return the requested information - return _Func->GetPlayerOnFireStatus(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -bool CPlayer::IsCrouched() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->GetPlayerCrouchStatus(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -Int32 CPlayer::GetState() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->GetPlayerState(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -Int32 CPlayer::GetAction() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->GetPlayerAction(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -Int32 CPlayer::GetGameKeys() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->GetPlayerGameKeys(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -const Vector3 & CPlayer::GetAimPos() const -{ - // Validate the managed identifier - Validate(); - // Clear previous position information, if any - s_Vector3.Clear(); - // Query the server for the position values - _Func->GetPlayerAimPos(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); - // Return the requested information - return s_Vector3; -} - -// ------------------------------------------------------------------------------------------------ -const Vector3 & CPlayer::GetAimDir() const -{ - // Validate the managed identifier - Validate(); - // Clear previous direction information, if any - s_Vector3.Clear(); - // Query the server for the direction values - _Func->GetPlayerAimDir(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); - // Return the requested information - return s_Vector3; -} - -// ------------------------------------------------------------------------------------------------ -void CPlayer::Embark(CVehicle & vehicle) const -{ - // Is the specified vehicle even valid? - if (!vehicle.IsActive()) + if (_Func->RedirectPlayerToServer(m_ID, ip, port, + nick, server_pass, user_pass) == vcmpErrorNullArgument) { - STHROWF("Invalid vehicle argument: null"); + STHROWF("Invalid arguments encountered"); } - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->PutPlayerInVehicle(m_ID, vehicle.GetID(), 0, true, true); -} - -// ------------------------------------------------------------------------------------------------ -void CPlayer::Embark(CVehicle & vehicle, Int32 slot, bool allocate, bool warp) const -{ - // Is the specified vehicle even valid? - if (!vehicle.IsActive()) - { - STHROWF("Invalid vehicle argument: null"); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->PutPlayerInVehicle(m_ID, vehicle.GetID(), slot, allocate, warp); -} - -// ------------------------------------------------------------------------------------------------ -void CPlayer::Disembark() const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->RemovePlayerFromVehicle(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -bool CPlayer::Redirect(CSStr ip, Uint32 port, CSStr nick, CSStr pass, CSStr user) -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->RedirectPlayerToServer(m_ID, ip, port, nick, pass, user); } // ------------------------------------------------------------------------------------------------ @@ -1129,7 +1127,7 @@ Int32 CPlayer::GetAuthority() const // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetPlayer(m_ID).mAuthority; + return Core::Get().GetPlayer(m_ID).mAuthority; } // ------------------------------------------------------------------------------------------------ @@ -1138,11 +1136,11 @@ void CPlayer::SetAuthority(Int32 level) const // Validate the managed identifier Validate(); // Perform the requested operation - _Core->GetPlayer(m_ID).mAuthority = level; + Core::Get().GetPlayer(m_ID).mAuthority = level; } // ------------------------------------------------------------------------------------------------ -CSStr CPlayer::GetMessagePrefix(Uint32 index) const +const String & CPlayer::GetMessagePrefix(Uint32 index) const { // Perform a range check on the specified prefix index if (index >= SQMOD_PLAYER_MSG_PREFIXES) @@ -1152,11 +1150,11 @@ CSStr CPlayer::GetMessagePrefix(Uint32 index) const // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetPlayer(m_ID).mPrefixes[index].c_str(); + return mMessagePrefixes[index]; } // ------------------------------------------------------------------------------------------------ -void CPlayer::SetMessagePrefix(Uint32 index, CSStr prefix) const +void CPlayer::SetMessagePrefix(Uint32 index, CSStr prefix) { // Perform a range check on the specified prefix index if (index >= SQMOD_PLAYER_MSG_PREFIXES) @@ -1166,115 +1164,343 @@ void CPlayer::SetMessagePrefix(Uint32 index, CSStr prefix) const // Validate the managed identifier Validate(); // Perform the requested operation - _Core->GetPlayer(m_ID).mPrefixes[index].assign(prefix); + mMessagePrefixes[index].assign(prefix); } // ------------------------------------------------------------------------------------------------ -Uint32 CPlayer::GetMessageColor() const +Int32 CPlayer::GetLastWeapon() const { // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetPlayer(m_ID).mMessageColor; + return Core::Get().GetPlayer(m_ID).mLastWeapon; } // ------------------------------------------------------------------------------------------------ -void CPlayer::SetMessageColor(Uint32 color) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Core->GetPlayer(m_ID).mMessageColor = color; -} - -// ------------------------------------------------------------------------------------------------ -Int32 CPlayer::GetAnnounceStyle() const +Float32 CPlayer::GetLastHealth() const { // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetPlayer(m_ID).mAnnounceStyle; + return Core::Get().GetPlayer(m_ID).mLastHealth; } // ------------------------------------------------------------------------------------------------ -void CPlayer::SetAnnounceStyle(Int32 style) const +Float32 CPlayer::GetLastArmour() const +{ + // Validate the managed identifier + Validate(); + // Return the requested information + return Core::Get().GetPlayer(m_ID).mLastArmour; +} + +// ------------------------------------------------------------------------------------------------ +Float32 CPlayer::GetLastHeading() const +{ + // Validate the managed identifier + Validate(); + // Return the requested information + return Core::Get().GetPlayer(m_ID).mLastHeading; +} + +// ------------------------------------------------------------------------------------------------ +const Vector3 & CPlayer::GetLastPosition() const +{ + // Validate the managed identifier + Validate(); + // Return the requested information + return Core::Get().GetPlayer(m_ID).mLastPosition; +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::StartStream() +{ + // Validate the managed identifier + Validate(); + // Initialize the stream buffer + m_Buffer.Adjust(mBufferInitSize); + m_Buffer.Move(0); +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::StartStream(Uint32 size) +{ + // Validate the managed identifier + Validate(); + // Initialize the stream buffer + m_Buffer.Adjust(size); + m_Buffer.Move(0); +} + +// ------------------------------------------------------------------------------------------------ +Int32 CPlayer::GetBufferCursor() const +{ + return m_Buffer.Position(); +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::SetBufferCursor(Int32 pos) { // Validate the managed identifier Validate(); // Perform the requested operation - _Core->GetPlayer(m_ID).mAnnounceStyle = style; + m_Buffer.Move(pos); } // ------------------------------------------------------------------------------------------------ -Float32 CPlayer::GetPosX() const +void CPlayer::StreamByte(SQInteger val) { // Validate the managed identifier Validate(); - // Clear previous position information, if any + // Perform the requested operation + m_Buffer.Push< Uint8 >(ConvTo< Uint8 >::From(val)); +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::StreamShort(SQInteger val) +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + m_Buffer.Push< Int16 >(ConvTo< Int16 >::From(val)); +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::StreamInt(SQInteger val) +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + m_Buffer.Push< Int32 >(ConvTo< Int32 >::From(val)); +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::StreamFloat(SQFloat val) +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + m_Buffer.Push< Float32 >(ConvTo< Float32 >::From(val)); +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::StreamString(CSStr val) +{ + // Validate the managed identifier + Validate(); + // Is the given string value even valid? + if (!val) + { + STHROWF("Invalid string argument: null"); + } + // Calculate the string length + Uint16 length = ConvTo< Uint16 >::From(std::strlen(val)); + // Change the size endianness to big endian + Uint16 size = ((length >> 8) & 0xFF) | ((length & 0xFF) << 8); + // Write the size and then the string contents + m_Buffer.Push< Uint16 >(size); + m_Buffer.AppendS(val, length); +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::StreamRawString(CSStr val) +{ + // Validate the managed identifier + Validate(); + // Is the given string value even valid? + if (!val) + { + STHROWF("Invalid string argument: null"); + } + // Calculate the string length + Uint16 length = ConvTo< Uint16 >::From(std::strlen(val)); + // Write the the string contents + m_Buffer.AppendS(val, length); +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::FlushStream(bool reset) +{ + // Validate the managed identifier + Validate(); + // Do we even have what to send? + if (!m_Buffer) + { + STHROWF("Cannot send uninitialized stream buffer"); + } + else if (!m_Buffer.Position()) + { + STHROWF("Cannot send empty stream buffer"); + } + // Attempt to send the stream buffer contents + const vcmpError result = _Func->SendClientScriptData(m_ID, m_Buffer.Data(), m_Buffer.Position()); + // Should we reset the buffer cursor? + if (reset) + { + m_Buffer.Move(0); + } + // Check for errors + if (result == vcmpErrorTooLargeInput) + { + STHROWF("Stream buffer is too big"); + } +} + +// ------------------------------------------------------------------------------------------------ +Uint32 CPlayer::GetBufferCapacity() const +{ + return m_Buffer.Capacity(); +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::SendBuffer(const BufferWrapper & buffer) const +{ + // Validate the managed identifier + Validate(); + // Validate the specified buffer + buffer.ValidateDeeper(); + // Validate the buffer cursor + if (!buffer.GetRef()->Position()) + { + STHROWF("Cannot send empty stream buffer"); + } + // Attempt to send the stream buffer contents + const vcmpError result = _Func->SendClientScriptData(m_ID, buffer.GetRef()->Data(), + buffer.GetRef()->Position()); + // Check for errors + if (result == vcmpErrorTooLargeInput) + { + STHROWF("Stream buffer is too big"); + } +} + +// ------------------------------------------------------------------------------------------------ +Float32 CPlayer::GetPositionX() const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any s_Vector3.x = 0; // Query the server for the requested component value - _Func->GetPlayerPos(m_ID, &s_Vector3.x, NULL, NULL); + _Func->GetPlayerPosition(m_ID, &s_Vector3.x, nullptr, nullptr); // Return the requested information return s_Vector3.x; } // ------------------------------------------------------------------------------------------------ -Float32 CPlayer::GetPosY() const +Float32 CPlayer::GetPositionY() const { // Validate the managed identifier Validate(); - // Clear previous position information, if any + // Clear previous information, if any s_Vector3.y = 0; // Query the server for the requested component value - _Func->GetPlayerPos(m_ID, NULL, &s_Vector3.y, NULL); + _Func->GetPlayerPosition(m_ID, nullptr, &s_Vector3.y, nullptr); // Return the requested information return s_Vector3.y; } // ------------------------------------------------------------------------------------------------ -Float32 CPlayer::GetPosZ() const +Float32 CPlayer::GetPositionZ() const { // Validate the managed identifier Validate(); - // Clear previous position information, if any + // Clear previous information, if any s_Vector3.z = 0; // Query the server for the requested component value - _Func->GetPlayerPos(m_ID, NULL, NULL, &s_Vector3.z); + _Func->GetPlayerPosition(m_ID, nullptr, nullptr, &s_Vector3.z); // Return the requested information return s_Vector3.z; } // ------------------------------------------------------------------------------------------------ -void CPlayer::SetPosX(Float32 x) const +void CPlayer::SetPositionX(Float32 x) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetPlayerPos(m_ID, NULL, &s_Vector3.y, &s_Vector3.z); + _Func->GetPlayerPosition(m_ID, nullptr, &s_Vector3.y, &s_Vector3.z); // Perform the requested operation - _Func->SetPlayerPos(m_ID, x, s_Vector3.y, s_Vector3.z); + _Func->SetPlayerPosition(m_ID, x, s_Vector3.y, s_Vector3.z); } // ------------------------------------------------------------------------------------------------ -void CPlayer::SetPosY(Float32 y) const +void CPlayer::SetPositionY(Float32 y) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetPlayerPos(m_ID, &s_Vector3.x, NULL, &s_Vector3.z); + _Func->GetPlayerPosition(m_ID, &s_Vector3.x, nullptr, &s_Vector3.z); // Perform the requested operation - _Func->SetPlayerPos(m_ID, s_Vector3.x, y, s_Vector3.z); + _Func->SetPlayerPosition(m_ID, s_Vector3.x, y, s_Vector3.z); } // ------------------------------------------------------------------------------------------------ -void CPlayer::SetPosZ(Float32 z) const +void CPlayer::SetPositionZ(Float32 z) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetPlayerPos(m_ID, &s_Vector3.x, &s_Vector3.y, NULL); + _Func->GetPlayerPosition(m_ID, &s_Vector3.x, &s_Vector3.y, nullptr); // Perform the requested operation - _Func->SetPlayerPos(m_ID, s_Vector3.z, s_Vector3.y, z); + _Func->SetPlayerPosition(m_ID, s_Vector3.z, s_Vector3.y, z); +} + +// ------------------------------------------------------------------------------------------------ +Int32 CPlayer::GetColorR() const +{ + // Validate the managed identifier + Validate(); + // Return the requested information + return static_cast< Int32 >((_Func->GetPlayerColour(m_ID) >> 16) & 0xFF); +} + +// ------------------------------------------------------------------------------------------------ +Int32 CPlayer::GetColorG() const +{ + // Validate the managed identifier + Validate(); + // Return the requested information + return static_cast< Int32 >((_Func->GetPlayerColour(m_ID) >> 8) & 0xFF); +} + +// ------------------------------------------------------------------------------------------------ +Int32 CPlayer::GetColorB() const +{ + // Validate the managed identifier + Validate(); + // Return the requested information + return static_cast< Int32 >(_Func->GetPlayerColour(m_ID) & 0xFF); +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::SetColorR(Int32 r) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->SetPlayerColour(m_ID, (ConvTo< Uint8 >::From(r) << 16) | + (~(0xFF << 16) & _Func->GetPlayerColour(m_ID))); +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::SetColorG(Int32 g) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->SetPlayerColour(m_ID, (ConvTo< Uint8 >::From(g) << 8) | + (~(0xFF << 8) & _Func->GetPlayerColour(m_ID))); +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::SetColorB(Int32 g) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->SetPlayerColour(m_ID, (ConvTo< Uint8 >::From(g)) | + (~(0xFF) & _Func->GetPlayerColour(m_ID))); } // ------------------------------------------------------------------------------------------------ @@ -1316,32 +1542,23 @@ SQInteger CPlayer::Msg(HSQUIRRELVM vm) { return sq_throwerror(vm, "Invalid player reference"); } - // Do we have enough values to call the format function? - else if (top > 3) + // Attempt to generate the string value + StackStrF val(vm, 3); + // Have we failed to retrieve the string? + if (SQ_FAILED(val.mRes)) { - SStr msg = NULL; - SQInteger len = 0; - // Attempt to generate the specified string format - SQRESULT ret = sqstd_format(vm, 3, &len, &msg); - // Did the format failed? - if (SQ_FAILED(ret)) - { - return ret; // Propagate the exception - } - // Send the resulted message string - _Func->SendClientMessage(player->GetID(), color.GetRGBA(), "%s", msg); + return val.mRes; // Propagate the error! } - else + // Send the resulted message string + const vcmpError result = _Func->SendClientMessage(player->GetID(), color.GetRGBA(), + "%s%s%s", + player->mMessagePrefix.c_str(), + val.mPtr, + player->mMessagePostfix.c_str()); + // Check the result + if (result == vcmpErrorTooLargeInput) { - // Attempt to retrieve the value from the stack as a string - Var< CSStr > msg(vm, 3); - // See if the obtained value is a valid message - if (!msg.value) - { - return sq_throwerror(vm, "Unable to retrieve the message"); - } - // Send the resulted message string - _Func->SendClientMessage(player->GetID(), color.GetRGBA(), "%s", msg.value); + return sq_throwerror(vm, "Client message too big"); } // This function does not return a value return 0; @@ -1392,38 +1609,31 @@ SQInteger CPlayer::MsgP(HSQUIRRELVM vm) return sq_throwerror(vm, ToStrF("Prefix index is out of range: %u > %u", index, SQMOD_PLAYER_MSG_PREFIXES)); } - // Do we have enough values to call the format function? - else if (top > 3) + // Attempt to generate the string value + StackStrF val(vm, 3); + // Have we failed to retrieve the string? + if (SQ_FAILED(val.mRes)) { - SStr msg = NULL; - SQInteger len = 0; - // Attempt to generate the specified string format - SQRESULT ret = sqstd_format(vm, 3, &len, &msg); - // Did the format failed? - if (SQ_FAILED(ret)) - { - return ret; // Propagate the exception - } - // Retrieve the associated player structure - const auto & splayer = _Core->GetPlayer(player->GetID()); - // Send the resulted message string - _Func->SendClientMessage(player->GetID(), splayer.mMessageColor, "%s%s", - splayer.mPrefixes[index].c_str(), msg); + return val.mRes; // Propagate the error! + } + vcmpError result = vcmpErrorNone; + // Send the resulted message string + if (player->mLimitPrefixPostfixMessage) + { + result = _Func->SendClientMessage(player->GetID(), player->mMessageColor, "%s%s", + player->mMessagePrefixes[index].c_str(), val.mPtr); } else { - // Attempt to retrieve the value from the stack as a string - Var< CSStr > msg(vm, 3); - // See if the obtained value is a valid message - if (!msg.value) - { - return sq_throwerror(vm, "Unable to retrieve the message"); - } - // Retrieve the associated player structure - const auto & splayer = _Core->GetPlayer(player->GetID()); - // Send the resulted message string - _Func->SendClientMessage(player->GetID(), splayer.mMessageColor, "%s%s", - splayer.mPrefixes[index].c_str(), msg.value); + result = _Func->SendClientMessage(player->GetID(), player->mMessageColor, "%s%s%s%s", + player->mMessagePrefix.c_str(), + player->mMessagePrefixes[index].c_str(), val.mPtr, + player->mMessagePostfix.c_str()); + } + // Check the result + if (result == vcmpErrorTooLargeInput) + { + return sq_throwerror(vm, "Client message too big"); } // This function does not return a value return 0; @@ -1470,32 +1680,23 @@ SQInteger CPlayer::MsgEx(HSQUIRRELVM vm) { return sq_throwerror(vm, "Invalid player reference"); } - // Do we have enough values to call the format function? - else if (top > 5) + // Attempt to generate the string value + StackStrF val(vm, 5); + // Have we failed to retrieve the string? + if (SQ_FAILED(val.mRes)) { - SStr msg = NULL; - SQInteger len = 0; - // Attempt to generate the specified string format - SQRESULT ret = sqstd_format(vm, 5, &len, &msg); - // Did the format failed? - if (SQ_FAILED(ret)) - { - return ret; // Propagate the exception - } - // Send the resulted message string - _Func->SendClientMessage(player->GetID(), SQMOD_PACK_RGBA(r, g, b, 0), "%s", msg); + return val.mRes; // Propagate the error! } - else + // Send the resulted message string + const vcmpError result = _Func->SendClientMessage(player->GetID(), SQMOD_PACK_RGBA(r, g, b, 0), + "%s%s%s", + player->mMessagePrefix.c_str(), + val.mPtr, + player->mMessagePostfix.c_str()); + // Check the result + if (result == vcmpErrorTooLargeInput) { - // Attempt to retrieve the value from the stack as a string - Var< CSStr > msg(vm, 5); - // See if the obtained value is a valid message - if (!msg.value) - { - return sq_throwerror(vm, "Unable to retrieve the message"); - } - // Send the resulted message string - _Func->SendClientMessage(player->GetID(), SQMOD_PACK_RGBA(r, g, b, 0), "%s", msg.value); + return sq_throwerror(vm, "Client message too big"); } // This function does not return a value return 0; @@ -1532,34 +1733,23 @@ SQInteger CPlayer::Message(HSQUIRRELVM vm) { return sq_throwerror(vm, "Invalid player reference"); } - // Do we have enough values to call the format function? - else if (top > 2) + // Attempt to generate the string value + StackStrF val(vm, 2); + // Have we failed to retrieve the string? + if (SQ_FAILED(val.mRes)) { - SStr msg = NULL; - SQInteger len = 0; - // Attempt to generate the specified string format - SQRESULT ret = sqstd_format(vm, 2, &len, &msg); - // Did the format failed? - if (SQ_FAILED(ret)) - { - return ret; // Propagate the exception - } - // Send the resulted message string - _Func->SendClientMessage(player->GetID(), - _Core->GetPlayer(player->GetID()).mMessageColor, "%s", msg); + return val.mRes; // Propagate the error! } - else + // Send the resulted message string + const vcmpError result = _Func->SendClientMessage(player->GetID(), player->mMessageColor, + "%s%s%s", + player->mMessagePrefix.c_str(), + val.mPtr, + player->mMessagePostfix.c_str()); + // Check the result + if (result == vcmpErrorTooLargeInput) { - // Attempt to retrieve the value from the stack as a string - Var< CSStr > msg(vm, 2); - // See if the obtained value is a valid message - if (!msg.value) - { - return sq_throwerror(vm, "Unable to retrieve the message"); - } - // Send the resulted message string - _Func->SendClientMessage(player->GetID(), - _Core->GetPlayer(player->GetID()).mMessageColor, "%s", msg.value); + return sq_throwerror(vm, "Client message too big"); } // This function does not return a value return 0; @@ -1596,34 +1786,27 @@ SQInteger CPlayer::Announce(HSQUIRRELVM vm) { return sq_throwerror(vm, "Invalid player reference"); } - // Do we have enough values to call the format function? - else if (top > 2) + // Attempt to generate the string value + StackStrF val(vm, 2); + // Have we failed to retrieve the string? + if (SQ_FAILED(val.mRes)) { - SStr msg = NULL; - SQInteger len = 0; - // Attempt to generate the specified string format - SQRESULT ret = sqstd_format(vm, 2, &len, &msg); - // Did the format failed? - if (SQ_FAILED(ret)) - { - return ret; // Propagate the exception - } - // Send the resulted announcement string - _Func->SendGameMessage(player->GetID(), - _Core->GetPlayer(player->GetID()).mAnnounceStyle, "%s", msg); + return val.mRes; // Propagate the error! } - else + // Send the resulted announcement string + const vcmpError result = _Func->SendGameMessage(player->GetID(), player->mAnnounceStyle, + "%s%s%s", + player->mAnnouncePrefix.c_str(), + val.mPtr, + player->mAnnouncePostfix.c_str()); + // Validate the result + if (result == vcmpErrorArgumentOutOfBounds) { - // Attempt to retrieve the value from the stack as a string - Var< CSStr > msg(vm, 2); - // See if the obtained value is a valid announcement - if (!msg.value) - { - return sq_throwerror(vm, "Unable to retrieve the announcement"); - } - // Send the resulted announcement string - _Func->SendGameMessage(player->GetID(), - _Core->GetPlayer(player->GetID()).mAnnounceStyle, "%s", msg.value); + return sq_throwerror(vm, "Invalid announcement style"); + } + else if (result == vcmpErrorTooLargeInput) + { + return sq_throwerror(vm, "Game message too big"); } // This function does not return a value return 0; @@ -1668,32 +1851,26 @@ SQInteger CPlayer::AnnounceEx(HSQUIRRELVM vm) { return sq_throwerror(vm, "Invalid player reference"); } - // Do we have enough values to call the format function? - else if (top > 3) + // Attempt to generate the string value + StackStrF val(vm, 3); + // Have we failed to retrieve the string? + if (SQ_FAILED(val.mRes)) { - SStr msg = NULL; - SQInteger len = 0; - // Attempt to generate the specified string format - SQRESULT ret = sqstd_format(vm, 3, &len, &msg); - // Did the format failed? - if (SQ_FAILED(ret)) - { - return ret; // Propagate the exception - } - // Send the resulted announcement string - _Func->SendGameMessage(player->GetID(), style, "%s", msg); + return val.mRes; // Propagate the error! } - else + // Send the resulted announcement string + const vcmpError result = _Func->SendGameMessage(player->GetID(), style, "%s%s%s", + player->mAnnouncePrefix.c_str(), + val.mPtr, + player->mAnnouncePostfix.c_str()); + // Validate the result + if (result == vcmpErrorArgumentOutOfBounds) { - // Attempt to retrieve the value from the stack as a string - Var< CSStr > msg(vm, 3); - // See if the obtained value is a valid announcement - if (!msg.value) - { - return sq_throwerror(vm, "Unable to retrieve the announcement"); - } - // Send the resulted announcement string - _Func->SendGameMessage(player->GetID(), style, "%s", msg.value); + return sq_throwerror(vm, "Invalid announcement style"); + } + else if (result == vcmpErrorTooLargeInput) + { + return sq_throwerror(vm, "Game message too big"); } // This function does not return a value return 0; @@ -1708,8 +1885,8 @@ static const Object & Player_FindByID(Int32 id) STHROWF("The specified player identifier is invalid: %d", id); } // Obtain the ends of the entity pool - Core::Players::const_iterator itr = _Core->GetPlayers().cbegin(); - Core::Players::const_iterator end = _Core->GetPlayers().cend(); + Core::Players::const_iterator itr = Core::Get().GetPlayers().cbegin(); + Core::Players::const_iterator end = Core::Get().GetPlayers().cend(); // Process each entity in the pool for (; itr != end; ++itr) { @@ -1732,8 +1909,8 @@ static const Object & Player_FindByTag(CSStr tag) STHROWF("The specified player tag is invalid: null/empty"); } // Obtain the ends of the entity pool - Core::Players::const_iterator itr = _Core->GetPlayers().cbegin(); - Core::Players::const_iterator end = _Core->GetPlayers().cend(); + Core::Players::const_iterator itr = Core::Get().GetPlayers().cbegin(); + Core::Players::const_iterator end = Core::Get().GetPlayers().cend(); // Process each entity in the pool for (; itr != end; ++itr) { @@ -1753,8 +1930,8 @@ static Array Player_FindActive() // Remember the initial stack size StackGuard sg; // Obtain the ends of the entity pool - Core::Players::const_iterator itr = _Core->GetPlayers().cbegin(); - Core::Players::const_iterator end = _Core->GetPlayers().cend(); + Core::Players::const_iterator itr = Core::Get().GetPlayers().cbegin(); + Core::Players::const_iterator end = Core::Get().GetPlayers().cend(); // Allocate an empty array on the stack sq_newarray(DefaultVM::Get(), 0); // Process each entity in the pool @@ -1776,6 +1953,37 @@ static Array Player_FindActive() return Var< Array >(DefaultVM::Get(), -1).value; } +// ------------------------------------------------------------------------------------------------ +static const Object & Player_FindAuto(Object & by) +{ + switch (by.GetType()) + { + case OT_INTEGER: + { + return Core::Get().GetPlayer(by.Cast< Int32 >()).mObj; + } break; + case OT_FLOAT: + { + return Core::Get().GetPlayer(std::round(by.Cast< Float32 >())).mObj; + } break; + case OT_STRING: + { + // Obtain the argument as a string + String str(by.Cast< String >()); + // Attempt to locate the player with this name + Int32 id = _Func->GetPlayerIdFromName(&str[0]); + // Was there a player with this name? + if (VALID_ENTITYEX(id, SQMOD_PLAYER_POOL)) + { + Core::Get().GetPlayer(id).mObj; + } + } break; + default: STHROWF("Unsupported search identifier"); + } + // Default to a null object + return NullObject(); +} + // ================================================================================================ void Register_CPlayer(HSQUIRRELVM vm) { @@ -1787,6 +1995,16 @@ void Register_CPlayer(HSQUIRRELVM vm) .Func(_SC("_tostring"), &CPlayer::ToString) // Static Values .SetStaticValue(_SC("MaxID"), CPlayer::Max) + // Member Variables + .Var(_SC("BufferInitSize"), &CPlayer::mBufferInitSize) + .Var(_SC("MessageColor"), &CPlayer::mMessageColor) + .Var(_SC("AnnounceStyle"), &CPlayer::mAnnounceStyle) + .Var(_SC("DefaultAmmo"), &CPlayer::mDefaultAmmo) + .Var(_SC("MessagePrefix"), &CPlayer::mMessagePrefix) + .Var(_SC("MessagePostfix"), &CPlayer::mMessagePostfix) + .Var(_SC("AnnouncePrefix"), &CPlayer::mAnnouncePrefix) + .Var(_SC("AnnouncePostfix"), &CPlayer::mAnnouncePostfix) + .Var(_SC("LimitPrefixPostfixMessage"), &CPlayer::mLimitPrefixPostfixMessage) // Core Properties .Prop(_SC("ID"), &CPlayer::GetID) .Prop(_SC("Tag"), &CPlayer::GetTag, &CPlayer::SetTag) @@ -1796,29 +2014,33 @@ void Register_CPlayer(HSQUIRRELVM vm) .Func(_SC("Bind"), &CPlayer::BindEvent) // Properties .Prop(_SC("Class"), &CPlayer::GetClass) + .Prop(_SC("Connected"), &CPlayer::IsConnected) .Prop(_SC("Admin"), &CPlayer::GetAdmin, &CPlayer::SetAdmin) .Prop(_SC("IP"), &CPlayer::GetIP) - .Prop(_SC("Connected"), &CPlayer::IsConnected) - .Prop(_SC("Spawned"), &CPlayer::IsSpawned) + .Prop(_SC("UID"), &CPlayer::GetUID) + .Prop(_SC("UID2"), &CPlayer::GetUID2) .Prop(_SC("Key"), &CPlayer::GetKey) - .Prop(_SC("World"), &CPlayer::GetWorld, &CPlayer::SetWorld) - .Prop(_SC("SecWorld"), &CPlayer::GetSecWorld, &CPlayer::SetSecWorld) - .Prop(_SC("UniqueWorld"), &CPlayer::GetUniqueWorld) - .Prop(_SC("State"), &CPlayer::GetState) - .Prop(_SC("Action"), &CPlayer::GetAction) .Prop(_SC("Name"), &CPlayer::GetName, &CPlayer::SetName) + .Prop(_SC("State"), &CPlayer::GetState) + .Prop(_SC("World"), &CPlayer::GetWorld, &CPlayer::SetWorld) + .Prop(_SC("SecWorld"), &CPlayer::GetSecondaryWorld, &CPlayer::SetSecondaryWorld) + .Prop(_SC("SecondaryWorld"), &CPlayer::GetSecondaryWorld, &CPlayer::SetSecondaryWorld) + .Prop(_SC("UniqueWorld"), &CPlayer::GetUniqueWorld) + .Prop(_SC("Class"), &CPlayer::GetClass) .Prop(_SC("Team"), &CPlayer::GetTeam, &CPlayer::SetTeam) .Prop(_SC("Skin"), &CPlayer::GetSkin, &CPlayer::SetSkin) .Prop(_SC("Color"), &CPlayer::GetColor, &CPlayer::SetColor) + .Prop(_SC("Colour"), &CPlayer::GetColor, &CPlayer::SetColor) + .Prop(_SC("Spawned"), &CPlayer::IsSpawned) + .Prop(_SC("Typing"), &CPlayer::IsTyping) .Prop(_SC("Money"), &CPlayer::GetMoney, &CPlayer::SetMoney) .Prop(_SC("Score"), &CPlayer::GetScore, &CPlayer::SetScore) + .Prop(_SC("WantedLevel"), &CPlayer::GetWantedLevel, &CPlayer::SetWantedLevel) .Prop(_SC("Ping"), &CPlayer::GetPing) .Prop(_SC("FPS"), &CPlayer::GetFPS) - .Prop(_SC("Typing"), &CPlayer::IsTyping) - .Prop(_SC("UID"), &CPlayer::GetUID) - .Prop(_SC("UID2"), &CPlayer::GetUID2) .Prop(_SC("Health"), &CPlayer::GetHealth, &CPlayer::SetHealth) .Prop(_SC("Armor"), &CPlayer::GetArmor, &CPlayer::SetArmor) + .Prop(_SC("Armour"), &CPlayer::GetArmor, &CPlayer::SetArmor) .Prop(_SC("Immunity"), &CPlayer::GetImmunity, &CPlayer::SetImmunity) .Prop(_SC("Pos"), &CPlayer::GetPosition, &CPlayer::SetPosition) .Prop(_SC("Position"), &CPlayer::GetPosition, &CPlayer::SetPosition) @@ -1826,64 +2048,97 @@ void Register_CPlayer(HSQUIRRELVM vm) .Prop(_SC("Angle"), &CPlayer::GetHeading, &CPlayer::SetHeading) .Prop(_SC("Heading"), &CPlayer::GetHeading, &CPlayer::SetHeading) .Prop(_SC("Alpha"), &CPlayer::GetAlpha, &CPlayer::SetAlpha) + .Prop(_SC("AimPos"), &CPlayer::GetAimPosition) + .Prop(_SC("AimPosition"), &CPlayer::GetAimPosition) + .Prop(_SC("AimDir"), &CPlayer::GetAimDirection) + .Prop(_SC("AimDirection"), &CPlayer::GetAimDirection) + .Prop(_SC("Burning"), &CPlayer::IsBurning) + .Prop(_SC("Crouched"), &CPlayer::IsCrouched) + .Prop(_SC("Action"), &CPlayer::GetAction) + .Prop(_SC("GameKeys"), &CPlayer::GetGameKeys) .Prop(_SC("VehicleStatus"), &CPlayer::GetVehicleStatus) - .Prop(_SC("Slot"), &CPlayer::GetOccupiedSlot) + .Prop(_SC("VehicleSlot"), &CPlayer::GetVehicleSlot) .Prop(_SC("Vehicle"), &CPlayer::GetVehicle) .Prop(_SC("VehicleID"), &CPlayer::GetVehicleID) - .Prop(_SC("Controllable"), &CPlayer::GetControllable, &CPlayer::SetControllable) - .Prop(_SC("Driveby"), &CPlayer::GetDriveby, &CPlayer::SetDriveby) - .Prop(_SC("WhiteScanlines"), &CPlayer::GetWhiteScanlines, &CPlayer::SetWhiteScanlines) - .Prop(_SC("GreenScanlines"), &CPlayer::GetGreenScanlines, &CPlayer::SetGreenScanlines) - .Prop(_SC("Widescreen"), &CPlayer::GetWidescreen, &CPlayer::SetWidescreen) - .Prop(_SC("ShowMarkers"), &CPlayer::GetShowMarkers, &CPlayer::SetShowMarkers) - .Prop(_SC("AttackPriv"), &CPlayer::GetAttackPriv, &CPlayer::SetAttackPriv) - .Prop(_SC("HasMarker"), &CPlayer::GetHasMarker, &CPlayer::SetHasMarker) - .Prop(_SC("ChatTags"), &CPlayer::GetChatTags, &CPlayer::SetChatTags) - .Prop(_SC("DrunkEffects"), &CPlayer::GetDrunkEffects, &CPlayer::SetDrunkEffects) .Prop(_SC("Weapon"), &CPlayer::GetWeapon, &CPlayer::SetWeapon) + .Prop(_SC("Ammo"), &CPlayer::GetAmmo) + .Prop(_SC("WeaponSlot"), &CPlayer::GetWeaponSlot, &CPlayer::SetWeaponSlot) .Prop(_SC("CameraLocked"), &CPlayer::IsCameraLocked) - .Prop(_SC("WantedLevel"), &CPlayer::GetWantedLevel, &CPlayer::SetWantedLevel) .Prop(_SC("TouchedVehicle"), &CPlayer::StandingOnVehicle) .Prop(_SC("TouchedObject"), &CPlayer::StandingOnObject) .Prop(_SC("Away"), &CPlayer::IsAway) - .Prop(_SC("Spectating"), &CPlayer::GetSpectator) .Prop(_SC("Spec"), &CPlayer::GetSpectator, &CPlayer::SetSpectator) - .Prop(_SC("Crouched"), &CPlayer::IsCrouched) - .Prop(_SC("GameKeys"), &CPlayer::GetGameKeys) - .Prop(_SC("AimPos"), &CPlayer::GetAimPos) - .Prop(_SC("AimPosition"), &CPlayer::GetAimPos) - .Prop(_SC("AimDir"), &CPlayer::GetAimDir) - .Prop(_SC("AimDirection"), &CPlayer::GetAimDir) .Prop(_SC("Authority"), &CPlayer::GetAuthority, &CPlayer::SetAuthority) - .Prop(_SC("MessageColor"), &CPlayer::GetMessageColor, &CPlayer::SetMessageColor) - .Prop(_SC("AnnounceStyle"), &CPlayer::GetAnnounceStyle, &CPlayer::SetAnnounceStyle) - .Prop(_SC("X"), &CPlayer::GetPosX, &CPlayer::SetPosX) - .Prop(_SC("Y"), &CPlayer::GetPosY, &CPlayer::SetPosY) - .Prop(_SC("Z"), &CPlayer::GetPosZ, &CPlayer::SetPosZ) + .Prop(_SC("LastWeapon"), &CPlayer::GetLastWeapon) + .Prop(_SC("LastHealth"), &CPlayer::GetLastHealth) + .Prop(_SC("LastArmour"), &CPlayer::GetLastArmour) + .Prop(_SC("LastHeading"), &CPlayer::GetLastHeading) + .Prop(_SC("LastPosition"), &CPlayer::GetLastPosition) + .Prop(_SC("BufferCursor"), &CPlayer::GetBufferCursor, &CPlayer::SetBufferCursor) + .Prop(_SC("BufferCapacity"), &CPlayer::GetBufferCapacity) + .Prop(_SC("PosX"), &CPlayer::GetPositionX, &CPlayer::SetPositionX) + .Prop(_SC("PosY"), &CPlayer::GetPositionY, &CPlayer::SetPositionY) + .Prop(_SC("PosZ"), &CPlayer::GetPositionZ, &CPlayer::SetPositionZ) + .Prop(_SC("Red"), &CPlayer::GetColorR, &CPlayer::SetColorR) + .Prop(_SC("Green"), &CPlayer::GetColorG, &CPlayer::SetColorG) + .Prop(_SC("Blue"), &CPlayer::GetColorB, &CPlayer::SetColorB) // Member Methods .Func(_SC("StreamedFor"), &CPlayer::IsStreamedFor) .Func(_SC("Kick"), &CPlayer::Kick) .Func(_SC("Ban"), &CPlayer::Ban) + .Func(_SC("GetOption"), &CPlayer::GetOption) + .Func(_SC("SetOption"), &CPlayer::SetOption) + .Func(_SC("SetOptionEx"), &CPlayer::SetOptionEx) .Func(_SC("WorldCompatible"), &CPlayer::IsWorldCompatible) .Func(_SC("SetColor"), &CPlayer::SetColorEx) + .Func(_SC("SetColour"), &CPlayer::SetColorEx) .Func(_SC("Spawn"), &CPlayer::ForceSpawn) .Func(_SC("Select"), &CPlayer::ForceSelect) .Func(_SC("GiveMoney"), &CPlayer::GiveMoney) - .Func(_SC("SetPosition"), &CPlayer::SetPositionEx) .Func(_SC("SetPos"), &CPlayer::SetPositionEx) + .Func(_SC("SetPosition"), &CPlayer::SetPositionEx) .Func(_SC("SetSpeed"), &CPlayer::SetSpeedEx) - .Func(_SC("SetWeapon"), &CPlayer::SetWeapon) + .Func(_SC("Disembark"), &CPlayer::Disembark) + .Func(_SC("SetWeapon"), &CPlayer::SetWeaponEx) .Func(_SC("GiveWeapon"), &CPlayer::GiveWeapon) + .Func(_SC("WeaponAtSlot"), &CPlayer::GetWeaponAtSlot) + .Func(_SC("AmmoAtSlot"), &CPlayer::GetAmmoAtSlot) + .Func(_SC("RemoveWeapon"), &CPlayer::RemoveWeapon) .Func(_SC("StripWeapons"), &CPlayer::StripWeapons) .Func(_SC("RestoreCamera"), &CPlayer::RestoreCamera) .Func(_SC("SetAnim"), &CPlayer::SetAnimation) .Func(_SC("Animation"), &CPlayer::SetAnimation) + .Func(_SC("Spectating"), &CPlayer::GetSpectator) .Func(_SC("Spectate"), &CPlayer::SetSpectator) - .Func(_SC("Disembark"), &CPlayer::Disembark) .Func(_SC("Redirect"), &CPlayer::Redirect) .Func(_SC("GetMsgPrefix"), &CPlayer::GetMessagePrefix) .Func(_SC("SetMsgPrefix"), &CPlayer::SetMessagePrefix) - // Raw Methods + .Func(_SC("StreamByte"), &CPlayer::StreamByte) + .Func(_SC("StreamShort"), &CPlayer::StreamShort) + .Func(_SC("StreamInt"), &CPlayer::StreamInt) + .Func(_SC("StreamFloat"), &CPlayer::StreamFloat) + .Func(_SC("StreamString"), &CPlayer::StreamString) + .Func(_SC("StreamRawString"), &CPlayer::StreamRawString) + .Func(_SC("FlushStream"), &CPlayer::FlushStream) + .Func(_SC("SendBuffer"), &CPlayer::SendBuffer) + // Member Overloads + .Overload< void (CPlayer::*)(const Vector3 &) const > + (_SC("AddSpeed"), &CPlayer::AddSpeed) + .Overload< void (CPlayer::*)(Float32, Float32, Float32) const > + (_SC("AddSpeed"), &CPlayer::AddSpeedEx) + .Overload< bool (CPlayer::*)(CVehicle &) const > + (_SC("Embark"), &CPlayer::Embark) + .Overload< bool (CPlayer::*)(CVehicle &, SQInt32, bool, bool) const > + (_SC("Embark"), &CPlayer::Embark) + .Overload< void (CPlayer::*)(const Vector3 &, const Vector3 &) const > + (_SC("CameraPosition"), &CPlayer::SetCameraPosition) + .Overload< void (CPlayer::*)(Float32, Float32, Float32, Float32, Float32, Float32) const > + (_SC("CameraPosition"), &CPlayer::SetCameraPosition) + .Overload< void (CPlayer::*)(void) > + (_SC("StartStream"), &CPlayer::StartStream) + .Overload< void (CPlayer::*)(Uint32) > + (_SC("StartStream"), &CPlayer::StartStream) + // Raw Squirrel Methods .SquirrelFunc(_SC("Msg"), &CPlayer::Msg) .SquirrelFunc(_SC("MsgP"), &CPlayer::MsgP) .SquirrelFunc(_SC("MsgEx"), &CPlayer::MsgEx) @@ -1892,20 +2147,8 @@ void Register_CPlayer(HSQUIRRELVM vm) .SquirrelFunc(_SC("AnnounceEx"), &CPlayer::AnnounceEx) .SquirrelFunc(_SC("Text"), &CPlayer::Announce) .SquirrelFunc(_SC("TextEx"), &CPlayer::AnnounceEx) - // Member Overloads - .Overload< void (CPlayer::*)(const Vector3 &) const > - (_SC("AddSpeed"), &CPlayer::AddSpeed) - .Overload< void (CPlayer::*)(Float32, Float32, Float32) const > - (_SC("AddSpeed"), &CPlayer::AddSpeedEx) - .Overload< void (CPlayer::*)(const Vector3 &, const Vector3 &) const > - (_SC("CameraPosition"), &CPlayer::SetCameraPosition) - .Overload< void (CPlayer::*)(Float32, Float32, Float32, Float32, Float32, Float32) const > - (_SC("CameraPosition"), &CPlayer::SetCameraPosition) - .Overload< void (CPlayer::*)(CVehicle &) const > - (_SC("Embark"), &CPlayer::Embark) - .Overload< void (CPlayer::*)(CVehicle &, SQInt32, bool, bool) const > - (_SC("Embark"), &CPlayer::Embark) // Static Functions + .StaticFunc(_SC("Find"), &Player_FindAuto) .StaticFunc(_SC("FindByID"), &Player_FindByID) .StaticFunc(_SC("FindByTag"), &Player_FindByTag) .StaticFunc(_SC("FindActive"), &Player_FindActive) diff --git a/source/Entity/Player.hpp b/source/Entity/Player.hpp index da2952bc..371324f6 100644 --- a/source/Entity/Player.hpp +++ b/source/Entity/Player.hpp @@ -3,10 +3,19 @@ // ------------------------------------------------------------------------------------------------ #include "Base/Shared.hpp" +#include "Base/Buffer.hpp" // ------------------------------------------------------------------------------------------------ namespace SqMod { +/* ------------------------------------------------------------------------------------------------ + * Circular locks employed by the player manager. +*/ +enum PlayerCircularLocks +{ + PCL_EMIT_PLAYER_OPTION = (1 << 0) +}; + /* ------------------------------------------------------------------------------------------------ * Manages a single player entity. */ @@ -39,6 +48,16 @@ private: */ Object m_Data; + /* -------------------------------------------------------------------------------------------- + * Buffer used to generate client data. + */ + Buffer m_Buffer; + + /* -------------------------------------------------------------------------------------------- + * Prevent events from triggering themselves. + */ + Uint32 m_CircularLocks; + /* -------------------------------------------------------------------------------------------- * Base constructor. */ @@ -46,11 +65,64 @@ private: public: + // -------------------------------------------------------------------------------------------- + typedef String MsgPrefix[SQMOD_PLAYER_MSG_PREFIXES]; + /* -------------------------------------------------------------------------------------------- * Maximum possible number that could represent an identifier for this entity type. */ static const Int32 Max; + /* -------------------------------------------------------------------------------------------- + * The initial size of the allocated memory buffer when starting a new stream. + */ + Uint32 mBufferInitSize; + + /* -------------------------------------------------------------------------------------------- + * Default color to use in client messages. + */ + Uint32 mMessageColor; + + /* -------------------------------------------------------------------------------------------- + * Default style to use in client announcements. + */ + Int32 mAnnounceStyle; + + /* -------------------------------------------------------------------------------------------- + * Default ammo to give to the managed player when not specifying any. + */ + Int32 mDefaultAmmo; + + /* -------------------------------------------------------------------------------------------- + * Set of strings to add before a client message automatically. + */ + String mMessagePrefix; + + /* -------------------------------------------------------------------------------------------- + * Set of strings to add before a client message automatically. + */ + String mMessagePostfix; + + /* -------------------------------------------------------------------------------------------- + * Set of strings to add before a client announcement automatically. + */ + String mAnnouncePrefix; + + /* -------------------------------------------------------------------------------------------- + * Set of strings to add before a client announcement automatically. + */ + String mAnnouncePostfix; + + /* -------------------------------------------------------------------------------------------- + * Set of strings to add before a client message automatically. + */ + MsgPrefix mMessagePrefixes; + + /* -------------------------------------------------------------------------------------------- + * Don't include the auto message prefix/postfix in already prefixed messages. + */ + bool mLimitPrefixPostfixMessage; + /* -------------------------------------------------------------------------------------------- * Copy constructor. (disabled) */ @@ -143,16 +215,16 @@ public: */ void BindEvent(Int32 evid, Object & env, Function & func) const; + /* -------------------------------------------------------------------------------------------- + * See whether the managed player entity is connected. + */ + bool IsConnected() const; + /* -------------------------------------------------------------------------------------------- * See if the managed player entity is streamed for the specified player. */ bool IsStreamedFor(CPlayer & player) const; - /* -------------------------------------------------------------------------------------------- - * Retrieve the class of the managed player entity. - */ - Int32 GetClass() const; - /* -------------------------------------------------------------------------------------------- * See whether the managed player entity has administrator privileges. */ @@ -168,6 +240,16 @@ public: */ CSStr GetIP() const; + /* -------------------------------------------------------------------------------------------- + * Retrieve the unique user identifier of the managed player entity. + */ + CSStr GetUID() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the unique user identifier version 2 of the managed player entity. + */ + CSStr GetUID2() const; + /* -------------------------------------------------------------------------------------------- * Kick the managed player entity from the server. */ @@ -178,21 +260,41 @@ public: */ void Ban() const; - /* -------------------------------------------------------------------------------------------- - * See whether the managed player entity is connected. - */ - bool IsConnected() const; - - /* -------------------------------------------------------------------------------------------- - * See whether the managed player entity is spawned. - */ - bool IsSpawned() const; - /* -------------------------------------------------------------------------------------------- * Retrieve the key of the managed player entity. */ Uint32 GetKey() const; + /* -------------------------------------------------------------------------------------------- + * Retrieve the nick name of the managed player entity. + */ + CSStr GetName() const; + + /* -------------------------------------------------------------------------------------------- + * Modify the nick name of the managed player entity. + */ + void SetName(CSStr name) const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the current state of the managed player entity. + */ + Int32 GetState() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the current option value of the managed player entity. + */ + Int32 GetOption(Int32 option_id) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the current option value of the managed player entity. + */ + void SetOption(Int32 option_id, bool toggle); + + /* -------------------------------------------------------------------------------------------- + * Modify the current option value of the managed player entity. + */ + void SetOptionEx(Int32 option_id, bool toggle, Int32 header, Object & payload); + /* -------------------------------------------------------------------------------------------- * Retrieve the world in which the managed player entity exists. */ @@ -206,12 +308,12 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the secondary world of the managed player entity. */ - Int32 GetSecWorld() const; + Int32 GetSecondaryWorld() const; /* -------------------------------------------------------------------------------------------- * Modify the secondary world of the managed player entity. */ - void SetSecWorld(Int32 world) const; + void SetSecondaryWorld(Int32 world) const; /* -------------------------------------------------------------------------------------------- * Retrieve the unique world of the managed player entity. @@ -224,14 +326,9 @@ public: bool IsWorldCompatible(Int32 world) const; /* -------------------------------------------------------------------------------------------- - * Retrieve the nick name of the managed player entity. + * Retrieve the class of the managed player entity. */ - CSStr GetName() const; - - /* -------------------------------------------------------------------------------------------- - * Modify the nick name of the managed player entity. - */ - void SetName(CSStr name) const; + Int32 GetClass() const; /* -------------------------------------------------------------------------------------------- * Retrieve the team of the managed player entity. @@ -268,6 +365,11 @@ public: */ void SetColorEx(Uint8 r, Uint8 g, Uint8 b) const; + /* -------------------------------------------------------------------------------------------- + * See whether the managed player entity is spawned. + */ + bool IsSpawned() const; + /* -------------------------------------------------------------------------------------------- * Force the managed player entity to spawn in the game. */ @@ -278,6 +380,11 @@ public: */ void ForceSelect() const; + /* -------------------------------------------------------------------------------------------- + * See whether the managed player entity is typing. + */ + bool IsTyping() const; + /* -------------------------------------------------------------------------------------------- * Retrieve the money amount of the managed player entity. */ @@ -303,6 +410,16 @@ public: */ void SetScore(Int32 score) const; + /* -------------------------------------------------------------------------------------------- + * Retrieve the wanted level of the managed player entity. + */ + Int32 GetWantedLevel() const; + + /* -------------------------------------------------------------------------------------------- + * Modify the wanted level of the managed player entity. + */ + void SetWantedLevel(Int32 level) const; + /* -------------------------------------------------------------------------------------------- * Retrieve the connection latency of the managed player entity. */ @@ -313,21 +430,6 @@ public: */ Float32 GetFPS() const; - /* -------------------------------------------------------------------------------------------- - * See whether the managed player entity is typing. - */ - bool IsTyping() const; - - /* -------------------------------------------------------------------------------------------- - * Retrieve the unique user identifier of the managed player entity. - */ - CSStr GetUID() const; - - /* -------------------------------------------------------------------------------------------- - * Retrieve the unique user identifier version 2 of the managed player entity. - */ - CSStr GetUID2() const; - /* -------------------------------------------------------------------------------------------- * Retrieve the current health of the managed player entity. */ @@ -418,6 +520,51 @@ public: */ void SetAlpha(Int32 alpha, Int32 fade) const; + /* -------------------------------------------------------------------------------------------- + * Retrieve the aim position of the managed player entity. + */ + const Vector3 & GetAimPosition() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the aim direction of the managed player entity. + */ + const Vector3 & GetAimDirection() const; + + /* -------------------------------------------------------------------------------------------- + * See whether the managed player entity is burning. + */ + bool IsBurning() const; + + /* -------------------------------------------------------------------------------------------- + * See whether the managed player entity is crouched. + */ + bool IsCrouched() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the current action of the managed player entity. + */ + Int32 GetAction() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the game keys of the managed player entity. + */ + Int32 GetGameKeys() const; + + /* -------------------------------------------------------------------------------------------- + * Embark the managed player entity into the specified vehicle entity. + */ + bool Embark(CVehicle & vehicle) const; + + /* -------------------------------------------------------------------------------------------- + * Embark the managed player entity into the specified vehicle entity. + */ + bool Embark(CVehicle & vehicle, Int32 slot, bool allocate, bool warp) const; + + /* -------------------------------------------------------------------------------------------- + * Disembark the managed player entity from the currently embarked vehicle entity. + */ + void Disembark() const; + /* -------------------------------------------------------------------------------------------- * Retrieve the vehicle status of the managed player entity. */ @@ -426,7 +573,7 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the occupied vehicle slot by the managed player entity. */ - Int32 GetOccupiedSlot() const; + Int32 GetVehicleSlot() const; /* -------------------------------------------------------------------------------------------- * Retrieve the vehicle in which the managed player entity is embarked. @@ -438,106 +585,6 @@ public: */ Int32 GetVehicleID() const; - /* -------------------------------------------------------------------------------------------- - * See whether the managed player entity can be controlled. - */ - bool GetControllable() const; - - /* -------------------------------------------------------------------------------------------- - * Set whether the managed player entity can be controlled. - */ - void SetControllable(bool toggle) const; - - /* -------------------------------------------------------------------------------------------- - * See whether the managed player entity can driveby. - */ - bool GetDriveby() const; - - /* -------------------------------------------------------------------------------------------- - * Set whether the managed player entity can driveby. - */ - void SetDriveby(bool toggle) const; - - /* -------------------------------------------------------------------------------------------- - * See whether the managed player entity has white scanlines. - */ - bool GetWhiteScanlines() const; - - /* -------------------------------------------------------------------------------------------- - * Set whether the managed player entity has white scanlines. - */ - void SetWhiteScanlines(bool toggle) const; - - /* -------------------------------------------------------------------------------------------- - * See whether the managed player entity has green scanlines. - */ - bool GetGreenScanlines() const; - - /* -------------------------------------------------------------------------------------------- - * Set whether the managed player entity has green scanlines. - */ - void SetGreenScanlines(bool toggle) const; - - /* -------------------------------------------------------------------------------------------- - * See whether the managed player entity has widescreen. - */ - bool GetWidescreen() const; - - /* -------------------------------------------------------------------------------------------- - * Set whether the managed player entity has widescreen. - */ - void SetWidescreen(bool toggle) const; - - /* -------------------------------------------------------------------------------------------- - * See whether the managed player entity displays markers. - */ - bool GetShowMarkers() const; - - /* -------------------------------------------------------------------------------------------- - * Set whether the managed player entity displays markers. - */ - void SetShowMarkers(bool toggle) const; - - /* -------------------------------------------------------------------------------------------- - * See whether the managed player entity has attacking privileges. - */ - bool GetAttackPriv() const; - - /* -------------------------------------------------------------------------------------------- - * Set whether the managed player entity has attacking privileges. - */ - void SetAttackPriv(bool toggle) const; - - /* -------------------------------------------------------------------------------------------- - * See whether the managed player entity has markers. - */ - bool GetHasMarker() const; - - /* -------------------------------------------------------------------------------------------- - * Set whether the managed player entity has markers. - */ - void SetHasMarker(bool toggle) const; - - /* -------------------------------------------------------------------------------------------- - * See whether the managed player entity has chat tags. - */ - bool GetChatTags() const; - - /* -------------------------------------------------------------------------------------------- - * Set whether the managed player entity has chat tags. - */ - void SetChatTags(bool toggle) const; - - /* -------------------------------------------------------------------------------------------- - * See whether the managed player entity is under drunk effects. - */ - bool GetDrunkEffects() const; - - /* -------------------------------------------------------------------------------------------- - * Set whether the managed player entity is under drunk effects. - */ - void SetDrunkEffects(bool toggle) const; - /* -------------------------------------------------------------------------------------------- * Retrieve the weapon identifier of the managed player entity. */ @@ -546,13 +593,48 @@ public: /* -------------------------------------------------------------------------------------------- * Modify the weapon of the managed player entity. */ - void SetWeapon(Int32 wep, Int32 ammo) const; + void SetWeapon(Int32 wep) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the weapon of the managed player entity. + */ + void SetWeaponEx(Int32 wep, Int32 ammo) const; /* -------------------------------------------------------------------------------------------- * Give a weapon of the managed player entity. */ void GiveWeapon(Int32 wep, Int32 ammo) const; + /* -------------------------------------------------------------------------------------------- + * Retrieve the active weapon ammo of the managed player entity. + */ + Int32 GetAmmo() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the weapon slot of the managed player entity. + */ + Int32 GetWeaponSlot() const; + + /* -------------------------------------------------------------------------------------------- + * Modify the weapon slot of the managed player entity. + */ + void SetWeaponSlot(Int32 slot) const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the weapon identifier at the specified slot for the managed player entity. + */ + Int32 GetWeaponAtSlot(Int32 slot) const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the ammo from the weapon at the specified slot for the managed player entity. + */ + Int32 GetAmmoAtSlot(Int32 slot) const; + + /* -------------------------------------------------------------------------------------------- + * Remove a certain weapon from the managed player entity. + */ + void RemoveWeapon(Int32 wep) const; + /* -------------------------------------------------------------------------------------------- * Strip the managed player entity of all weapons. */ @@ -583,16 +665,6 @@ public: */ void SetAnimation(Int32 group, Int32 anim) const; - /* -------------------------------------------------------------------------------------------- - * Retrieve the wanted level of the managed player entity. - */ - Int32 GetWantedLevel() const; - - /* -------------------------------------------------------------------------------------------- - * Modify the wanted level of the managed player entity. - */ - void SetWantedLevel(Int32 level) const; - /* -------------------------------------------------------------------------------------------- * Retrieve the vehicle that the managed player entity is standing on. */ @@ -618,60 +690,10 @@ public: */ void SetSpectator(CPlayer & target) const; - /* -------------------------------------------------------------------------------------------- - * See whether the managed player entity is burning. - */ - bool IsBurning() const; - - /* -------------------------------------------------------------------------------------------- - * See whether the managed player entity is crouched. - */ - bool IsCrouched() const; - - /* -------------------------------------------------------------------------------------------- - * Retrieve the current state of the managed player entity. - */ - Int32 GetState() const; - - /* -------------------------------------------------------------------------------------------- - * Retrieve the current action of the managed player entity. - */ - Int32 GetAction() const; - - /* -------------------------------------------------------------------------------------------- - * Retrieve the game keys of the managed player entity. - */ - Int32 GetGameKeys() const; - - /* -------------------------------------------------------------------------------------------- - * Retrieve the aim position of the managed player entity. - */ - const Vector3 & GetAimPos() const; - - /* -------------------------------------------------------------------------------------------- - * Retrieve the aim direction of the managed player entity. - */ - const Vector3 & GetAimDir() const; - - /* -------------------------------------------------------------------------------------------- - * Embark the managed player entity into the specified vehicle entity. - */ - void Embark(CVehicle & vehicle) const; - - /* -------------------------------------------------------------------------------------------- - * Embark the managed player entity into the specified vehicle entity. - */ - void Embark(CVehicle & vehicle, Int32 slot, bool allocate, bool warp) const; - - /* -------------------------------------------------------------------------------------------- - * Disembark the managed player entity from the currently embarked vehicle entity. - */ - void Disembark() const; - /* -------------------------------------------------------------------------------------------- * Redirect the managed player entity to the specified server. */ - bool Redirect(CSStr ip, Uint32 port, CSStr nick, CSStr pass, CSStr user); + void Redirect(CSStr ip, Uint32 port, CSStr nick, CSStr server_pass, CSStr user_pass); /* -------------------------------------------------------------------------------------------- * Retrieve the authority level of the managed player entity. @@ -686,61 +708,162 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the message prefix at the specified index for the managed player entity. */ - CSStr GetMessagePrefix(Uint32 index) const; + const String & GetMessagePrefix(Uint32 index) const; /* -------------------------------------------------------------------------------------------- * Modify the message prefix at the specified index for the managed player entity. */ - void SetMessagePrefix(Uint32 index, CSStr prefix) const; - /* -------------------------------------------------------------------------------------------- - * Retrieve the message color for the managed player entity. - */ - Uint32 GetMessageColor() const; + void SetMessagePrefix(Uint32 index, CSStr prefix); /* -------------------------------------------------------------------------------------------- - * Modify the message color for the managed player entity. + * Retrieve the last known weapon for the managed player entity. */ - void SetMessageColor(Uint32 color) const; + Int32 GetLastWeapon() const; /* -------------------------------------------------------------------------------------------- - * Retrieve the announcement style for the managed player entity. + * Retrieve the last known health for the managed player entity. */ - Int32 GetAnnounceStyle() const; + Float32 GetLastHealth() const; /* -------------------------------------------------------------------------------------------- - * Modify the announcement style for the managed player entity. + * Retrieve the last known armour for the managed player entity. */ - void SetAnnounceStyle(Int32 style) const; + Float32 GetLastArmour() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the last known heading for the managed player entity. + */ + Float32 GetLastHeading() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the last known position for the managed player entity. + */ + const Vector3 & GetLastPosition() const; + + /* -------------------------------------------------------------------------------------------- + * Start a new stream with the default size. + */ + void StartStream(); + + /* -------------------------------------------------------------------------------------------- + * Start a new stream with a custom size. + */ + void StartStream(Uint32 size); + + /* -------------------------------------------------------------------------------------------- + * Retrieve the current cursor position of the stream buffer. + */ + Int32 GetBufferCursor() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the current cursor position of the stream buffer. + */ + void SetBufferCursor(Int32 pos); + + /* -------------------------------------------------------------------------------------------- + * Write a 8bit byte to the stream buffer. + */ + void StreamByte(SQInteger val); + + /* -------------------------------------------------------------------------------------------- + * Write a 16bit short to the stream buffer. + */ + void StreamShort(SQInteger val); + + /* -------------------------------------------------------------------------------------------- + * Write a 32bit integer to the stream buffer. + */ + void StreamInt(SQInteger val); + + /* -------------------------------------------------------------------------------------------- + * Write a 32bit float to the stream buffer. + */ + void StreamFloat(SQFloat val); + + /* -------------------------------------------------------------------------------------------- + * Write a string to the stream buffer. + */ + void StreamString(CSStr val); + + /* -------------------------------------------------------------------------------------------- + * Write a raw string to the stream buffer. + */ + void StreamRawString(CSStr val); + + /* -------------------------------------------------------------------------------------------- + * Send the data in the stream buffer to the client. + */ + void FlushStream(bool reset); + + /* -------------------------------------------------------------------------------------------- + * Retrieve the total capacity of the buffer stream in bytes. + */ + Uint32 GetBufferCapacity() const; + + /* -------------------------------------------------------------------------------------------- + * Send the specified buffer contents to the managed player entity. + */ + void SendBuffer(const BufferWrapper & buffer) const; /* -------------------------------------------------------------------------------------------- * Retrieve the position on the x axis of the managed player entity. */ - Float32 GetPosX() const; + Float32 GetPositionX() const; /* -------------------------------------------------------------------------------------------- * Retrieve the position on the y axis of the managed player entity. */ - Float32 GetPosY() const; + Float32 GetPositionY() const; /* -------------------------------------------------------------------------------------------- * Retrieve the position on the z axis of the managed player entity. */ - Float32 GetPosZ() const; + Float32 GetPositionZ() const; /* -------------------------------------------------------------------------------------------- * Modify the position on the x axis of the managed player entity. */ - void SetPosX(Float32 x) const; + void SetPositionX(Float32 x) const; /* -------------------------------------------------------------------------------------------- * Modify the position on the y axis of the managed player entity. */ - void SetPosY(Float32 y) const; + void SetPositionY(Float32 y) const; /* -------------------------------------------------------------------------------------------- * Modify the position on the z axis of the managed player entity. */ - void SetPosZ(Float32 z) const; + void SetPositionZ(Float32 z) const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the red color of the managed player entity. + */ + Int32 GetColorR() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the green color of the managed player entity. + */ + Int32 GetColorG() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the blue color of the managed player entity. + */ + Int32 GetColorB() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the red color of the managed player entity. + */ + void SetColorR(Int32 r) const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the green color of the managed player entity. + */ + void SetColorG(Int32 g) const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the blue color of the managed player entity. + */ + void SetColorB(Int32 b) const; /* -------------------------------------------------------------------------------------------- * Send a formatted colored message to the managed player entity. diff --git a/source/Entity/Sprite.cpp b/source/Entity/Sprite.cpp deleted file mode 100644 index 14be71a4..00000000 --- a/source/Entity/Sprite.cpp +++ /dev/null @@ -1,656 +0,0 @@ -// ------------------------------------------------------------------------------------------------ -#include "Entity/Sprite.hpp" -#include "Entity/Player.hpp" -#include "Base/Vector2i.hpp" -#include "Base/Stack.hpp" -#include "Core.hpp" - -// ------------------------------------------------------------------------------------------------ -namespace SqMod { - -// ------------------------------------------------------------------------------------------------ -const Int32 CSprite::Max = SQMOD_SPRITE_POOL; - -// ------------------------------------------------------------------------------------------------ -SQInteger CSprite::Typename(HSQUIRRELVM vm) -{ - static SQChar name[] = _SC("SqSprite"); - sq_pushstring(vm, name, sizeof(name)); - return 1; -} - -// ------------------------------------------------------------------------------------------------ -CSprite::CSprite(Int32 id) - : m_ID(VALID_ENTITYGETEX(id, SQMOD_SPRITE_POOL)) - , m_Tag(ToStrF("%d", id)) -{ - /* ... */ -} - -// ------------------------------------------------------------------------------------------------ -CSprite::~CSprite() -{ - /* ... */ -} - -// ------------------------------------------------------------------------------------------------ -Int32 CSprite::Cmp(const CSprite & o) const -{ - if (m_ID == o.m_ID) - return 0; - else if (m_ID > o.m_ID) - return 1; - else - return -1; -} - -// ------------------------------------------------------------------------------------------------ -const String & CSprite::ToString() const -{ - return m_Tag; -} - -// ------------------------------------------------------------------------------------------------ -const String & CSprite::GetTag() const -{ - return m_Tag; -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::SetTag(CSStr tag) -{ - m_Tag.assign(tag); -} - -// ------------------------------------------------------------------------------------------------ -Object & CSprite::GetData() -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return m_Data; -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::SetData(Object & data) -{ - // Validate the managed identifier - Validate(); - // Apply the specified value - m_Data = data; -} - -// ------------------------------------------------------------------------------------------------ -bool CSprite::Destroy(Int32 header, Object & payload) -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - return _Core->DelSprite(m_ID, header, payload); -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::BindEvent(Int32 evid, Object & env, Function & func) const -{ - // Validate the managed identifier - Validate(); - // Obtain the function instance called for this event - Function & event = _Core->GetSpriteEvent(m_ID, evid); - // Is the specified callback function null? - if (func.IsNull()) - { - event.Release(); // Then release the current callback - } - // Assign the specified environment and function - else - { - event = Function(env.GetVM(), env, func.GetFunc()); - } -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::ShowAll() const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->ShowSprite(m_ID, -1); -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::ShowFor(CPlayer & player) const -{ - // Is the specified player even valid? - if (!player.IsActive()) - { - STHROWF("Invalid player argument: null"); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->ShowSprite(m_ID, player.GetID()); - -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::ShowRange(Int32 first, Int32 last) const -{ - // Validate the specified range - if (first > last) - { - STHROWF("Invalid player range: %d > %d", first, last); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - for (; first <= last; ++first) - { - // Is the currently processed player even connected? - if (_Func->IsPlayerConnected(first)) - { - // Then show this textdraw on his client - _Func->ShowSprite(m_ID, first); - } - } -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::HideAll() const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->HideSprite(m_ID, -1); -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::HideFor(CPlayer & player) const -{ - // Is the specified player even valid? - if (!player.IsActive()) - { - STHROWF("Invalid player argument: null"); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->HideSprite(m_ID, player.GetID()); -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::HideRange(Int32 first, Int32 last) const -{ - // Validate the specified range - if (first > last) - { - STHROWF("Invalid player range: %d > %d", first, last); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - for (; first <= last; ++first) - { - // Is the currently processed player even connected? - if (_Func->IsPlayerConnected(first)) - { - // Then hide this textdraw on his client - _Func->HideSprite(m_ID, first); - } - } -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::SetPositionAll(const Vector2i & pos) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->MoveSprite(m_ID, -1, pos.x, pos.y); -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::SetPositionAllEx(Int32 x, Int32 y) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->MoveSprite(m_ID, -1, x, y); -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::SetPositionFor(CPlayer & player, const Vector2i & pos) const -{ - // Is the specified player even valid? - if (!player.IsActive()) - { - STHROWF("Invalid player argument: null"); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->MoveSprite(m_ID, player.GetID(), pos.x, pos.y); -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::SetPositionForEx(CPlayer & player, Int32 x, Int32 y) const -{ - // Is the specified player even valid? - if (!player.IsActive()) - { - STHROWF("Invalid player argument: null"); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->MoveSprite(m_ID, player.GetID(), x, y); -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::SetPositionRange(Int32 first, Int32 last, const Vector2i & pos) const -{ - // Validate the specified range - if (first > last) - { - STHROWF("Invalid player range: %d > %d", first, last); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - for (; first <= last; ++first) - { - // Is the currently processed player even connected? - if (_Func->IsPlayerConnected(first)) - { - // Then move this textdraw on his client - _Func->MoveSprite(m_ID, first, pos.x, pos.y); - } - } -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::SetCenterAll(const Vector2i & pos) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->SetSpriteCenter(m_ID, -1, pos.x, pos.y); -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::SetCenterAllEx(Int32 x, Int32 y) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->SetSpriteCenter(m_ID, -1, x, y); -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::SetCenterFor(CPlayer & player, const Vector2i & pos) const -{ - // Is the specified player even valid? - if (!player.IsActive()) - { - STHROWF("Invalid player argument: null"); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->SetSpriteCenter(m_ID, player.GetID(), pos.x, pos.y); -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::SetCenterForEx(CPlayer & player, Int32 x, Int32 y) const -{ - // Is the specified player even valid? - if (!player.IsActive()) - { - STHROWF("Invalid player argument: null"); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->SetSpriteCenter(m_ID, player.GetID(), x, y); -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::SetCenterRange(Int32 first, Int32 last, const Vector2i & pos) const -{ - // Validate the specified range - if (first > last) - { - STHROWF("Invalid player range: %d > %d", first, last); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - for (; first <= last; ++first) - { - // Is the currently processed player even connected? - if (_Func->IsPlayerConnected(first)) - { - // Then center this textdraw on his client - _Func->SetSpriteCenter(m_ID, first, pos.x, pos.y); - } - } -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::SetRotationAll(Float32 rot) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->RotateSprite(m_ID, -1, rot); -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::SetRotationFor(CPlayer & player, Float32 rot) const -{ - // Is the specified player even valid? - if (!player.IsActive()) - { - STHROWF("Invalid player argument: null"); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->RotateSprite(m_ID, player.GetID(), rot); -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::SetRotationRange(Int32 first, Int32 last, Float32 rot) const -{ - // Validate the specified range - if (first > last) - { - STHROWF("Invalid player range: %d > %d", first, last); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - for (; first <= last; ++first) - { - // Is the currently processed player even connected? - if (_Func->IsPlayerConnected(first)) - { - // Then rotate this textdraw on his client - _Func->RotateSprite(m_ID, first, rot); - } - } -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::SetAlphaAll(Uint8 alpha) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->SetSpriteAlpha(m_ID, -1, alpha); -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::SetAlphaFor(CPlayer & player, Uint8 alpha) const -{ - // Is the specified player even valid? - if (!player.IsActive()) - { - STHROWF("Invalid player argument: null"); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->SetSpriteAlpha(m_ID, player.GetID(), alpha); -} - -// ------------------------------------------------------------------------------------------------ -void CSprite::SetAlphaRange(Int32 first, Int32 last, Uint8 alpha) const -{ - // Validate the specified range - if (first > last) - { - STHROWF("Invalid player range: %d > %d", first, last); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - for (; first <= last; ++first) - { - // Is the currently processed player even connected? - if (_Func->IsPlayerConnected(first)) - { - // Then colorize this textdraw on his client - _Func->SetSpriteAlpha(m_ID, first, alpha); - } - } -} - -// ------------------------------------------------------------------------------------------------ -const String & CSprite::GetFilePath() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Core->GetSprite(m_ID).mPath; -} - -// ------------------------------------------------------------------------------------------------ -static Object & Sprite_CreateEx(CSStr file, Int32 xp, Int32 yp, Int32 xr, Int32 yr, - Float32 angle, Int32 alpha, bool rel) -{ - return _Core->NewSprite(-1, file, xp, yp, xr, yr, angle, alpha, rel, - SQMOD_CREATE_DEFAULT, NullObject()); -} - -// ------------------------------------------------------------------------------------------------ -static Object & Sprite_CreateEx(CSStr file, Int32 xp, Int32 yp, Int32 xr, Int32 yr, - Float32 angle, Int32 alpha, bool rel, Int32 header, Object & payload) -{ - return _Core->NewSprite(-1, file, xp, yp, xr, yr, angle, alpha, rel, header, payload); -} - -// ------------------------------------------------------------------------------------------------ -static Object & Sprite_CreateEx(Int32 index, CSStr file, Int32 xp, Int32 yp, Int32 xr, Int32 yr, - Float32 angle, Int32 alpha, bool rel) -{ - return _Core->NewSprite(index, file, xp, yp, xr, yr, angle, alpha, rel, - SQMOD_CREATE_DEFAULT, NullObject()); -} - -// ------------------------------------------------------------------------------------------------ -static Object & Sprite_CreateEx(Int32 index, CSStr file, Int32 xp, Int32 yp, Int32 xr, Int32 yr, - Float32 angle, Int32 alpha, bool rel, Int32 header, Object & payload) -{ - return _Core->NewSprite(index, file, xp, yp, xr, yr, angle, alpha, rel, header, payload); -} - -// ------------------------------------------------------------------------------------------------ -static Object & Sprite_Create(CSStr file, const Vector2i & pos, const Vector2i & rot, - Float32 angle, Int32 alpha, bool rel) -{ - return _Core->NewSprite(-1, file, pos.x, pos.y, rot.x, rot.y, angle, alpha, rel, - SQMOD_CREATE_DEFAULT, NullObject()); -} - -// ------------------------------------------------------------------------------------------------ -static Object & Sprite_Create(CSStr file, const Vector2i & pos, const Vector2i & rot, - Float32 angle, Int32 alpha, bool rel, Int32 header, Object & payload) -{ - return _Core->NewSprite(-1, file, pos.x, pos.y, rot.x, rot.y, angle, alpha, rel, header, payload); -} - -// ------------------------------------------------------------------------------------------------ -static Object & Sprite_Create(Int32 index, CSStr file, const Vector2i & pos, const Vector2i & rot, - Float32 angle, Int32 alpha, bool rel) -{ - return _Core->NewSprite(index, file, pos.x, pos.y, rot.x, rot.y, angle, alpha, rel, - SQMOD_CREATE_DEFAULT, NullObject()); -} - -// ------------------------------------------------------------------------------------------------ -static Object & Sprite_Create(Int32 index, CSStr file, const Vector2i & pos, const Vector2i & rot, - Float32 angle, Int32 alpha, bool rel, Int32 header, Object & payload) -{ - return _Core->NewSprite(index, file, pos.x, pos.y, rot.x, rot.y, angle, alpha, rel, header, payload); -} - -// ------------------------------------------------------------------------------------------------ -static const Object & Sprite_FindByID(Int32 id) -{ - // Perform a range check on the specified identifier - if (INVALID_ENTITYEX(id, SQMOD_SPRITE_POOL)) - { - STHROWF("The specified sprite identifier is invalid: %d", id); - } - // Obtain the ends of the entity pool - Core::Sprites::const_iterator itr = _Core->GetSprites().cbegin(); - Core::Sprites::const_iterator end = _Core->GetSprites().cend(); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Does the identifier match the specified one? - if (itr->mID == id) - { - return itr->mObj; // Stop searching and return this entity - } - } - // Unable to locate a sprite matching the specified identifier - return NullObject(); -} - -// ------------------------------------------------------------------------------------------------ -static const Object & Sprite_FindByTag(CSStr tag) -{ - // Perform a validity check on the specified tag - if (!tag || *tag == '\0') - { - STHROWF("The specified sprite tag is invalid: null/empty"); - } - // Obtain the ends of the entity pool - Core::Sprites::const_iterator itr = _Core->GetSprites().cbegin(); - Core::Sprites::const_iterator end = _Core->GetSprites().cend(); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Does this entity even exist and does the tag match the specified one? - if (itr->mInst != nullptr && itr->mInst->GetTag().compare(tag) == 0) - { - return itr->mObj; // Stop searching and return this entity - } - } - // Unable to locate a sprite matching the specified tag - return NullObject(); -} - -// ------------------------------------------------------------------------------------------------ -static Array Sprite_FindActive() -{ - // Remember the initial stack size - StackGuard sg; - // Obtain the ends of the entity pool - Core::Sprites::const_iterator itr = _Core->GetSprites().cbegin(); - Core::Sprites::const_iterator end = _Core->GetSprites().cend(); - // Allocate an empty array on the stack - sq_newarray(DefaultVM::Get(), 0); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Is this entity instance active? - if (VALID_ENTITY(itr->mID)) - { - // Push the script object on the stack - sq_pushobject(DefaultVM::Get(), (HSQOBJECT &)((*itr).mObj)); - // Append the object at the back of the array - if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -1))) - { - STHROWF("Unable to append entity instance to the list"); - } - } - } - // Return the array at the top of the stack - return Var< Array >(DefaultVM::Get(), -1).value; -} - -// ================================================================================================ -void Register_CSprite(HSQUIRRELVM vm) -{ - RootTable(vm).Bind(_SC("SqSprite"), - Class< CSprite, NoConstructor< CSprite > >(vm, _SC("SqSprite")) - // Metamethods - .Func(_SC("_cmp"), &CSprite::Cmp) - .SquirrelFunc(_SC("_typename"), &CSprite::Typename) - .Func(_SC("_tostring"), &CSprite::ToString) - // Static Values - .SetStaticValue(_SC("MaxID"), CSprite::Max) - // Core Properties - .Prop(_SC("ID"), &CSprite::GetID) - .Prop(_SC("Tag"), &CSprite::GetTag, &CSprite::SetTag) - .Prop(_SC("Data"), &CSprite::GetData, &CSprite::SetData) - .Prop(_SC("Active"), &CSprite::IsActive) - // Core Methods - .Func(_SC("Bind"), &CSprite::BindEvent) - // Core Overloads - .Overload< bool (CSprite::*)(void) >(_SC("Destroy"), &CSprite::Destroy) - .Overload< bool (CSprite::*)(Int32) >(_SC("Destroy"), &CSprite::Destroy) - .Overload< bool (CSprite::*)(Int32, Object &) >(_SC("Destroy"), &CSprite::Destroy) - // Properties - .Prop(_SC("Path"), &CSprite::GetFilePath) - // Member Methods - .Func(_SC("ShowAll"), &CSprite::ShowAll) - .Func(_SC("ShowTo"), &CSprite::ShowFor) - .Func(_SC("ShowFor"), &CSprite::ShowFor) - .Func(_SC("ShowRange"), &CSprite::ShowRange) - .Func(_SC("HideAll"), &CSprite::HideAll) - .Func(_SC("HideFor"), &CSprite::HideFor) - .Func(_SC("HideFrom"), &CSprite::HideFor) - .Func(_SC("HideRange"), &CSprite::HideRange) - .Func(_SC("SetPositionRange"), &CSprite::SetPositionRange) - .Func(_SC("SetCenterRange"), &CSprite::SetCenterRange) - .Func(_SC("SetRotationAll"), &CSprite::SetRotationAll) - .Func(_SC("SetRotationFor"), &CSprite::SetRotationFor) - .Func(_SC("SetRotationRange"), &CSprite::SetRotationRange) - .Func(_SC("SetAlphaAll"), &CSprite::SetAlphaAll) - .Func(_SC("SetAlphaFor"), &CSprite::SetAlphaFor) - .Func(_SC("SetAlphaRange"), &CSprite::SetAlphaRange) - // Member Overloads - .Overload< void (CSprite::*)(const Vector2i &) const > - (_SC("SetPositionAll"), &CSprite::SetPositionAll) - .Overload< void (CSprite::*)(Int32, Int32) const > - (_SC("SetPositionAll"), &CSprite::SetPositionAllEx) - .Overload< void (CSprite::*)(CPlayer &, const Vector2i &) const > - (_SC("SetPositionFor"), &CSprite::SetPositionFor) - .Overload< void (CSprite::*)(CPlayer &, Int32, Int32) const > - (_SC("SetPositionFor"), &CSprite::SetPositionForEx) - .Overload< void (CSprite::*)(const Vector2i &) const > - (_SC("SetCenterAll"), &CSprite::SetCenterAll) - .Overload< void (CSprite::*)(Int32, Int32) const > - (_SC("SetCenterAll"), &CSprite::SetCenterAllEx) - .Overload< void (CSprite::*)(CPlayer &, const Vector2i &) const > - (_SC("SetCenterFor"), &CSprite::SetCenterFor) - .Overload< void (CSprite::*)(CPlayer &, Int32, Int32) const > - (_SC("SetCenterFor"), &CSprite::SetCenterForEx) - // Static Functions - .StaticFunc(_SC("FindByID"), &Sprite_FindByID) - .StaticFunc(_SC("FindByTag"), &Sprite_FindByTag) - .StaticFunc(_SC("FindActive"), &Sprite_FindActive) - // Static Overloads - .StaticOverload< Object & (*)(CSStr, Int32, Int32, Int32, Int32, Float32, Int32, bool rel) > - (_SC("CreateEx"), &Sprite_CreateEx) - .StaticOverload< Object & (*)(CSStr, Int32, Int32, Int32, Int32, Float32, Int32, bool rel, Int32, Object &) > - (_SC("CreateEx"), &Sprite_CreateEx) - .StaticOverload< Object & (*)(Int32, CSStr, Int32, Int32, Int32, Int32, Float32, Int32, bool rel) > - (_SC("CreateEx"), &Sprite_CreateEx) - .StaticOverload< Object & (*)(Int32, CSStr, Int32, Int32, Int32, Int32, Float32, Int32, bool rel, Int32, Object &) > - (_SC("CreateEx"), &Sprite_CreateEx) - .StaticOverload< Object & (*)(CSStr, const Vector2i &, const Vector2i &, Float32, Int32, bool) > - (_SC("Create"), &Sprite_Create) - .StaticOverload< Object & (*)(CSStr, const Vector2i &, const Vector2i &, Float32, Int32, bool, Int32, Object &) > - (_SC("Create"), &Sprite_Create) - .StaticOverload< Object & (*)(Int32, CSStr, const Vector2i &, const Vector2i &, Float32, Int32, bool) > - (_SC("Create"), &Sprite_Create) - .StaticOverload< Object & (*)(Int32, CSStr, const Vector2i &, const Vector2i &, Float32, Int32, bool, Int32, Object &) > - (_SC("Create"), &Sprite_Create) - ); -} - -} // Namespace:: SqMod diff --git a/source/Entity/Sprite.hpp b/source/Entity/Sprite.hpp deleted file mode 100644 index ac45c2a8..00000000 --- a/source/Entity/Sprite.hpp +++ /dev/null @@ -1,278 +0,0 @@ -#ifndef _ENTITY_SPRITE_HPP_ -#define _ENTITY_SPRITE_HPP_ - -// ------------------------------------------------------------------------------------------------ -#include "Base/Shared.hpp" - -// ------------------------------------------------------------------------------------------------ -namespace SqMod { - -/* ------------------------------------------------------------------------------------------------ - * Manages a single sprite entity. -*/ -class CSprite -{ - // -------------------------------------------------------------------------------------------- - friend class Core; - -private: - - /* -------------------------------------------------------------------------------------------- - * Identifier of the managed entity. - */ - Int32 m_ID; - - /* -------------------------------------------------------------------------------------------- - * User tag associated with this instance. - */ - String m_Tag; - - /* -------------------------------------------------------------------------------------------- - * User data associated with this instance. - */ - Object m_Data; - - /* -------------------------------------------------------------------------------------------- - * Base constructor. - */ - CSprite(Int32 id); - -public: - - /* -------------------------------------------------------------------------------------------- - * Maximum possible number that could represent an identifier for this entity type. - */ - static const Int32 Max; - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. (disabled) - */ - CSprite(const CSprite &) = delete; - - /* -------------------------------------------------------------------------------------------- - * Move constructor. (disabled) - */ - CSprite(CSprite &&) = delete; - - /* -------------------------------------------------------------------------------------------- - * Destructor. - */ - ~CSprite(); - - /* -------------------------------------------------------------------------------------------- - * Copy assignment operator. (disabled) - */ - CSprite & operator = (const CSprite &) = delete; - - /* -------------------------------------------------------------------------------------------- - * Move assignment operator. (disabled) - */ - CSprite & operator = (CSprite &&) = delete; - - /* -------------------------------------------------------------------------------------------- - * See whether this instance manages a valid entity. - */ - void Validate() const - { - if (INVALID_ENTITY(m_ID)) - { - STHROWF("Invalid sprite reference [%s]", m_Tag.c_str()); - } - } - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to compare two instances of this type. - */ - Int32 Cmp(const CSprite & o) const; - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to convert an instance of this type to a string. - */ - const String & ToString() const; - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to retrieve the name from instances of this type. - */ - static SQInteger Typename(HSQUIRRELVM vm); - - /* -------------------------------------------------------------------------------------------- - * Retrieve the identifier of the entity managed by this instance. - */ - Int32 GetID() const - { - return m_ID; - } - - /* -------------------------------------------------------------------------------------------- - * Check whether this instance manages a valid entity. - */ - bool IsActive() const - { - return VALID_ENTITY(m_ID); - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated user tag. - */ - const String & GetTag() const; - - /* -------------------------------------------------------------------------------------------- - * Modify the associated user tag. - */ - void SetTag(CSStr tag); - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated user data. - */ - Object & GetData(); - - /* -------------------------------------------------------------------------------------------- - * Modify the associated user data. - */ - void SetData(Object & data); - - /* -------------------------------------------------------------------------------------------- - * Destroy the managed sprite entity. - */ - bool Destroy() - { - return Destroy(0, NullObject()); - } - - /* -------------------------------------------------------------------------------------------- - * Destroy the managed sprite entity. - */ - bool Destroy(Int32 header) - { - return Destroy(header, NullObject()); - } - - /* -------------------------------------------------------------------------------------------- - * Destroy the managed sprite entity. - */ - bool Destroy(Int32 header, Object & payload); - - /* -------------------------------------------------------------------------------------------- - * Bind to an event supported by this entity type. - */ - void BindEvent(Int32 evid, Object & env, Function & func) const; - - /* -------------------------------------------------------------------------------------------- - * Show the managed sprite entity to all players on the server. - */ - void ShowAll() const; - - /* -------------------------------------------------------------------------------------------- - * Show the managed sprite entity to the specified player entity. - */ - void ShowFor(CPlayer & player) const; - - /* -------------------------------------------------------------------------------------------- - * Show the managed sprite entity to all players in the specified range. - */ - void ShowRange(Int32 first, Int32 last) const; - - /* -------------------------------------------------------------------------------------------- - * Hide the managed sprite entity from all players on the server. - */ - void HideAll() const; - - /* -------------------------------------------------------------------------------------------- - * Hide the managed sprite entity from the specified player entity. - */ - void HideFor(CPlayer & player) const; - - /* -------------------------------------------------------------------------------------------- - * Hide the managed sprite entity from all players in the specified range. - */ - void HideRange(Int32 first, Int32 last) const; - - /* -------------------------------------------------------------------------------------------- - * Set the position of the managed sprite entity for all players on the server. - */ - void SetPositionAll(const Vector2i & pos) const; - - /* -------------------------------------------------------------------------------------------- - * Set the position of the managed sprite entity for all players on the server. - */ - void SetPositionAllEx(Int32 x, Int32 y) const; - - /* -------------------------------------------------------------------------------------------- - * Set the position of the managed sprite entity for the specified player entity. - */ - void SetPositionFor(CPlayer & player, const Vector2i & pos) const; - - /* -------------------------------------------------------------------------------------------- - * Set the position of the managed sprite entity for the specified player entity. - */ - void SetPositionForEx(CPlayer & player, Int32 x, Int32 y) const; - - /* -------------------------------------------------------------------------------------------- - * Set the position of the managed sprite entity for all players in the specified range. - */ - void SetPositionRange(Int32 first, Int32 last, const Vector2i & pos) const; - - /* -------------------------------------------------------------------------------------------- - * Set the center of the managed sprite entity for all players on the server. - */ - void SetCenterAll(const Vector2i & pos) const; - - /* -------------------------------------------------------------------------------------------- - * Set the center of the managed sprite entity for all players on the server. - */ - void SetCenterAllEx(Int32 x, Int32 y) const; - - /* -------------------------------------------------------------------------------------------- - * Set the center of the managed sprite entity for the specified player entity. - */ - void SetCenterFor(CPlayer & player, const Vector2i & pos) const; - - /* -------------------------------------------------------------------------------------------- - * Set the center of the managed sprite entity for the specified player entity. - */ - void SetCenterForEx(CPlayer & player, Int32 x, Int32 y) const; - - /* -------------------------------------------------------------------------------------------- - * Set the center of the managed sprite entity for all players in the specified range. - */ - void SetCenterRange(Int32 first, Int32 last, const Vector2i & pos) const; - - /* -------------------------------------------------------------------------------------------- - * Set the rotation of the managed sprite entity for all players on the server. - */ - void SetRotationAll(Float32 rot) const; - - /* -------------------------------------------------------------------------------------------- - * Set the rotation of the managed sprite entity for the specified player entity. - */ - void SetRotationFor(CPlayer & player, Float32 rot) const; - - /* -------------------------------------------------------------------------------------------- - * Set the rotation of the managed sprite entity for all players in the specified range. - */ - void SetRotationRange(Int32 first, Int32 last, Float32 rot) const; - - /* -------------------------------------------------------------------------------------------- - * Set the alpha of the managed sprite entity for all players on the server. - */ - void SetAlphaAll(Uint8 alpha) const; - - /* -------------------------------------------------------------------------------------------- - * Set the alpha of the managed sprite entity for the specified player entity. - */ - void SetAlphaFor(CPlayer & player, Uint8 alpha) const; - - /* -------------------------------------------------------------------------------------------- - * Set the alpha of the managed sprite entity for all players in the specified range. - */ - void SetAlphaRange(Int32 first, Int32 last, Uint8 alpha) const; - - /* -------------------------------------------------------------------------------------------- - * Retrieve the file path of the texture used by the managed sprite entity. - */ - const String & GetFilePath() const; -}; - -} // Namespace:: SqMod - -#endif // _ENTITY_SPRITE_HPP_ \ No newline at end of file diff --git a/source/Entity/Textdraw.cpp b/source/Entity/Textdraw.cpp deleted file mode 100644 index 190f89ad..00000000 --- a/source/Entity/Textdraw.cpp +++ /dev/null @@ -1,563 +0,0 @@ -// ------------------------------------------------------------------------------------------------ -#include "Entity/Textdraw.hpp" -#include "Entity/Player.hpp" -#include "Base/Vector2i.hpp" -#include "Base/Stack.hpp" -#include "Core.hpp" - -// ------------------------------------------------------------------------------------------------ -namespace SqMod { - -// ------------------------------------------------------------------------------------------------ -const Int32 CTextdraw::Max = SQMOD_TEXTDRAW_POOL; - -// ------------------------------------------------------------------------------------------------ -SQInteger CTextdraw::Typename(HSQUIRRELVM vm) -{ - static SQChar name[] = _SC("SqTextdraw"); - sq_pushstring(vm, name, sizeof(name)); - return 1; -} - -// ------------------------------------------------------------------------------------------------ -CTextdraw::CTextdraw(Int32 id) - : m_ID(VALID_ENTITYGETEX(id, SQMOD_TEXTDRAW_POOL)) - , m_Tag(ToStrF("%d", id)) -{ - /* ... */ -} - -// ------------------------------------------------------------------------------------------------ -CTextdraw::~CTextdraw() -{ - /* ... */ -} - -// ------------------------------------------------------------------------------------------------ -Int32 CTextdraw::Cmp(const CTextdraw & o) const -{ - if (m_ID == o.m_ID) - return 0; - else if (m_ID > o.m_ID) - return 1; - else - return -1; -} - -// ------------------------------------------------------------------------------------------------ -const String & CTextdraw::ToString() const -{ - return m_Tag; -} - -// ------------------------------------------------------------------------------------------------ -const String & CTextdraw::GetTag() const -{ - return m_Tag; -} - -// ------------------------------------------------------------------------------------------------ -void CTextdraw::SetTag(CSStr tag) -{ - m_Tag.assign(tag); -} - -// ------------------------------------------------------------------------------------------------ -Object & CTextdraw::GetData() -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return m_Data; -} - -// ------------------------------------------------------------------------------------------------ -void CTextdraw::SetData(Object & data) -{ - // Validate the managed identifier - Validate(); - // Apply the specified value - m_Data = data; -} - -// ------------------------------------------------------------------------------------------------ -bool CTextdraw::Destroy(Int32 header, Object & payload) -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - return _Core->DelTextdraw(m_ID, header, payload); -} - -// ------------------------------------------------------------------------------------------------ -void CTextdraw::BindEvent(Int32 evid, Object & env, Function & func) const -{ - // Validate the managed identifier - Validate(); - // Obtain the function instance called for this event - Function & event = _Core->GetTextdrawEvent(m_ID, evid); - // Is the specified callback function null? - if (func.IsNull()) - { - event.Release(); // Then release the current callback - } - // Assign the specified environment and function - else - { - event = Function(env.GetVM(), env, func.GetFunc()); - } -} - -// ------------------------------------------------------------------------------------------------ -void CTextdraw::ShowAll() const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->ShowTextdraw(m_ID, -1); -} - -// ------------------------------------------------------------------------------------------------ -void CTextdraw::ShowFor(CPlayer & player) const -{ - // Is the specified player even valid? - if (!player.IsActive()) - { - STHROWF("Invalid player argument: null"); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->ShowTextdraw(m_ID, player.GetID()); -} - -// ------------------------------------------------------------------------------------------------ -void CTextdraw::ShowRange(Int32 first, Int32 last) const -{ - // Validate the specified range - if (first > last) - { - STHROWF("Invalid player range: %d > %d", first, last); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - for (; first <= last; ++first) - { - // Is the currently processed player even connected? - if (_Func->IsPlayerConnected(first)) - { - // Then show this textdraw on his client - _Func->ShowTextdraw(m_ID, first); - } - } -} - -// ------------------------------------------------------------------------------------------------ -void CTextdraw::HideAll() const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->HideTextdraw(m_ID, -1); -} - -// ------------------------------------------------------------------------------------------------ -void CTextdraw::HideFor(CPlayer & player) const -{ - // Is the specified player even valid? - if (!player.IsActive()) - { - STHROWF("Invalid player argument: null"); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->HideTextdraw(m_ID, player.GetID()); -} - -// ------------------------------------------------------------------------------------------------ -void CTextdraw::HideRange(Int32 first, Int32 last) const -{ - // Validate the specified range - if (first > last) - { - STHROWF("Invalid player range: %d > %d", first, last); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - for (; first <= last; ++first) - { - // Is the currently processed player even connected? - if (_Func->IsPlayerConnected(first)) - { - // Then hide this textdraw on his client - _Func->HideTextdraw(m_ID, first); - } - } -} - -// ------------------------------------------------------------------------------------------------ -void CTextdraw::SetPositionAll(const Vector2i & pos) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->MoveTextdraw(m_ID, -1, pos.x, pos.y); -} - -// ------------------------------------------------------------------------------------------------ -void CTextdraw::SetPositionAllEx(Int32 x, Int32 y) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->MoveTextdraw(m_ID, -1, x, y); -} - -// ------------------------------------------------------------------------------------------------ -void CTextdraw::SetPositionFor(CPlayer & player, const Vector2i & pos) const -{ - // Is the specified player even valid? - if (!player.IsActive()) - { - STHROWF("Invalid player argument: null"); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->MoveTextdraw(m_ID, player.GetID(), pos.x, pos.y); -} - -// ------------------------------------------------------------------------------------------------ -void CTextdraw::SetPositionForEx(CPlayer & player, Int32 x, Int32 y) const -{ - // Is the specified player even valid? - if (!player.IsActive()) - { - STHROWF("Invalid player argument: null"); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->MoveTextdraw(m_ID, player.GetID(), x, y); -} - -// ------------------------------------------------------------------------------------------------ -void CTextdraw::SetPositionRange(Int32 first, Int32 last, const Vector2i & pos) const -{ - // Validate the specified range - if (first > last) - { - STHROWF("Invalid player range: %d > %d", first, last); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - for (; first <= last; ++first) - { - // Is the currently processed player even connected? - if (_Func->IsPlayerConnected(first)) - { - // Then move this textdraw on his client - _Func->MoveTextdraw(m_ID, first, pos.x, pos.y); - } - } -} - -// ------------------------------------------------------------------------------------------------ -void CTextdraw::SetColorAll(const Color4 & col) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->SetTextdrawColour(m_ID, -1, col.GetRGBA()); -} - -// ------------------------------------------------------------------------------------------------ -void CTextdraw::SetColorAllEx(Uint8 r, Uint8 g, Uint8 b, Uint8 a) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->SetTextdrawColour(m_ID, -1, SQMOD_PACK_RGBA(r, g, b, a)); -} - -// ------------------------------------------------------------------------------------------------ -void CTextdraw::SetColorFor(CPlayer & player, const Color4 & col) const -{ - // Is the specified player even valid? - if (!player.IsActive()) - { - STHROWF("Invalid player argument: null"); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->SetTextdrawColour(m_ID, player.GetID(), col.GetRGBA()); -} - -// ------------------------------------------------------------------------------------------------ -void CTextdraw::SetColorForEx(CPlayer & player, Uint8 r, Uint8 g, Uint8 b, Uint8 a) const -{ - // Is the specified player even valid? - if (!player.IsActive()) - { - STHROWF("Invalid player argument: null"); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->SetTextdrawColour(m_ID, player.GetID(), SQMOD_PACK_RGBA(r, g, b, a)); -} - -// ------------------------------------------------------------------------------------------------ -void CTextdraw::SetColorRange(Int32 first, Int32 last, const Color4 & col) const -{ - // Validate the specified range - if (first > last) - { - STHROWF("Invalid player range: %d > %d", first, last); - } - // Validate the managed identifier - Validate(); - // Perform the requested operation - for (const Uint32 color = col.GetRGBA(); first <= last; ++first) - { - // Is the currently processed player even connected? - if (_Func->IsPlayerConnected(first)) - { - // Then colorize this textdraw on his client - _Func->SetTextdrawColour(m_ID, first, color); - } - } -} - -// ------------------------------------------------------------------------------------------------ -const String & CTextdraw::GetText() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Core->GetTextdraw(m_ID).mText; -} - -// ------------------------------------------------------------------------------------------------ -static Object & Textdraw_CreateEx(CSStr text, Int32 xp, Int32 yp, - Uint8 r, Uint8 g, Uint8 b, Uint8 a, bool rel) -{ - return _Core->NewTextdraw(SQMOD_UNKNOWN, text, xp, yp, SQMOD_PACK_ARGB(a, r, g, b), rel, - SQMOD_CREATE_DEFAULT, NullObject()); -} - -// ------------------------------------------------------------------------------------------------ -static Object & Textdraw_CreateEx(CSStr text, Int32 xp, Int32 yp, - Uint8 r, Uint8 g, Uint8 b, Uint8 a, bool rel, - Int32 header, Object & payload) -{ - return _Core->NewTextdraw(SQMOD_UNKNOWN, text, xp, yp, SQMOD_PACK_ARGB(a, r, g, b), rel, - header, payload); -} - -// ------------------------------------------------------------------------------------------------ -static Object & Textdraw_CreateEx(Int32 index, CSStr text, Int32 xp, Int32 yp, - Uint8 r, Uint8 g, Uint8 b, Uint8 a, bool rel) -{ - return _Core->NewTextdraw(index,text, xp, yp, SQMOD_PACK_ARGB(a, r, g, b), rel, - SQMOD_CREATE_DEFAULT, NullObject()); -} - -// ------------------------------------------------------------------------------------------------ -static Object & Textdraw_CreateEx(Int32 index, CSStr text, Int32 xp, Int32 yp, - Uint8 r, Uint8 g, Uint8 b, Uint8 a, bool rel, - Int32 header, Object & payload) -{ - return _Core->NewTextdraw(index, text, xp, yp, SQMOD_PACK_ARGB(a, r, g, b), rel, - header, payload); -} - -// ------------------------------------------------------------------------------------------------ -static Object & Textdraw_Create(CSStr text, const Vector2i & pos, const Color4 & color, bool rel) -{ - return _Core->NewTextdraw(SQMOD_UNKNOWN, text, pos.x, pos.y, color.GetARGB(), rel, - SQMOD_CREATE_DEFAULT, NullObject()); -} - -// ------------------------------------------------------------------------------------------------ -static Object & Textdraw_Create(CSStr text, const Vector2i & pos, const Color4 & color, bool rel, - Int32 header, Object & payload) -{ - return _Core->NewTextdraw(SQMOD_UNKNOWN, text, pos.x, pos.y, color.GetARGB(), rel, - header, payload); -} - -// ------------------------------------------------------------------------------------------------ -static Object & Textdraw_Create(Int32 index, CSStr text, const Vector2i & pos, const Color4 & color, - bool rel) -{ - return _Core->NewTextdraw(index, text, pos.x, pos.y, color.GetARGB(), rel, - SQMOD_CREATE_DEFAULT, NullObject()); -} - -// ------------------------------------------------------------------------------------------------ -static Object & Textdraw_Create(Int32 index, CSStr text, const Vector2i & pos, const Color4 & color, - bool rel, Int32 header, Object & payload) -{ - return _Core->NewTextdraw(index, text, pos.x, pos.y, color.GetARGB(), rel, header, payload); -} - -// ------------------------------------------------------------------------------------------------ -static const Object & Textdraw_FindByID(Int32 id) -{ - // Perform a range check on the specified identifier - if (INVALID_ENTITYEX(id, SQMOD_TEXTDRAW_POOL)) - { - STHROWF("The specified textdraw identifier is invalid: %d", id); - } - // Obtain the ends of the entity pool - Core::Textdraws::const_iterator itr = _Core->GetTextdraws().cbegin(); - Core::Textdraws::const_iterator end = _Core->GetTextdraws().cend(); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Does the identifier match the specified one? - if (itr->mID == id) - { - return itr->mObj; // Stop searching and return this entity - } - } - // Unable to locate a textdraw matching the specified identifier - return NullObject(); -} - -// ------------------------------------------------------------------------------------------------ -static const Object & Textdraw_FindByTag(CSStr tag) -{ - // Perform a validity check on the specified tag - if (!tag || *tag == '\0') - { - STHROWF("The specified textdraw tag is invalid: null/empty"); - } - // Obtain the ends of the entity pool - Core::Textdraws::const_iterator itr = _Core->GetTextdraws().cbegin(); - Core::Textdraws::const_iterator end = _Core->GetTextdraws().cend(); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Does this entity even exist and does the tag match the specified one? - if (itr->mInst != nullptr && itr->mInst->GetTag().compare(tag) == 0) - { - return itr->mObj; // Stop searching and return this entity - } - } - // Unable to locate a textdraw matching the specified tag - return NullObject(); -} - -// ------------------------------------------------------------------------------------------------ -static Array Textdraw_FindActive() -{ - // Remember the initial stack size - StackGuard sg; - // Obtain the ends of the entity pool - Core::Textdraws::const_iterator itr = _Core->GetTextdraws().cbegin(); - Core::Textdraws::const_iterator end = _Core->GetTextdraws().cend(); - // Allocate an empty array on the stack - sq_newarray(DefaultVM::Get(), 0); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Is this entity instance active? - if (VALID_ENTITY(itr->mID)) - { - // Push the script object on the stack - sq_pushobject(DefaultVM::Get(), (HSQOBJECT &)((*itr).mObj)); - // Append the object at the back of the array - if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -1))) - { - STHROWF("Unable to append entity instance to the list"); - } - } - } - // Return the array at the top of the stack - return Var< Array >(DefaultVM::Get(), -1).value; -} - -// ================================================================================================ -void Register_CTextdraw(HSQUIRRELVM vm) -{ - RootTable(vm).Bind(_SC("SqTextdraw"), - Class< CTextdraw, NoConstructor< CTextdraw > >(vm, _SC("SqTextdraw")) - // Metamethods - .Func(_SC("_cmp"), &CTextdraw::Cmp) - .SquirrelFunc(_SC("_typename"), &CTextdraw::Typename) - .Func(_SC("_tostring"), &CTextdraw::ToString) - // Static Values - .SetStaticValue(_SC("MaxID"), CTextdraw::Max) - // Core Properties - .Prop(_SC("ID"), &CTextdraw::GetID) - .Prop(_SC("Tag"), &CTextdraw::GetTag, &CTextdraw::SetTag) - .Prop(_SC("Data"), &CTextdraw::GetData, &CTextdraw::SetData) - .Prop(_SC("Active"), &CTextdraw::IsActive) - // Core Methods - .Func(_SC("Bind"), &CTextdraw::BindEvent) - // Core Overloads - .Overload< bool (CTextdraw::*)(void) >(_SC("Destroy"), &CTextdraw::Destroy) - .Overload< bool (CTextdraw::*)(Int32) >(_SC("Destroy"), &CTextdraw::Destroy) - .Overload< bool (CTextdraw::*)(Int32, Object &) >(_SC("Destroy"), &CTextdraw::Destroy) - // Properties - .Prop(_SC("Text"), &CTextdraw::GetText) - // Member Methods - .Func(_SC("ShowAll"), &CTextdraw::ShowAll) - .Func(_SC("ShowTo"), &CTextdraw::ShowFor) - .Func(_SC("ShowFor"), &CTextdraw::ShowFor) - .Func(_SC("ShowRange"), &CTextdraw::ShowRange) - .Func(_SC("HideAll"), &CTextdraw::HideAll) - .Func(_SC("HideFor"), &CTextdraw::HideFor) - .Func(_SC("HideFrom"), &CTextdraw::HideFor) - .Func(_SC("HideRange"), &CTextdraw::HideRange) - .Func(_SC("SetPositionRange"), &CTextdraw::SetPositionRange) - .Func(_SC("SetColorRange"), &CTextdraw::SetColorRange) - // Member Overloads - .Overload< void (CTextdraw::*)(const Vector2i &) const > - (_SC("SetPositionAll"), &CTextdraw::SetPositionAll) - .Overload< void (CTextdraw::*)(Int32, Int32) const > - (_SC("SetPositionAll"), &CTextdraw::SetPositionAllEx) - .Overload< void (CTextdraw::*)(CPlayer &, const Vector2i &) const > - (_SC("SetPositionFor"), &CTextdraw::SetPositionFor) - .Overload< void (CTextdraw::*)(CPlayer &, Int32, Int32) const > - (_SC("SetPositionFor"), &CTextdraw::SetPositionForEx) - .Overload< void (CTextdraw::*)(const Color4 &) const > - (_SC("SetColorAll"), &CTextdraw::SetColorAll) - .Overload< void (CTextdraw::*)(Uint8, Uint8, Uint8, Uint8) const > - (_SC("SetColorAll"), &CTextdraw::SetColorAllEx) - .Overload< void (CTextdraw::*)(CPlayer &, const Color4 &) const > - (_SC("SetColorFor"), &CTextdraw::SetColorFor) - .Overload< void (CTextdraw::*)(CPlayer &, Uint8, Uint8, Uint8, Uint8) const > - (_SC("SetColorFor"), &CTextdraw::SetColorForEx) - // Static Functions - .StaticFunc(_SC("FindByID"), &Textdraw_FindByID) - .StaticFunc(_SC("FindByTag"), &Textdraw_FindByTag) - .StaticFunc(_SC("FindActive"), &Textdraw_FindActive) - // Static Overloads - .StaticOverload< Object & (*)(CSStr, Int32, Int32, Uint8, Uint8, Uint8, Uint8, bool) > - (_SC("CreateEx"), &Textdraw_CreateEx) - .StaticOverload< Object & (*)(CSStr, Int32, Int32, Uint8, Uint8, Uint8, Uint8, bool, Int32, Object &) > - (_SC("CreateEx"), &Textdraw_CreateEx) - .StaticOverload< Object & (*)(Int32, CSStr, Int32, Int32, Uint8, Uint8, Uint8, Uint8, bool) > - (_SC("CreateEx"), &Textdraw_CreateEx) - .StaticOverload< Object & (*)(Int32, CSStr, Int32, Int32, Uint8, Uint8, Uint8, Uint8, bool, Int32, Object &) > - (_SC("CreateEx"), &Textdraw_CreateEx) - .StaticOverload< Object & (*)(CSStr, const Vector2i &, const Color4 &, bool) > - (_SC("Create"), &Textdraw_Create) - .StaticOverload< Object & (*)(CSStr, const Vector2i &, const Color4 &, bool, Int32, Object &) > - (_SC("Create"), &Textdraw_Create) - .StaticOverload< Object & (*)(Int32, CSStr, const Vector2i &, const Color4 &, bool) > - (_SC("Create"), &Textdraw_Create) - .StaticOverload< Object & (*)(Int32, CSStr, const Vector2i &, const Color4 &, bool, Int32, Object &) > - (_SC("Create"), &Textdraw_Create) - ); -} - -} // Namespace:: SqMod diff --git a/source/Entity/Textdraw.hpp b/source/Entity/Textdraw.hpp deleted file mode 100644 index 79dcec64..00000000 --- a/source/Entity/Textdraw.hpp +++ /dev/null @@ -1,248 +0,0 @@ -#ifndef _ENTITY_TEXTDRAW_HPP_ -#define _ENTITY_TEXTDRAW_HPP_ - -// ------------------------------------------------------------------------------------------------ -#include "Base/Shared.hpp" - -// ------------------------------------------------------------------------------------------------ -namespace SqMod { - -/* ------------------------------------------------------------------------------------------------ - * Manages a single textdraw entity. -*/ -class CTextdraw -{ - // -------------------------------------------------------------------------------------------- - friend class Core; - -private: - - /* -------------------------------------------------------------------------------------------- - * Identifier of the managed entity. - */ - Int32 m_ID; - - /* -------------------------------------------------------------------------------------------- - * User tag associated with this instance. - */ - String m_Tag; - - /* -------------------------------------------------------------------------------------------- - * User data associated with this instance. - */ - Object m_Data; - - /* -------------------------------------------------------------------------------------------- - * Base constructor. - */ - CTextdraw(Int32 id); - -public: - - /* -------------------------------------------------------------------------------------------- - * Maximum possible number that could represent an identifier for this entity type. - */ - static const Int32 Max; - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. (disabled) - */ - CTextdraw(const CTextdraw &) = delete; - - /* -------------------------------------------------------------------------------------------- - * Move constructor. (disabled) - */ - CTextdraw(CTextdraw &&) = delete; - - /* -------------------------------------------------------------------------------------------- - * Destructor. - */ - ~CTextdraw(); - - /* -------------------------------------------------------------------------------------------- - * Copy assignment operator. (disabled) - */ - CTextdraw & operator = (const CTextdraw &) = delete; - - /* -------------------------------------------------------------------------------------------- - * Move assignment operator. (disabled) - */ - CTextdraw & operator = (CTextdraw &&) = delete; - - /* -------------------------------------------------------------------------------------------- - * See whether this instance manages a valid entity. - */ - void Validate() const - { - if (INVALID_ENTITY(m_ID)) - { - STHROWF("Invalid textdraw reference [%s]", m_Tag.c_str()); - } - } - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to compare two instances of this type. - */ - Int32 Cmp(const CTextdraw & o) const; - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to convert an instance of this type to a string. - */ - const String & ToString() const; - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to retrieve the name from instances of this type. - */ - static SQInteger Typename(HSQUIRRELVM vm); - - /* -------------------------------------------------------------------------------------------- - * Retrieve the identifier of the entity managed by this instance. - */ - Int32 GetID() const - { - return m_ID; - } - - /* -------------------------------------------------------------------------------------------- - * Check whether this instance manages a valid entity. - */ - bool IsActive() const - { - return VALID_ENTITY(m_ID); - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated user tag. - */ - const String & GetTag() const; - - /* -------------------------------------------------------------------------------------------- - * Modify the associated user tag. - */ - void SetTag(CSStr tag); - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated user data. - */ - Object & GetData(); - - /* -------------------------------------------------------------------------------------------- - * Modify the associated user data. - */ - void SetData(Object & data); - - /* -------------------------------------------------------------------------------------------- - * Destroy the managed textdraw entity. - */ - bool Destroy() - { - return Destroy(0, NullObject()); - } - - /* -------------------------------------------------------------------------------------------- - * Destroy the managed textdraw entity. - */ - bool Destroy(Int32 header) - { - return Destroy(header, NullObject()); - } - - /* -------------------------------------------------------------------------------------------- - * Destroy the managed textdraw entity. - */ - bool Destroy(Int32 header, Object & payload); - - /* -------------------------------------------------------------------------------------------- - * Bind to an event supported by this entity type. - */ - void BindEvent(Int32 evid, Object & env, Function & func) const; - - /* -------------------------------------------------------------------------------------------- - * Show the managed textdraw entity to all players on the server. - */ - void ShowAll() const; - - /* -------------------------------------------------------------------------------------------- - * Show the managed textdraw entity to the specified player entity. - */ - void ShowFor(CPlayer & player) const; - - /* -------------------------------------------------------------------------------------------- - * Show the managed textdraw entity to all players in the specified range. - */ - void ShowRange(Int32 first, Int32 last) const; - - /* -------------------------------------------------------------------------------------------- - * Hide the managed textdraw entity from all players on the server. - */ - void HideAll() const; - - /* -------------------------------------------------------------------------------------------- - * Hide the managed textdraw entity from the specified player entity. - */ - void HideFor(CPlayer & player) const; - - /* -------------------------------------------------------------------------------------------- - * Hide the managed textdraw entity from all players in the specified range. - */ - void HideRange(Int32 first, Int32 last) const; - - /* -------------------------------------------------------------------------------------------- - * Set the position of the managed textdraw entity for all players on the server. - */ - void SetPositionAll(const Vector2i & pos) const; - - /* -------------------------------------------------------------------------------------------- - * Set the position of the managed textdraw entity for all players on the server. - */ - void SetPositionAllEx(Int32 x, Int32 y) const; - - /* -------------------------------------------------------------------------------------------- - * Set the position of the managed textdraw entity for the specified player entity. - */ - void SetPositionFor(CPlayer & player, const Vector2i & pos) const; - - /* -------------------------------------------------------------------------------------------- - * Set the position of the managed textdraw entity for the specified player entity. - */ - void SetPositionForEx(CPlayer & player, Int32 x, Int32 y) const; - - /* -------------------------------------------------------------------------------------------- - * Set the position of the managed textdraw entity for all players in the specified range. - */ - void SetPositionRange(Int32 first, Int32 last, const Vector2i & pos) const; - - /* -------------------------------------------------------------------------------------------- - * Set the center of the managed textdraw entity for all players on the server. - */ - void SetColorAll(const Color4 & col) const; - - /* -------------------------------------------------------------------------------------------- - * Set the color of the managed textdraw entity for all players on the server. - */ - void SetColorAllEx(Uint8 r, Uint8 g, Uint8 b, Uint8 a) const; - - /* -------------------------------------------------------------------------------------------- - * Set the color of the managed textdraw entity for the specified player entity. - */ - void SetColorFor(CPlayer & player, const Color4 & col) const; - - /* -------------------------------------------------------------------------------------------- - * Set the color of the managed textdraw entity for the specified player entity. - */ - void SetColorForEx(CPlayer & player, Uint8 r, Uint8 g, Uint8 b, Uint8 a) const; - - /* -------------------------------------------------------------------------------------------- - * Set the color of the managed textdraw entity for all players in the specified range. - */ - void SetColorRange(Int32 first, Int32 last, const Color4 & col) const; - - /* -------------------------------------------------------------------------------------------- - * Retrieve the text string used by the managed textdraw entity. - */ - const String & GetText() const; -}; - -} // Namespace:: SqMod - -#endif // _ENTITY_TEXTDRAW_HPP_ \ No newline at end of file diff --git a/source/Entity/Vehicle.cpp b/source/Entity/Vehicle.cpp index c7802fc2..d713407e 100644 --- a/source/Entity/Vehicle.cpp +++ b/source/Entity/Vehicle.cpp @@ -2,7 +2,8 @@ #include "Entity/Vehicle.hpp" #include "Entity/Player.hpp" #include "Base/Quaternion.hpp" -#include "Base/Vector4.hpp" +#include "Base/Vector2.hpp" +#include "Base/Vector3.hpp" #include "Base/Stack.hpp" #include "Core.hpp" @@ -10,8 +11,8 @@ namespace SqMod { // ------------------------------------------------------------------------------------------------ +Vector2 CVehicle::s_Vector2; Vector3 CVehicle::s_Vector3; -Vector4 CVehicle::s_Vector4; Quaternion CVehicle::s_Quaternion; // ------------------------------------------------------------------------------------------------ @@ -20,7 +21,7 @@ const Int32 CVehicle::Max = SQMOD_VEHICLE_POOL; // ------------------------------------------------------------------------------------------------ SQInteger CVehicle::Typename(HSQUIRRELVM vm) { - static SQChar name[] = _SC("SqVehicle"); + static const SQChar name[] = _SC("SqVehicle"); sq_pushstring(vm, name, sizeof(name)); return 1; } @@ -28,7 +29,7 @@ SQInteger CVehicle::Typename(HSQUIRRELVM vm) // ------------------------------------------------------------------------------------------------ CVehicle::CVehicle(Int32 id) : m_ID(VALID_ENTITYGETEX(id, SQMOD_VEHICLE_POOL)) - , m_Tag(ToStrF("%d", id)) + , m_Tag(ToStrF("%d", id)), m_Data(), m_CircularLocks(0) { /* ... */ } @@ -43,11 +44,17 @@ CVehicle::~CVehicle() Int32 CVehicle::Cmp(const CVehicle & o) const { if (m_ID == o.m_ID) + { return 0; + } else if (m_ID > o.m_ID) + { return 1; + } else + { return -1; + } } // ------------------------------------------------------------------------------------------------ @@ -92,7 +99,7 @@ bool CVehicle::Destroy(Int32 header, Object & payload) // Validate the managed identifier Validate(); // Perform the requested operation - return _Core->DelVehicle(m_ID, header, payload); + return Core::Get().DelVehicle(m_ID, header, payload); } // ------------------------------------------------------------------------------------------------ @@ -101,7 +108,7 @@ void CVehicle::BindEvent(Int32 evid, Object & env, Function & func) const // Validate the managed identifier Validate(); // Obtain the function instance called for this event - Function & event = _Core->GetVehicleEvent(m_ID, evid); + Function & event = Core::Get().GetVehicleEvent(m_ID, evid); // Is the specified callback function null? if (func.IsNull()) { @@ -128,6 +135,60 @@ bool CVehicle::IsStreamedFor(CPlayer & player) const return _Func->IsVehicleStreamedForPlayer(m_ID, player.GetID()); } +// ------------------------------------------------------------------------------------------------ +bool CVehicle::GetOption(Int32 option_id) const +{ + // Attempt to obtain the current value of the specified option + const bool value = _Func->GetVehicleOption(m_ID, static_cast< vcmpVehicleOption >(option_id)); + // Check for errors + if (_Func->GetLastError() == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Invalid option identifier: %d", option_id); + } + // Return the requested value + return value; +} + +// ------------------------------------------------------------------------------------------------ +void CVehicle::SetOption(Int32 option_id, bool toggle) +{ + // Attempt to obtain the current value of the specified option + const bool value = _Func->GetVehicleOption(m_ID, static_cast< vcmpVehicleOption >(option_id)); + // Attempt to modify the current value of the specified option + if (_Func->SetVehicleOption(m_ID, static_cast< vcmpVehicleOption >(option_id), + toggle) == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Invalid option identifier: %d", option_id); + } + else if (!(m_CircularLocks & VCL_EMIT_VEHICLE_OPTION)) + { + // Prevent this event from triggering while executed + BitGuardU32 bg(m_CircularLocks, VCL_EMIT_VEHICLE_OPTION); + // Now forward the event call + Core::Get().EmitVehicleOption(m_ID, option_id, value, 0, NullObject()); + } +} + +// ------------------------------------------------------------------------------------------------ +void CVehicle::SetOptionEx(Int32 option_id, bool toggle, Int32 header, Object & payload) +{ + // Attempt to obtain the current value of the specified option + const bool value = _Func->GetVehicleOption(m_ID, static_cast< vcmpVehicleOption >(option_id)); + // Attempt to modify the current value of the specified option + if (_Func->SetVehicleOption(m_ID, static_cast< vcmpVehicleOption >(option_id), + toggle) == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Invalid option identifier: %d", option_id); + } + else if (!(m_CircularLocks & VCL_EMIT_VEHICLE_OPTION)) + { + // Prevent this event from triggering while executed + BitGuardU32 bg(m_CircularLocks, VCL_EMIT_VEHICLE_OPTION); + // Now forward the event call + Core::Get().EmitVehicleOption(m_ID, option_id, value, header, payload); + } +} + // ------------------------------------------------------------------------------------------------ Int32 CVehicle::GetSyncSource() const { @@ -179,7 +240,7 @@ Object & CVehicle::GetOccupant(Int32 slot) const // Validate the managed identifier Validate(); // Return the requested information - return _Core->GetPlayer(_Func->GetVehicleOccupant(m_ID, slot)).mObj; + return Core::Get().GetPlayer(_Func->GetVehicleOccupant(m_ID, slot)).mObj; } // ------------------------------------------------------------------------------------------------ @@ -218,6 +279,15 @@ void CVehicle::SetImmunity(Int32 flags) const _Func->SetVehicleImmunityFlags(m_ID, flags); } +// ------------------------------------------------------------------------------------------------ +void CVehicle::Explode() const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->ExplodeVehicle(m_ID); +} + // ------------------------------------------------------------------------------------------------ bool CVehicle::IsWrecked() const { @@ -232,10 +302,10 @@ const Vector3 & CVehicle::GetPosition() const { // Validate the managed identifier Validate(); - // Clear previous position information, if any + // Clear previous information, if any s_Vector3.Clear(); - // Query the server for the position values - _Func->GetVehiclePos(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); + // Query the server for the values + _Func->GetVehiclePosition(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); // Return the requested information return s_Vector3; } @@ -246,7 +316,7 @@ void CVehicle::SetPosition(const Vector3 & pos) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehiclePos(m_ID, pos.x, pos.y, pos.z, false); + _Func->SetVehiclePosition(m_ID, pos.x, pos.y, pos.z, false); } // ------------------------------------------------------------------------------------------------ @@ -255,7 +325,7 @@ void CVehicle::SetPositionEx(const Vector3 & pos, bool empty) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehiclePos(m_ID, pos.x, pos.y, pos.z, empty); + _Func->SetVehiclePosition(m_ID, pos.x, pos.y, pos.z, empty); } // ------------------------------------------------------------------------------------------------ @@ -264,7 +334,7 @@ void CVehicle::SetPositionEx(Float32 x, Float32 y, Float32 z) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehiclePos(m_ID, x, y, z, false); + _Func->SetVehiclePosition(m_ID, x, y, z, false); } // ------------------------------------------------------------------------------------------------ @@ -273,7 +343,7 @@ void CVehicle::SetPositionEx(Float32 x, Float32 y, Float32 z, bool empty) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehiclePos(m_ID, x, y, z, empty); + _Func->SetVehiclePosition(m_ID, x, y, z, empty); } // ------------------------------------------------------------------------------------------------ @@ -281,10 +351,10 @@ const Quaternion & CVehicle::GetRotation() const { // Validate the managed identifier Validate(); - // Clear previous rotation information, if any + // Clear previous information, if any s_Quaternion.Clear(); - // Query the server for the rotation values - _Func->GetVehicleRot(m_ID, &s_Quaternion.x, &s_Quaternion.y, &s_Quaternion.z, &s_Quaternion.w); + // Query the server for the values + _Func->GetVehicleRotation(m_ID, &s_Quaternion.x, &s_Quaternion.y, &s_Quaternion.z, &s_Quaternion.w); // Return the requested information return s_Quaternion; } @@ -295,7 +365,7 @@ void CVehicle::SetRotation(const Quaternion & rot) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehicleRot(m_ID, rot.x, rot.y, rot.z, rot.w); + _Func->SetVehicleRotation(m_ID, rot.x, rot.y, rot.z, rot.w); } // ------------------------------------------------------------------------------------------------ @@ -304,7 +374,7 @@ void CVehicle::SetRotationEx(Float32 x, Float32 y, Float32 z, Float32 w) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehicleRot(m_ID, x, y, z, w); + _Func->SetVehicleRotation(m_ID, x, y, z, w); } // ------------------------------------------------------------------------------------------------ @@ -312,10 +382,10 @@ const Vector3 & CVehicle::GetRotationEuler() const { // Validate the managed identifier Validate(); - // Clear previous rotation information, if any + // Clear previous information, if any s_Vector3.Clear(); - // Query the server for the rotation values - _Func->GetVehicleRotEuler(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); + // Query the server for the values + _Func->GetVehicleRotationEuler(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); // Return the requested information return s_Vector3; } @@ -326,7 +396,7 @@ void CVehicle::SetRotationEuler(const Vector3 & rot) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehicleRotEuler(m_ID, rot.x, rot.y, rot.z); + _Func->SetVehicleRotationEuler(m_ID, rot.x, rot.y, rot.z); } // ------------------------------------------------------------------------------------------------ @@ -335,7 +405,7 @@ void CVehicle::SetRotationEulerEx(Float32 x, Float32 y, Float32 z) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehicleRotEuler(m_ID, x, y, z); + _Func->SetVehicleRotationEuler(m_ID, x, y, z); } // ------------------------------------------------------------------------------------------------ @@ -343,10 +413,10 @@ const Vector3 & CVehicle::GetSpeed() const { // Validate the managed identifier Validate(); - // Clear previous speed information, if any + // Clear previous information, if any s_Vector3.Clear(); - // Query the server for the speed values - _Func->GetVehicleSpeed(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); + // Query the server for the values + _Func->GetVehicleSpeed(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z, false); // Return the requested information return s_Vector3; } @@ -357,7 +427,7 @@ void CVehicle::SetSpeed(const Vector3 & vel) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehicleSpeed(m_ID, vel.x, vel.y, vel.z); + _Func->SetVehicleSpeed(m_ID, vel.x, vel.y, vel.z, false, false); } // ------------------------------------------------------------------------------------------------ @@ -366,7 +436,7 @@ void CVehicle::SetSpeedEx(Float32 x, Float32 y, Float32 z) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehicleSpeed(m_ID, x, y, z); + _Func->SetVehicleSpeed(m_ID, x, y, z, false, false); } // ------------------------------------------------------------------------------------------------ @@ -375,7 +445,7 @@ void CVehicle::AddSpeed(const Vector3 & vel) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->AddVehicleSpeed(m_ID, vel.x, vel.y, vel.z); + _Func->SetVehicleSpeed(m_ID, vel.x, vel.y, vel.z, true, false); } // ------------------------------------------------------------------------------------------------ @@ -384,56 +454,56 @@ void CVehicle::AddSpeedEx(Float32 x, Float32 y, Float32 z) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->AddVehicleSpeed(m_ID, x, y, z); + _Func->SetVehicleSpeed(m_ID, x, y, z, true, false); } // ------------------------------------------------------------------------------------------------ -const Vector3 & CVehicle::GetRelSpeed() const +const Vector3 & CVehicle::GetRelativeSpeed() const { // Validate the managed identifier Validate(); - // Clear previous relative speed information, if any + // Clear previous information, if any s_Vector3.Clear(); - // Query the server for the relative speed values - _Func->GetVehicleRelSpeed(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); + // Query the server for the values + _Func->GetVehicleSpeed(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z, true); // Return the requested information return s_Vector3; } // ------------------------------------------------------------------------------------------------ -void CVehicle::SetRelSpeed(const Vector3 & vel) const +void CVehicle::SetRelativeSpeed(const Vector3 & vel) const { // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehicleRelSpeed(m_ID, vel.x, vel.y, vel.z); + _Func->SetVehicleSpeed(m_ID, vel.x, vel.y, vel.z, false, true); } // ------------------------------------------------------------------------------------------------ -void CVehicle::SetRelSpeedEx(Float32 x, Float32 y, Float32 z) const +void CVehicle::SetRelativeSpeedEx(Float32 x, Float32 y, Float32 z) const { // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehicleRelSpeed(m_ID, x, y, z); + _Func->SetVehicleSpeed(m_ID, x, y, z, false, true); } // ------------------------------------------------------------------------------------------------ -void CVehicle::AddRelSpeed(const Vector3 & vel) const +void CVehicle::AddRelativeSpeed(const Vector3 & vel) const { // Validate the managed identifier Validate(); // Perform the requested operation - _Func->AddVehicleRelSpeed(m_ID, vel.x, vel.y, vel.z); + _Func->SetVehicleSpeed(m_ID, vel.x, vel.y, vel.z, true, true); } // ------------------------------------------------------------------------------------------------ -void CVehicle::AddRelSpeedEx(Float32 x, Float32 y, Float32 z) const +void CVehicle::AddRelativeSpeedEx(Float32 x, Float32 y, Float32 z) const { // Validate the managed identifier Validate(); // Perform the requested operation - _Func->AddVehicleRelSpeed(m_ID, x, y, z); + _Func->SetVehicleSpeed(m_ID, x, y, z, true, true); } // ------------------------------------------------------------------------------------------------ @@ -441,10 +511,10 @@ const Vector3 & CVehicle::GetTurnSpeed() const { // Validate the managed identifier Validate(); - // Clear previous turn speed information, if any + // Clear previous information, if any s_Vector3.Clear(); - // Query the server for the turn speed values - _Func->GetVehicleTurnSpeed(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); + // Query the server for the values + _Func->GetVehicleTurnSpeed(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z, false); // Return the requested information return s_Vector3; } @@ -455,7 +525,7 @@ void CVehicle::SetTurnSpeed(const Vector3 & vel) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehicleTurnSpeed(m_ID, vel.x, vel.y, vel.z); + _Func->SetVehicleTurnSpeed(m_ID, vel.x, vel.y, vel.z, false, false); } // ------------------------------------------------------------------------------------------------ @@ -464,7 +534,7 @@ void CVehicle::SetTurnSpeedEx(Float32 x, Float32 y, Float32 z) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehicleTurnSpeed(m_ID, x, y, z); + _Func->SetVehicleTurnSpeed(m_ID, x, y, z, false, false); } // ------------------------------------------------------------------------------------------------ @@ -473,7 +543,7 @@ void CVehicle::AddTurnSpeed(const Vector3 & vel) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->AddVehicleTurnSpeed(m_ID, vel.x, vel.y, vel.z); + _Func->SetVehicleTurnSpeed(m_ID, vel.x, vel.y, vel.z, true, false); } // ------------------------------------------------------------------------------------------------ @@ -482,87 +552,87 @@ void CVehicle::AddTurnSpeedEx(Float32 x, Float32 y, Float32 z) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->AddVehicleTurnSpeed(m_ID, x, y, z); + _Func->SetVehicleTurnSpeed(m_ID, x, y, z, true, false); } // ------------------------------------------------------------------------------------------------ -const Vector3 & CVehicle::GetRelTurnSpeed() const +const Vector3 & CVehicle::GetRelativeTurnSpeed() const { // Validate the managed identifier Validate(); - // Clear previous relative turn speed information, if any + // Clear previous information, if any s_Vector3.Clear(); - // Query the server for the relative turn speed values - _Func->GetVehicleRelTurnSpeed(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); + // Query the server for the values + _Func->GetVehicleTurnSpeed(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z, true); // Return the requested information return s_Vector3; } // ------------------------------------------------------------------------------------------------ -void CVehicle::SetRelTurnSpeed(const Vector3 & vel) const +void CVehicle::SetRelativeTurnSpeed(const Vector3 & vel) const { // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehicleRelTurnSpeed(m_ID, vel.x, vel.y, vel.z); + _Func->SetVehicleTurnSpeed(m_ID, vel.x, vel.y, vel.z, false, true); } // ------------------------------------------------------------------------------------------------ -void CVehicle::SetRelTurnSpeedEx(Float32 x, Float32 y, Float32 z) const +void CVehicle::SetRelativeTurnSpeedEx(Float32 x, Float32 y, Float32 z) const { // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehicleRelTurnSpeed(m_ID, x, y, z); + _Func->SetVehicleTurnSpeed(m_ID, x, y, z, false, true); } // ------------------------------------------------------------------------------------------------ -void CVehicle::AddRelTurnSpeed(const Vector3 & vel) const +void CVehicle::AddRelativeTurnSpeed(const Vector3 & vel) const { // Validate the managed identifier Validate(); // Perform the requested operation - _Func->AddVehicleRelTurnSpeed(m_ID, vel.x, vel.y, vel.z); + _Func->SetVehicleTurnSpeed(m_ID, vel.x, vel.y, vel.z, true, true); } // ------------------------------------------------------------------------------------------------ -void CVehicle::AddRelTurnSpeedEx(Float32 x, Float32 y, Float32 z) const +void CVehicle::AddRelativeTurnSpeedEx(Float32 x, Float32 y, Float32 z) const { // Validate the managed identifier Validate(); // Perform the requested operation - _Func->AddVehicleRelTurnSpeed(m_ID, x, y, z); + _Func->SetVehicleTurnSpeed(m_ID, x, y, z, true, true); } // ------------------------------------------------------------------------------------------------ -const Vector4 & CVehicle::GetSpawnPosition() const +const Vector3 & CVehicle::GetSpawnPosition() const { // Validate the managed identifier Validate(); - // Clear previous spawn position information, if any - s_Vector4.Clear(); - // Query the server for the spawn position values - _Func->GetVehicleSpawnPos(m_ID, &s_Vector4.x, &s_Vector4.y, &s_Vector4.z, &s_Vector4.w); + // Clear previous information, if any + s_Vector3.Clear(); + // Query the server for the values + _Func->GetVehicleSpawnPosition(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); // Return the requested information - return s_Vector4; + return s_Vector3; } // ------------------------------------------------------------------------------------------------ -void CVehicle::SetSpawnPosition(const Vector4 & pos) const +void CVehicle::SetSpawnPosition(const Vector3 & pos) const { // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehicleSpawnPos(m_ID, pos.x, pos.y, pos.z, pos.w); + _Func->SetVehicleSpawnPosition(m_ID, pos.x, pos.y, pos.z); } // ------------------------------------------------------------------------------------------------ -void CVehicle::SetSpawnPositionEx(Float32 x, Float32 y, Float32 z, Float32 w) const +void CVehicle::SetSpawnPositionEx(Float32 x, Float32 y, Float32 z) const { // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehicleSpawnPos(m_ID, x, y, z, w); + _Func->SetVehicleSpawnPosition(m_ID, x, y, z); } // ------------------------------------------------------------------------------------------------ @@ -570,10 +640,10 @@ const Quaternion & CVehicle::GetSpawnRotation() const { // Validate the managed identifier Validate(); - // Clear previous spawn rotation information, if any + // Clear previous information, if any s_Quaternion.Clear(); - // Query the server for the spawn rotation values - _Func->GetVehicleSpawnRot(m_ID, &s_Quaternion.x, &s_Quaternion.y, &s_Quaternion.z, &s_Quaternion.w); + // Query the server for the values + _Func->GetVehicleSpawnRotation(m_ID, &s_Quaternion.x, &s_Quaternion.y, &s_Quaternion.z, &s_Quaternion.w); // Return the requested information return s_Quaternion; } @@ -584,7 +654,7 @@ void CVehicle::SetSpawnRotation(const Quaternion & rot) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehicleSpawnRot(m_ID, rot.x, rot.y, rot.z, rot.w); + _Func->SetVehicleSpawnRotation(m_ID, rot.x, rot.y, rot.z, rot.w); } // ------------------------------------------------------------------------------------------------ @@ -593,7 +663,7 @@ void CVehicle::SetSpawnRotationEx(Float32 x, Float32 y, Float32 z, Float32 w) co // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehicleSpawnRot(m_ID, x, y, z, w); + _Func->SetVehicleSpawnRotation(m_ID, x, y, z, w); } // ------------------------------------------------------------------------------------------------ @@ -601,10 +671,10 @@ const Vector3 & CVehicle::GetSpawnRotationEuler() const { // Validate the managed identifier Validate(); - // Clear previous rotation information, if any + // Clear previous information, if any s_Vector3.Clear(); // Query the server for the rotation values - _Func->GetVehicleSpawnRotEuler(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); + _Func->GetVehicleSpawnRotationEuler(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z); // Return the requested information return s_Vector3; } @@ -615,7 +685,7 @@ void CVehicle::SetSpawnRotationEuler(const Vector3 & rot) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehicleSpawnRotEuler(m_ID, rot.x, rot.y, rot.z); + _Func->SetVehicleSpawnRotationEuler(m_ID, rot.x, rot.y, rot.z); } // ------------------------------------------------------------------------------------------------ @@ -624,11 +694,11 @@ void CVehicle::SetSpawnRotationEulerEx(Float32 x, Float32 y, Float32 z) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehicleSpawnRotEuler(m_ID, x, y, z); + _Func->SetVehicleSpawnRotationEuler(m_ID, x, y, z); } // ------------------------------------------------------------------------------------------------ -Uint32 CVehicle::GetRespawnTimer() const +Uint32 CVehicle::GetIdleRespawnTimer() const { // Validate the managed identifier Validate(); @@ -637,12 +707,12 @@ Uint32 CVehicle::GetRespawnTimer() const } // ------------------------------------------------------------------------------------------------ -void CVehicle::SetRespawnTimer(Uint32 timer) const +void CVehicle::SetIdleRespawnTimer(Uint32 millis) const { // Validate the managed identifier Validate(); // Perform the requested operation - _Func->SetVehicleIdleRespawnTimer(m_ID, timer); + _Func->SetVehicleIdleRespawnTimer(m_ID, millis); } // ------------------------------------------------------------------------------------------------ @@ -671,7 +741,7 @@ Int32 CVehicle::GetPrimaryColor() const // The color value Int32 primary = -1; // Query the server for the requested color - _Func->GetVehicleColour(m_ID, &primary, NULL); + _Func->GetVehicleColour(m_ID, &primary, nullptr); // Return the requested information return primary; } @@ -684,7 +754,7 @@ void CVehicle::SetPrimaryColor(Int32 col) const // The unchanged color value Int32 secondary; // Query the server for the unchanged color - _Func->GetVehicleColour(m_ID, NULL, &secondary); + _Func->GetVehicleColour(m_ID, nullptr, &secondary); // Perform the requested operation _Func->SetVehicleColour(m_ID, col, secondary); } @@ -697,7 +767,7 @@ Int32 CVehicle::GetSecondaryColor() const // The color value Int32 secondary = -1; // Query the server for the requested color - _Func->GetVehicleColour(m_ID, NULL, &secondary); + _Func->GetVehicleColour(m_ID, nullptr, &secondary); // Return the requested information return secondary; } @@ -710,7 +780,7 @@ void CVehicle::SetSecondaryColor(Int32 col) const // The unchanged color value Int32 primary; // Query the server for the unchanged color - _Func->GetVehicleColour(m_ID, &primary, NULL); + _Func->GetVehicleColour(m_ID, &primary, nullptr); // Perform the requested operation _Func->SetVehicleColour(m_ID, primary, col); } @@ -724,24 +794,6 @@ void CVehicle::SetColors(Int32 primary, Int32 secondary) const _Func->SetVehicleColour(m_ID, primary, secondary); } -// ------------------------------------------------------------------------------------------------ -bool CVehicle::GetLocked() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->GetVehicleDoorsLocked(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -void CVehicle::SetLocked(bool toggle) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->SetVehicleDoorsLocked(m_ID, toggle); -} - // ------------------------------------------------------------------------------------------------ Int32 CVehicle::GetPartStatus(Int32 part) const { @@ -796,42 +848,6 @@ void CVehicle::SetDamageData(Uint32 data) const _Func->SetVehicleDamageData(m_ID, data); } -// ------------------------------------------------------------------------------------------------ -bool CVehicle::GetAlarm() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->GetVehicleAlarm(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -void CVehicle::SetAlarm(bool toggle) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->SetVehicleAlarm(m_ID, toggle); -} - -// ------------------------------------------------------------------------------------------------ -bool CVehicle::GetLights() const -{ - // Validate the managed identifier - Validate(); - // Return the requested information - return _Func->GetVehicleLights(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -void CVehicle::SetLights(bool toggle) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->SetVehicleLights(m_ID, toggle); -} - // ------------------------------------------------------------------------------------------------ Int32 CVehicle::GetRadio() const { @@ -851,61 +867,46 @@ void CVehicle::SetRadio(Int32 radio) const } // ------------------------------------------------------------------------------------------------ -bool CVehicle::GetRadioLocked() const +const Vector2 & CVehicle::GetTurretRotation() const { // Validate the managed identifier Validate(); + // Clear previous information, if any + s_Vector2.Clear(); + // Query the server for the values + _Func->GetVehicleTurretRotation(m_ID, &s_Vector2.x, &s_Vector2.y); // Return the requested information - return _Func->IsVehicleRadioLocked(m_ID); + return s_Vector2; } // ------------------------------------------------------------------------------------------------ -void CVehicle::SetRadioLocked(bool toggle) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->SetVehicleRadioLocked(m_ID, toggle); -} - -// ------------------------------------------------------------------------------------------------ -bool CVehicle::GetGhostState() const +Float32 CVehicle::GetHorizontalTurretRotation() const { // Validate the managed identifier Validate(); + // Where the rotation value is retrieved + Float32 rot = 0.0f; + // Query the server for the turret rotation value + _Func->GetVehicleTurretRotation(m_ID, &rot, nullptr); // Return the requested information - return _Func->GetVehicleGhostState(m_ID); + return rot; } // ------------------------------------------------------------------------------------------------ -void CVehicle::SetGhostState(bool toggle) const +Float32 CVehicle::GetVerticalTurretRotation() const { // Validate the managed identifier Validate(); - // Perform the requested operation - _Func->SetVehicleGhostState(m_ID, toggle); + // Where the rotation value is retrieved + Float32 rot = 0.0f; + // Query the server for the turret rotation value + _Func->GetVehicleTurretRotation(m_ID, nullptr, &rot); + // Return the requested information + return rot; } // ------------------------------------------------------------------------------------------------ -void CVehicle::ResetHandling() const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->ResetInstHandling(m_ID); -} - -// ------------------------------------------------------------------------------------------------ -void CVehicle::ResetHandling(Int32 rule) const -{ - // Validate the managed identifier - Validate(); - // Perform the requested operation - _Func->ResetInstHandlingRule(m_ID, rule); -} - -// ------------------------------------------------------------------------------------------------ -bool CVehicle::ExistsHandling(Int32 rule) const +bool CVehicle::ExistsHandlingRule(Int32 rule) const { // Validate the managed identifier Validate(); @@ -914,7 +915,7 @@ bool CVehicle::ExistsHandling(Int32 rule) const } // ------------------------------------------------------------------------------------------------ -Float32 CVehicle::GetHandlingData(Int32 rule) const +Float32 CVehicle::GetHandlingRule(Int32 rule) const { // Validate the managed identifier Validate(); @@ -923,7 +924,7 @@ Float32 CVehicle::GetHandlingData(Int32 rule) const } // ------------------------------------------------------------------------------------------------ -void CVehicle::SetHandlingData(Int32 rule, Float32 data) const +void CVehicle::SetHandlingRule(Int32 rule, Float32 data) const { // Validate the managed identifier Validate(); @@ -932,7 +933,25 @@ void CVehicle::SetHandlingData(Int32 rule, Float32 data) const } // ------------------------------------------------------------------------------------------------ -void CVehicle::Embark(CPlayer & player) const +void CVehicle::ResetHandlingRule(Int32 rule) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->ResetInstHandlingRule(m_ID, rule); +} + +// ------------------------------------------------------------------------------------------------ +void CVehicle::ResetHandlings() const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->ResetInstHandling(m_ID); +} + +// ------------------------------------------------------------------------------------------------ +bool CVehicle::Embark(CPlayer & player) const { // Is the specified player even valid? if (!player.IsActive()) @@ -942,11 +961,12 @@ void CVehicle::Embark(CPlayer & player) const // Validate the managed identifier Validate(); // Perform the requested operation - _Func->PutPlayerInVehicle(player.GetID(), m_ID, 0, true, true); + return (_Func->PutPlayerInVehicle(player.GetID(), m_ID, 0, true, true) + != vcmpErrorRequestDenied); } // ------------------------------------------------------------------------------------------------ -void CVehicle::Embark(CPlayer & player, Int32 slot, bool allocate, bool warp) const +bool CVehicle::Embark(CPlayer & player, Int32 slot, bool allocate, bool warp) const { // Is the specified player even valid? if (!player.IsActive()) @@ -956,262 +976,551 @@ void CVehicle::Embark(CPlayer & player, Int32 slot, bool allocate, bool warp) co // Validate the managed identifier Validate(); // Perform the requested operation - _Func->PutPlayerInVehicle(player.GetID(), m_ID, slot, allocate, warp); + return (_Func->PutPlayerInVehicle(player.GetID(), m_ID, slot, allocate, warp) + != vcmpErrorRequestDenied); } // ------------------------------------------------------------------------------------------------ -Float32 CVehicle::GetPosX() const +Float32 CVehicle::GetPositionX() const { // Validate the managed identifier Validate(); - // Clear previous position information, if any + // Clear previous information, if any s_Vector3.x = 0; // Query the server for the requested component value - _Func->GetVehiclePos(m_ID, &s_Vector3.x, NULL, NULL); + _Func->GetVehiclePosition(m_ID, &s_Vector3.x, nullptr, nullptr); // Return the requested information return s_Vector3.x; } // ------------------------------------------------------------------------------------------------ -Float32 CVehicle::GetPosY() const +Float32 CVehicle::GetPositionY() const { // Validate the managed identifier Validate(); - // Clear previous position information, if any + // Clear previous information, if any s_Vector3.y = 0; // Query the server for the requested component value - _Func->GetVehiclePos(m_ID, NULL, &s_Vector3.y, NULL); + _Func->GetVehiclePosition(m_ID, nullptr, &s_Vector3.y, nullptr); // Return the requested information return s_Vector3.y; } // ------------------------------------------------------------------------------------------------ -Float32 CVehicle::GetPosZ() const +Float32 CVehicle::GetPositionZ() const { // Validate the managed identifier Validate(); - // Clear previous position information, if any + // Clear previous information, if any s_Vector3.z = 0; // Query the server for the requested component value - _Func->GetVehiclePos(m_ID, NULL, NULL, &s_Vector3.z); + _Func->GetVehiclePosition(m_ID, nullptr, nullptr, &s_Vector3.z); // Return the requested information return s_Vector3.z; } // ------------------------------------------------------------------------------------------------ -void CVehicle::SetPosX(Float32 x) const +void CVehicle::SetPositionX(Float32 x) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetVehiclePos(m_ID, NULL, &s_Vector3.y, &s_Vector3.z); + _Func->GetVehiclePosition(m_ID, nullptr, &s_Vector3.y, &s_Vector3.z); // Perform the requested operation - _Func->SetVehiclePos(m_ID, x, s_Vector3.y, s_Vector3.z, false); + _Func->SetVehiclePosition(m_ID, x, s_Vector3.y, s_Vector3.z, false); } // ------------------------------------------------------------------------------------------------ -void CVehicle::SetPosY(Float32 y) const +void CVehicle::SetPositionY(Float32 y) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetVehiclePos(m_ID, &s_Vector3.x, NULL, &s_Vector3.z); + _Func->GetVehiclePosition(m_ID, &s_Vector3.x, nullptr, &s_Vector3.z); // Perform the requested operation - _Func->SetVehiclePos(m_ID, s_Vector3.x, y, s_Vector3.z, false); + _Func->SetVehiclePosition(m_ID, s_Vector3.x, y, s_Vector3.z, false); } // ------------------------------------------------------------------------------------------------ -void CVehicle::SetPosZ(Float32 z) const +void CVehicle::SetPositionZ(Float32 z) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetVehiclePos(m_ID, &s_Vector3.x, &s_Vector3.y, NULL); + _Func->GetVehiclePosition(m_ID, &s_Vector3.x, &s_Vector3.y, nullptr); // Perform the requested operation - _Func->SetVehiclePos(m_ID, s_Vector3.z, s_Vector3.y, z, false); + _Func->SetVehiclePosition(m_ID, s_Vector3.z, s_Vector3.y, z, false); } // ------------------------------------------------------------------------------------------------ -Float32 CVehicle::GetRotX() const +Float32 CVehicle::GetRotationX() const { // Validate the managed identifier Validate(); - // Clear previous rotation information, if any + // Clear previous information, if any s_Quaternion.x = 0; // Query the server for the requested component value - _Func->GetVehicleRot(m_ID, &s_Quaternion.x, NULL, NULL, NULL); + _Func->GetVehicleRotation(m_ID, &s_Quaternion.x, nullptr, nullptr, nullptr); // Return the requested information return s_Quaternion.x; } // ------------------------------------------------------------------------------------------------ -Float32 CVehicle::GetRotY() const +Float32 CVehicle::GetRotationY() const { // Validate the managed identifier Validate(); - // Clear previous rotation information, if any + // Clear previous information, if any s_Quaternion.y = 0; // Query the server for the requested component value - _Func->GetVehicleRot(m_ID, NULL, &s_Quaternion.y, NULL, NULL); + _Func->GetVehicleRotation(m_ID, nullptr, &s_Quaternion.y, nullptr, nullptr); // Return the requested information return s_Quaternion.y; } // ------------------------------------------------------------------------------------------------ -Float32 CVehicle::GetRotZ() const +Float32 CVehicle::GetRotationZ() const { // Validate the managed identifier Validate(); - // Clear previous rotation information, if any + // Clear previous information, if any s_Quaternion.z = 0; // Query the server for the requested component value - _Func->GetVehicleRot(m_ID, NULL, NULL, &s_Quaternion.z, NULL); + _Func->GetVehicleRotation(m_ID, nullptr, nullptr, &s_Quaternion.z, nullptr); // Return the requested information return s_Quaternion.z; } // ------------------------------------------------------------------------------------------------ -Float32 CVehicle::GetRotW() const +Float32 CVehicle::GetRotationW() const { // Validate the managed identifier Validate(); - // Clear previous rotation information, if any + // Clear previous information, if any s_Quaternion.w = 0; // Query the server for the requested component value - _Func->GetVehicleRot(m_ID, NULL, NULL, NULL, &s_Quaternion.w); + _Func->GetVehicleRotation(m_ID, nullptr, nullptr, nullptr, &s_Quaternion.w); // Return the requested information return s_Quaternion.w; } // ------------------------------------------------------------------------------------------------ -void CVehicle::SetRotX(Float32 x) const +void CVehicle::SetRotationX(Float32 x) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetVehicleRot(m_ID, NULL, &s_Quaternion.y, &s_Quaternion.z, &s_Quaternion.w); + _Func->GetVehicleRotation(m_ID, nullptr, &s_Quaternion.y, &s_Quaternion.z, &s_Quaternion.w); // Perform the requested operation - _Func->SetVehicleRot(m_ID, x, s_Quaternion.y, s_Quaternion.z, s_Quaternion.w); + _Func->SetVehicleRotation(m_ID, x, s_Quaternion.y, s_Quaternion.z, s_Quaternion.w); } // ------------------------------------------------------------------------------------------------ -void CVehicle::SetRotY(Float32 y) const +void CVehicle::SetRotationY(Float32 y) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetVehicleRot(m_ID, &s_Quaternion.x, NULL, &s_Quaternion.z, &s_Quaternion.w); + _Func->GetVehicleRotation(m_ID, &s_Quaternion.x, nullptr, &s_Quaternion.z, &s_Quaternion.w); // Perform the requested operation - _Func->SetVehicleRot(m_ID, s_Quaternion.x, y, s_Quaternion.z, s_Quaternion.w); + _Func->SetVehicleRotation(m_ID, s_Quaternion.x, y, s_Quaternion.z, s_Quaternion.w); } // ------------------------------------------------------------------------------------------------ -void CVehicle::SetRotZ(Float32 z) const +void CVehicle::SetRotationZ(Float32 z) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetVehicleRot(m_ID, &s_Quaternion.x, &s_Quaternion.y, NULL, &s_Quaternion.w); + _Func->GetVehicleRotation(m_ID, &s_Quaternion.x, &s_Quaternion.y, nullptr, &s_Quaternion.w); // Perform the requested operation - _Func->SetVehicleRot(m_ID, s_Quaternion.x, s_Quaternion.y, z, s_Quaternion.w); + _Func->SetVehicleRotation(m_ID, s_Quaternion.x, s_Quaternion.y, z, s_Quaternion.w); } // ------------------------------------------------------------------------------------------------ -void CVehicle::SetRotW(Float32 w) const +void CVehicle::SetRotationW(Float32 w) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetVehicleRot(m_ID, &s_Quaternion.x, &s_Quaternion.y, &s_Quaternion.z, NULL); + _Func->GetVehicleRotation(m_ID, &s_Quaternion.x, &s_Quaternion.y, &s_Quaternion.z, nullptr); // Perform the requested operation - _Func->SetVehicleRot(m_ID, s_Quaternion.x, s_Quaternion.y, s_Quaternion.z, w); + _Func->SetVehicleRotation(m_ID, s_Quaternion.x, s_Quaternion.y, s_Quaternion.z, w); } // ------------------------------------------------------------------------------------------------ -Float32 CVehicle::GetERotX() const +Float32 CVehicle::GetEulerRotationX() const { // Validate the managed identifier Validate(); - // Clear previous rotation information, if any + // Clear previous information, if any s_Vector3.x = 0; // Query the server for the requested component value - _Func->GetVehicleRotEuler(m_ID, &s_Vector3.x, NULL, NULL); + _Func->GetVehicleRotationEuler(m_ID, &s_Vector3.x, nullptr, nullptr); // Return the requested information return s_Vector3.x; } // ------------------------------------------------------------------------------------------------ -Float32 CVehicle::GetERotY() const +Float32 CVehicle::GetEulerRotationY() const { // Validate the managed identifier Validate(); - // Clear previous rotation information, if any + // Clear previous information, if any s_Vector3.y = 0; // Query the server for the requested component value - _Func->GetVehicleRotEuler(m_ID, NULL, &s_Vector3.y, NULL); + _Func->GetVehicleRotationEuler(m_ID, nullptr, &s_Vector3.y, nullptr); // Return the requested information return s_Vector3.y; } // ------------------------------------------------------------------------------------------------ -Float32 CVehicle::GetERotZ() const +Float32 CVehicle::GetEulerRotationZ() const { // Validate the managed identifier Validate(); - // Clear previous rotation information, if any + // Clear previous information, if any s_Vector3.z = 0; // Query the server for the requested component value - _Func->GetVehicleRotEuler(m_ID, NULL, NULL, &s_Vector3.z); + _Func->GetVehicleRotationEuler(m_ID, nullptr, nullptr, &s_Vector3.z); // Return the requested information return s_Vector3.z; } // ------------------------------------------------------------------------------------------------ -void CVehicle::SetERotX(Float32 x) const +void CVehicle::SetEulerRotationX(Float32 x) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetVehicleRotEuler(m_ID, NULL, &s_Vector3.y, &s_Vector3.z); + _Func->GetVehicleRotationEuler(m_ID, nullptr, &s_Vector3.y, &s_Vector3.z); // Perform the requested operation - _Func->SetVehicleRotEuler(m_ID, x, s_Vector3.y, s_Vector3.z); + _Func->SetVehicleRotationEuler(m_ID, x, s_Vector3.y, s_Vector3.z); } // ------------------------------------------------------------------------------------------------ -void CVehicle::SetERotY(Float32 y) const +void CVehicle::SetEulerRotationY(Float32 y) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetVehicleRotEuler(m_ID, &s_Vector3.x, NULL, &s_Vector3.z); + _Func->GetVehicleRotationEuler(m_ID, &s_Vector3.x, nullptr, &s_Vector3.z); // Perform the requested operation - _Func->SetVehicleRotEuler(m_ID, s_Vector3.x, y, s_Vector3.z); + _Func->SetVehicleRotationEuler(m_ID, s_Vector3.x, y, s_Vector3.z); } // ------------------------------------------------------------------------------------------------ -void CVehicle::SetERotZ(Float32 z) const +void CVehicle::SetEulerRotationZ(Float32 z) const { // Validate the managed identifier Validate(); // Retrieve the current values for unchanged components - _Func->GetVehicleRotEuler(m_ID, &s_Vector3.x, &s_Vector3.y, NULL); + _Func->GetVehicleRotationEuler(m_ID, &s_Vector3.x, &s_Vector3.y, nullptr); // Perform the requested operation - _Func->SetVehicleRotEuler(m_ID, s_Vector3.z, s_Vector3.y, z); + _Func->SetVehicleRotationEuler(m_ID, s_Vector3.z, s_Vector3.y, z); +} + +// ------------------------------------------------------------------------------------------------ +Float32 CVehicle::GetSpeedX() const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Vector3.x = 0.0f; + // Query the server for the requested component value + _Func->GetVehicleSpeed(m_ID, &s_Vector3.x, nullptr, nullptr, false); + // Return the requested information + return s_Vector3.x; +} + +// ------------------------------------------------------------------------------------------------ +Float32 CVehicle::GetSpeedY() const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Vector3.y = 0.0f; + // Query the server for the requested component value + _Func->GetVehicleSpeed(m_ID, nullptr, &s_Vector3.y, nullptr, false); + // Return the requested information + return s_Vector3.y; +} + +// ------------------------------------------------------------------------------------------------ +Float32 CVehicle::GetSpeedZ() const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Vector3.z = 0.0f; + // Query the server for the requested component value + _Func->GetVehicleSpeed(m_ID, nullptr, nullptr, &s_Vector3.z, false); + // Return the requested information + return s_Vector3.z; +} + +// ------------------------------------------------------------------------------------------------ +void CVehicle::SetSpeedX(Float32 x) const +{ + // Validate the managed identifier + Validate(); + // Retrieve the current values for unchanged components + _Func->GetVehicleSpeed(m_ID, nullptr, &s_Vector3.y, &s_Vector3.z, false); + // Perform the requested operation + _Func->SetVehicleSpeed(m_ID, x, s_Vector3.y, s_Vector3.z, false, false); +} + +// ------------------------------------------------------------------------------------------------ +void CVehicle::SetSpeedY(Float32 y) const +{ + // Validate the managed identifier + Validate(); + // Retrieve the current values for unchanged components + _Func->GetVehicleSpeed(m_ID, &s_Vector3.x, nullptr, &s_Vector3.z, false); + // Perform the requested operation + _Func->SetVehicleSpeed(m_ID, s_Vector3.x, y, s_Vector3.z, false, false); +} + +// ------------------------------------------------------------------------------------------------ +void CVehicle::SetSpeedZ(Float32 z) const +{ + // Validate the managed identifier + Validate(); + // Retrieve the current values for unchanged components + _Func->GetVehicleSpeed(m_ID, &s_Vector3.x, &s_Vector3.y, nullptr, false); + // Perform the requested operation + _Func->SetVehicleSpeed(m_ID, s_Vector3.z, s_Vector3.y, z, false, false); +} + +// ------------------------------------------------------------------------------------------------ +Float32 CVehicle::GetRelativeSpeedX() const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Vector3.x = 0.0f; + // Query the server for the requested component value + _Func->GetVehicleSpeed(m_ID, &s_Vector3.x, nullptr, nullptr, true); + // Return the requested information + return s_Vector3.x; +} + +// ------------------------------------------------------------------------------------------------ +Float32 CVehicle::GetRelativeSpeedY() const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Vector3.y = 0.0f; + // Query the server for the requested component value + _Func->GetVehicleSpeed(m_ID, nullptr, &s_Vector3.y, nullptr, true); + // Return the requested information + return s_Vector3.y; +} + +// ------------------------------------------------------------------------------------------------ +Float32 CVehicle::GetRelativeSpeedZ() const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Vector3.z = 0.0f; + // Query the server for the requested component value + _Func->GetVehicleSpeed(m_ID, nullptr, nullptr, &s_Vector3.z, true); + // Return the requested information + return s_Vector3.z; +} + +// ------------------------------------------------------------------------------------------------ +void CVehicle::SetRelativeSpeedX(Float32 x) const +{ + // Validate the managed identifier + Validate(); + // Retrieve the current values for unchanged components + _Func->GetVehicleSpeed(m_ID, nullptr, &s_Vector3.y, &s_Vector3.z, true); + // Perform the requested operation + _Func->SetVehicleSpeed(m_ID, x, s_Vector3.y, s_Vector3.z, false, true); +} + +// ------------------------------------------------------------------------------------------------ +void CVehicle::SetRelativeSpeedY(Float32 y) const +{ + // Validate the managed identifier + Validate(); + // Retrieve the current values for unchanged components + _Func->GetVehicleSpeed(m_ID, &s_Vector3.x, nullptr, &s_Vector3.z, true); + // Perform the requested operation + _Func->SetVehicleSpeed(m_ID, s_Vector3.x, y, s_Vector3.z, false, true); +} + +// ------------------------------------------------------------------------------------------------ +void CVehicle::SetRelativeSpeedZ(Float32 z) const +{ + // Validate the managed identifier + Validate(); + // Retrieve the current values for unchanged components + _Func->GetVehicleSpeed(m_ID, &s_Vector3.x, &s_Vector3.y, nullptr, true); + // Perform the requested operation + _Func->SetVehicleSpeed(m_ID, s_Vector3.z, s_Vector3.y, z, false, true); +} + +// ------------------------------------------------------------------------------------------------ +Float32 CVehicle::GetTurnSpeedX() const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Vector3.x = 0.0f; + // Query the server for the requested component value + _Func->GetVehicleTurnSpeed(m_ID, &s_Vector3.x, nullptr, nullptr, false); + // Return the requested information + return s_Vector3.x; +} + +// ------------------------------------------------------------------------------------------------ +Float32 CVehicle::GetTurnSpeedY() const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Vector3.y = 0.0f; + // Query the server for the requested component value + _Func->GetVehicleTurnSpeed(m_ID, nullptr, &s_Vector3.y, nullptr, false); + // Return the requested information + return s_Vector3.y; +} + +// ------------------------------------------------------------------------------------------------ +Float32 CVehicle::GetTurnSpeedZ() const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Vector3.z = 0.0f; + // Query the server for the requested component value + _Func->GetVehicleTurnSpeed(m_ID, nullptr, nullptr, &s_Vector3.z, false); + // Return the requested information + return s_Vector3.z; +} + +// ------------------------------------------------------------------------------------------------ +void CVehicle::SetTurnSpeedX(Float32 x) const +{ + // Validate the managed identifier + Validate(); + // Retrieve the current values for unchanged components + _Func->GetVehicleTurnSpeed(m_ID, nullptr, &s_Vector3.y, &s_Vector3.z, false); + // Perform the requested operation + _Func->SetVehicleTurnSpeed(m_ID, x, s_Vector3.y, s_Vector3.z, false, false); +} + +// ------------------------------------------------------------------------------------------------ +void CVehicle::SetTurnSpeedY(Float32 y) const +{ + // Validate the managed identifier + Validate(); + // Retrieve the current values for unchanged components + _Func->GetVehicleTurnSpeed(m_ID, &s_Vector3.x, nullptr, &s_Vector3.z, false); + // Perform the requested operation + _Func->SetVehicleTurnSpeed(m_ID, s_Vector3.x, y, s_Vector3.z, false, false); +} + +// ------------------------------------------------------------------------------------------------ +void CVehicle::SetTurnSpeedZ(Float32 z) const +{ + // Validate the managed identifier + Validate(); + // Retrieve the current values for unchanged components + _Func->GetVehicleTurnSpeed(m_ID, &s_Vector3.x, &s_Vector3.y, nullptr, false); + // Perform the requested operation + _Func->SetVehicleTurnSpeed(m_ID, s_Vector3.z, s_Vector3.y, z, false, false); +} + +// ------------------------------------------------------------------------------------------------ +Float32 CVehicle::GetRelativeTurnSpeedX() const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Vector3.x = 0.0f; + // Query the server for the requested component value + _Func->GetVehicleTurnSpeed(m_ID, &s_Vector3.x, nullptr, nullptr, true); + // Return the requested information + return s_Vector3.x; +} + +// ------------------------------------------------------------------------------------------------ +Float32 CVehicle::GetRelativeTurnSpeedY() const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Vector3.y = 0.0f; + // Query the server for the requested component value + _Func->GetVehicleTurnSpeed(m_ID, nullptr, &s_Vector3.y, nullptr, true); + // Return the requested information + return s_Vector3.y; +} + +// ------------------------------------------------------------------------------------------------ +Float32 CVehicle::GetRelativeTurnSpeedZ() const +{ + // Validate the managed identifier + Validate(); + // Clear previous information, if any + s_Vector3.z = 0.0f; + // Query the server for the requested component value + _Func->GetVehicleTurnSpeed(m_ID, nullptr, nullptr, &s_Vector3.z, true); + // Return the requested information + return s_Vector3.z; +} + +// ------------------------------------------------------------------------------------------------ +void CVehicle::SetRelativeTurnSpeedX(Float32 x) const +{ + // Validate the managed identifier + Validate(); + // Retrieve the current values for unchanged components + _Func->GetVehicleTurnSpeed(m_ID, nullptr, &s_Vector3.y, &s_Vector3.z, true); + // Perform the requested operation + _Func->SetVehicleTurnSpeed(m_ID, x, s_Vector3.y, s_Vector3.z, false, true); +} + +// ------------------------------------------------------------------------------------------------ +void CVehicle::SetRelativeTurnSpeedY(Float32 y) const +{ + // Validate the managed identifier + Validate(); + // Retrieve the current values for unchanged components + _Func->GetVehicleTurnSpeed(m_ID, &s_Vector3.x, nullptr, &s_Vector3.z, true); + // Perform the requested operation + _Func->SetVehicleTurnSpeed(m_ID, s_Vector3.x, y, s_Vector3.z, false, true); +} + +// ------------------------------------------------------------------------------------------------ +void CVehicle::SetRelativeTurnSpeedZ(Float32 z) const +{ + // Validate the managed identifier + Validate(); + // Retrieve the current values for unchanged components + _Func->GetVehicleTurnSpeed(m_ID, &s_Vector3.x, &s_Vector3.y, nullptr, true); + // Perform the requested operation + _Func->SetVehicleTurnSpeed(m_ID, s_Vector3.z, s_Vector3.y, z, false, true); } // ------------------------------------------------------------------------------------------------ static Object & Vehicle_CreateEx(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, Float32 angle, Int32 primary, Int32 secondary) { - return _Core->NewVehicle(model, world, x, y, z, angle, primary, secondary, + return Core::Get().NewVehicle(model, world, x, y, z, angle, primary, secondary, SQMOD_CREATE_DEFAULT, NullObject()); } static Object & Vehicle_CreateEx(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, Float32 angle, Int32 primary, Int32 secondary, Int32 header, Object & payload) { - return _Core->NewVehicle(model, world, x, y, z, angle, primary, secondary, + return Core::Get().NewVehicle(model, world, x, y, z, angle, primary, secondary, header, payload); } @@ -1219,14 +1528,14 @@ static Object & Vehicle_CreateEx(Int32 model, Int32 world, Float32 x, Float32 y, static Object & Vehicle_Create(Int32 model, Int32 world, const Vector3 & pos, Float32 angle, Int32 primary, Int32 secondary) { - return _Core->NewVehicle(model, world, pos.x, pos.y, pos.z, angle, primary, secondary, + return Core::Get().NewVehicle(model, world, pos.x, pos.y, pos.z, angle, primary, secondary, SQMOD_CREATE_DEFAULT, NullObject()); } static Object & Vehicle_Create(Int32 model, Int32 world, const Vector3 & pos, Float32 angle, Int32 primary, Int32 secondary, Int32 header, Object & payload) { - return _Core->NewVehicle(model, world, pos.x, pos.y, pos.z, angle, primary, secondary, + return Core::Get().NewVehicle(model, world, pos.x, pos.y, pos.z, angle, primary, secondary, header, payload); } @@ -1239,8 +1548,8 @@ static const Object & Vehicle_FindByID(Int32 id) STHROWF("The specified vehicle identifier is invalid: %d", id); } // Obtain the ends of the entity pool - Core::Vehicles::const_iterator itr = _Core->GetVehicles().cbegin(); - Core::Vehicles::const_iterator end = _Core->GetVehicles().cend(); + Core::Vehicles::const_iterator itr = Core::Get().GetVehicles().cbegin(); + Core::Vehicles::const_iterator end = Core::Get().GetVehicles().cend(); // Process each entity in the pool for (; itr != end; ++itr) { @@ -1263,8 +1572,8 @@ static const Object & Vehicle_FindByTag(CSStr tag) STHROWF("The specified vehicle tag is invalid: null/empty"); } // Obtain the ends of the entity pool - Core::Vehicles::const_iterator itr = _Core->GetVehicles().cbegin(); - Core::Vehicles::const_iterator end = _Core->GetVehicles().cend(); + Core::Vehicles::const_iterator itr = Core::Get().GetVehicles().cbegin(); + Core::Vehicles::const_iterator end = Core::Get().GetVehicles().cend(); // Process each entity in the pool for (; itr != end; ++itr) { @@ -1284,8 +1593,8 @@ static Array Vehicle_FindActive() // Remember the initial stack size StackGuard sg; // Obtain the ends of the entity pool - Core::Vehicles::const_iterator itr = _Core->GetVehicles().cbegin(); - Core::Vehicles::const_iterator end = _Core->GetVehicles().cend(); + Core::Vehicles::const_iterator itr = Core::Get().GetVehicles().cbegin(); + Core::Vehicles::const_iterator end = Core::Get().GetVehicles().cend(); // Allocate an empty array on the stack sq_newarray(DefaultVM::Get(), 0); // Process each entity in the pool @@ -1340,73 +1649,86 @@ void Register_CVehicle(HSQUIRRELVM vm) .Prop(_SC("Position"), &CVehicle::GetPosition, &CVehicle::SetPosition) .Prop(_SC("Rot"), &CVehicle::GetRotation, &CVehicle::SetRotation) .Prop(_SC("Rotation"), &CVehicle::GetRotation, &CVehicle::SetRotation) - .Prop(_SC("ERot"), &CVehicle::GetRotationEuler, &CVehicle::SetRotationEuler) - .Prop(_SC("RotEuler"), &CVehicle::GetRotationEuler, &CVehicle::SetRotationEuler) - .Prop(_SC("RotationEuler"), &CVehicle::GetRotationEuler, &CVehicle::SetRotationEuler) + .Prop(_SC("EulerRot"), &CVehicle::GetRotationEuler, &CVehicle::SetRotationEuler) + .Prop(_SC("EulerRotation"), &CVehicle::GetRotationEuler, &CVehicle::SetRotationEuler) .Prop(_SC("Speed"), &CVehicle::GetSpeed, &CVehicle::SetSpeed) - .Prop(_SC("RelSpeed"), &CVehicle::GetRelSpeed, &CVehicle::SetRelSpeed) - .Prop(_SC("RelativeSpeed"), &CVehicle::GetRelSpeed, &CVehicle::SetRelSpeed) + .Prop(_SC("RelSpeed"), &CVehicle::GetRelativeSpeed, &CVehicle::SetRelativeSpeed) + .Prop(_SC("RelativeSpeed"), &CVehicle::GetRelativeSpeed, &CVehicle::SetRelativeSpeed) .Prop(_SC("TurnSpeed"), &CVehicle::GetTurnSpeed, &CVehicle::SetTurnSpeed) - .Prop(_SC("RelTurnSpeed"), &CVehicle::GetRelTurnSpeed, &CVehicle::SetRelTurnSpeed) - .Prop(_SC("RelativeTurnSpeed"), &CVehicle::GetRelTurnSpeed, &CVehicle::SetRelTurnSpeed) + .Prop(_SC("RelTurnSpeed"), &CVehicle::GetRelativeTurnSpeed, &CVehicle::SetRelativeTurnSpeed) + .Prop(_SC("RelativeTurnSpeed"), &CVehicle::GetRelativeTurnSpeed, &CVehicle::SetRelativeTurnSpeed) .Prop(_SC("SpawnPos"), &CVehicle::GetSpawnPosition, &CVehicle::SetSpawnPosition) .Prop(_SC("SpawnPosition"), &CVehicle::GetSpawnPosition, &CVehicle::SetSpawnPosition) .Prop(_SC("SpawnRot"), &CVehicle::GetSpawnRotation, &CVehicle::SetSpawnRotation) .Prop(_SC("SpawnRotation"), &CVehicle::GetSpawnRotation, &CVehicle::SetSpawnRotation) - .Prop(_SC("SpawnERot"), &CVehicle::GetSpawnRotationEuler, &CVehicle::SetSpawnRotationEuler) - .Prop(_SC("SpawnRotEuler"), &CVehicle::GetSpawnRotationEuler, &CVehicle::SetSpawnRotationEuler) - .Prop(_SC("SpawnRotationEuler"), &CVehicle::GetSpawnRotationEuler, &CVehicle::SetSpawnRotationEuler) - .Prop(_SC("RespawnTimer"), &CVehicle::GetRespawnTimer, &CVehicle::SetRespawnTimer) + .Prop(_SC("SpawnEulerRot"), &CVehicle::GetSpawnRotationEuler, &CVehicle::SetSpawnRotationEuler) + .Prop(_SC("SpawnEulerRotation"), &CVehicle::GetSpawnRotationEuler, &CVehicle::SetSpawnRotationEuler) + .Prop(_SC("IdleRespawnTimer"), &CVehicle::GetIdleRespawnTimer, &CVehicle::SetIdleRespawnTimer) .Prop(_SC("Health"), &CVehicle::GetHealth, &CVehicle::SetHealth) .Prop(_SC("PrimaryColor"), &CVehicle::GetPrimaryColor, &CVehicle::SetPrimaryColor) .Prop(_SC("SecondaryColor"), &CVehicle::GetSecondaryColor, &CVehicle::SetSecondaryColor) - .Prop(_SC("Locked"), &CVehicle::GetLocked, &CVehicle::SetLocked) .Prop(_SC("DamageData"), &CVehicle::GetDamageData, &CVehicle::SetDamageData) - .Prop(_SC("Alarm"), &CVehicle::GetAlarm, &CVehicle::SetAlarm) - .Prop(_SC("Lights"), &CVehicle::GetLights, &CVehicle::SetLights) .Prop(_SC("Radio"), &CVehicle::GetRadio, &CVehicle::SetRadio) - .Prop(_SC("RadioLocked"), &CVehicle::GetRadioLocked, &CVehicle::SetRadioLocked) - .Prop(_SC("Ghost"), &CVehicle::GetGhostState, &CVehicle::SetGhostState) - .Prop(_SC("GhostState"), &CVehicle::GetGhostState, &CVehicle::SetGhostState) - .Prop(_SC("X"), &CVehicle::GetPosX, &CVehicle::SetPosX) - .Prop(_SC("Y"), &CVehicle::GetPosY, &CVehicle::SetPosY) - .Prop(_SC("Z"), &CVehicle::GetPosZ, &CVehicle::SetPosZ) - .Prop(_SC("RX"), &CVehicle::GetRotX, &CVehicle::SetRotX) - .Prop(_SC("RY"), &CVehicle::GetRotY, &CVehicle::SetRotY) - .Prop(_SC("RZ"), &CVehicle::GetRotZ, &CVehicle::SetRotZ) - .Prop(_SC("RW"), &CVehicle::GetRotW, &CVehicle::SetRotW) - .Prop(_SC("EX"), &CVehicle::GetERotX, &CVehicle::SetERotX) - .Prop(_SC("EY"), &CVehicle::GetERotY, &CVehicle::SetERotY) - .Prop(_SC("EZ"), &CVehicle::GetERotZ, &CVehicle::SetERotZ) + .Prop(_SC("TurretRotation"), &CVehicle::GetTurretRotation) + .Prop(_SC("HorTurretRotation"), &CVehicle::GetHorizontalTurretRotation) + .Prop(_SC("HorizontalTurretRotation"), &CVehicle::GetHorizontalTurretRotation) + .Prop(_SC("VerTurretRotation"), &CVehicle::GetVerticalTurretRotation) + .Prop(_SC("VerticalTurretRotation"), &CVehicle::GetVerticalTurretRotation) + .Prop(_SC("PosX"), &CVehicle::GetPositionX, &CVehicle::SetPositionX) + .Prop(_SC("PosY"), &CVehicle::GetPositionY, &CVehicle::SetPositionY) + .Prop(_SC("PosZ"), &CVehicle::GetPositionZ, &CVehicle::SetPositionZ) + .Prop(_SC("RotX"), &CVehicle::GetRotationX, &CVehicle::SetRotationX) + .Prop(_SC("RotY"), &CVehicle::GetRotationY, &CVehicle::SetRotationY) + .Prop(_SC("RotZ"), &CVehicle::GetRotationZ, &CVehicle::SetRotationZ) + .Prop(_SC("RotW"), &CVehicle::GetRotationW, &CVehicle::SetRotationW) + .Prop(_SC("EulerX"), &CVehicle::GetEulerRotationX, &CVehicle::SetEulerRotationX) + .Prop(_SC("EulerY"), &CVehicle::GetEulerRotationY, &CVehicle::SetEulerRotationY) + .Prop(_SC("EulerZ"), &CVehicle::GetEulerRotationZ, &CVehicle::SetEulerRotationZ) + .Prop(_SC("SpeedX"), &CVehicle::GetSpeedX, &CVehicle::SetSpeedX) + .Prop(_SC("SpeedY"), &CVehicle::GetSpeedY, &CVehicle::SetSpeedY) + .Prop(_SC("SpeedZ"), &CVehicle::GetSpeedZ, &CVehicle::SetSpeedZ) + .Prop(_SC("RelSpeedX"), &CVehicle::GetRelativeSpeedX, &CVehicle::SetRelativeSpeedX) + .Prop(_SC("RelSpeedY"), &CVehicle::GetRelativeSpeedY, &CVehicle::SetRelativeSpeedY) + .Prop(_SC("RelSpeedZ"), &CVehicle::GetRelativeSpeedZ, &CVehicle::SetRelativeSpeedZ) + .Prop(_SC("TurnSpeedX"), &CVehicle::GetTurnSpeedX, &CVehicle::SetTurnSpeedX) + .Prop(_SC("TurnSpeedY"), &CVehicle::GetTurnSpeedY, &CVehicle::SetTurnSpeedY) + .Prop(_SC("TurnSpeedZ"), &CVehicle::GetTurnSpeedZ, &CVehicle::SetTurnSpeedZ) + .Prop(_SC("RelTurnSpeedX"), &CVehicle::GetRelativeTurnSpeedX, &CVehicle::SetRelativeTurnSpeedX) + .Prop(_SC("RelTurnSpeedY"), &CVehicle::GetRelativeTurnSpeedY, &CVehicle::SetRelativeTurnSpeedY) + .Prop(_SC("RelTurnSpeedZ"), &CVehicle::GetRelativeTurnSpeedZ, &CVehicle::SetRelativeTurnSpeedZ) // Member Methods .Func(_SC("StreamedFor"), &CVehicle::IsStreamedFor) + .Func(_SC("GetOption"), &CVehicle::GetOption) + .Func(_SC("SetOption"), &CVehicle::SetOption) + .Func(_SC("SetOptionEx"), &CVehicle::SetOptionEx) .Func(_SC("Occupant"), &CVehicle::GetOccupant) .Func(_SC("OccupantID"), &CVehicle::GetOccupantID) .Func(_SC("Respawn"), &CVehicle::Respawn) + .Func(_SC("Explode"), &CVehicle::Explode) .Func(_SC("SetRot"), &CVehicle::SetRotationEx) .Func(_SC("SetRotation"), &CVehicle::SetRotationEx) - .Func(_SC("SetERot"), &CVehicle::SetRotationEulerEx) - .Func(_SC("SetRotEuler"), &CVehicle::SetRotationEulerEx) - .Func(_SC("SetRotationEuler"), &CVehicle::SetRotationEulerEx) + .Func(_SC("SetEulerRot"), &CVehicle::SetRotationEulerEx) + .Func(_SC("SetEulerRotation"), &CVehicle::SetRotationEulerEx) .Func(_SC("SetSpeed"), &CVehicle::SetSpeedEx) - .Func(_SC("SetRelativeSpeed"), &CVehicle::SetRelSpeedEx) + .Func(_SC("SetRelativeSpeed"), &CVehicle::SetRelativeSpeedEx) .Func(_SC("SetTurnSpeed"), &CVehicle::SetTurnSpeedEx) - .Func(_SC("SetRelativeTurnSpeed"), &CVehicle::SetRelTurnSpeedEx) + .Func(_SC("SetRelativeTurnSpeed"), &CVehicle::SetRelativeTurnSpeedEx) .Func(_SC("SetSpawnPos"), &CVehicle::SetSpawnPositionEx) .Func(_SC("SetSpawnPosition"), &CVehicle::SetSpawnPositionEx) .Func(_SC("SetSpawnRot"), &CVehicle::SetSpawnRotationEx) .Func(_SC("SetSpawnRotation"), &CVehicle::SetSpawnRotationEx) - .Func(_SC("SetSpawnERot"), &CVehicle::SetSpawnRotationEulerEx) - .Func(_SC("SetSpawnRotEuler"), &CVehicle::SetSpawnRotationEulerEx) - .Func(_SC("SetSpawnRotationEuler"), &CVehicle::SetSpawnRotationEulerEx) + .Func(_SC("SetSpawnEulerRot"), &CVehicle::SetSpawnRotationEulerEx) + .Func(_SC("SetSpawnEulerRotation"), &CVehicle::SetSpawnRotationEulerEx) .Func(_SC("SetColors"), &CVehicle::SetColors) .Func(_SC("GetPartStatus"), &CVehicle::GetPartStatus) .Func(_SC("SetPartStatus"), &CVehicle::SetPartStatus) .Func(_SC("GetTyreStatus"), &CVehicle::GetTyreStatus) .Func(_SC("SetTyreStatus"), &CVehicle::SetTyreStatus) - .Func(_SC("ExistsHandling"), &CVehicle::ExistsHandling) - .Func(_SC("GetHandlingData"), &CVehicle::GetHandlingData) - .Func(_SC("SetHandlingData"), &CVehicle::SetHandlingData) + .Func(_SC("ExistsHandlingRule"), &CVehicle::ExistsHandlingRule) + .Func(_SC("GetHandlingRule"), &CVehicle::GetHandlingRule) + .Func(_SC("SetHandlingRule"), &CVehicle::SetHandlingRule) + .Func(_SC("ResetHandlingRule"), &CVehicle::ResetHandlingRule) + .Func(_SC("ResetHandlings"), &CVehicle::ResetHandlings) // Member Overloads .Overload< void (CVehicle::*)(const Vector3 &, bool) const > (_SC("SetPos"), &CVehicle::SetPositionEx) @@ -1425,24 +1747,24 @@ void Register_CVehicle(HSQUIRRELVM vm) .Overload< void (CVehicle::*)(Float32, Float32, Float32) const > (_SC("AddSpeed"), &CVehicle::AddSpeedEx) .Overload< void (CVehicle::*)(const Vector3 &) const > - (_SC("AddRelSpeed"), &CVehicle::AddRelSpeed) + (_SC("AddRelativeSpeed"), &CVehicle::AddRelativeSpeed) .Overload< void (CVehicle::*)(Float32, Float32, Float32) const > - (_SC("AddRelSpeed"), &CVehicle::AddRelSpeedEx) + (_SC("AddRelativeSpeed"), &CVehicle::AddRelativeSpeedEx) .Overload< void (CVehicle::*)(const Vector3 &) const > (_SC("AddTurnSpeed"), &CVehicle::AddTurnSpeed) .Overload< void (CVehicle::*)(Float32, Float32, Float32) const > (_SC("AddTurnSpeed"), &CVehicle::AddTurnSpeedEx) .Overload< void (CVehicle::*)(const Vector3 &) const > - (_SC("AddRelTurnSpeed"), &CVehicle::AddRelTurnSpeed) + (_SC("AddRelativeTurnSpeed"), &CVehicle::AddRelativeTurnSpeed) .Overload< void (CVehicle::*)(Float32, Float32, Float32) const > - (_SC("AddRelTurnSpeed"), &CVehicle::AddRelTurnSpeedEx) + (_SC("AddRelativeTurnSpeed"), &CVehicle::AddRelativeTurnSpeedEx) .Overload< void (CVehicle::*)(void) const > - (_SC("ResetHandling"), &CVehicle::ResetHandling) + (_SC("ResetHandling"), &CVehicle::ResetHandlings) .Overload< void (CVehicle::*)(Int32) const > - (_SC("ResetHandling"), &CVehicle::ResetHandling) - .Overload< void (CVehicle::*)(CPlayer &) const > + (_SC("ResetHandling"), &CVehicle::ResetHandlingRule) + .Overload< bool (CVehicle::*)(CPlayer &) const > (_SC("Embark"), &CVehicle::Embark) - .Overload< void (CVehicle::*)(CPlayer &, Int32, bool, bool) const > + .Overload< bool (CVehicle::*)(CPlayer &, Int32, bool, bool) const > (_SC("Embark"), &CVehicle::Embark) // Static Functions .StaticFunc(_SC("FindByID"), &Vehicle_FindByID) @@ -1457,6 +1779,7 @@ void Register_CVehicle(HSQUIRRELVM vm) (_SC("Create"), &Vehicle_Create) .StaticOverload< Object & (*)(Int32, Int32, const Vector3 &, Float32, Int32, Int32, Int32, Object &) > (_SC("Create"), &Vehicle_Create) + ); } diff --git a/source/Entity/Vehicle.hpp b/source/Entity/Vehicle.hpp index dbf1aab8..9c42e550 100644 --- a/source/Entity/Vehicle.hpp +++ b/source/Entity/Vehicle.hpp @@ -7,6 +7,14 @@ // ------------------------------------------------------------------------------------------------ namespace SqMod { +/* ------------------------------------------------------------------------------------------------ + * Circular locks employed by the vehicle manager. +*/ +enum VehicleCircularLocks +{ + VCL_EMIT_VEHICLE_OPTION = (1 << 0) +}; + /* ------------------------------------------------------------------------------------------------ * Manages a single vehicle entity. */ @@ -18,8 +26,8 @@ class CVehicle private: // -------------------------------------------------------------------------------------------- + static Vector2 s_Vector2; static Vector3 s_Vector3; - static Vector4 s_Vector4; static Quaternion s_Quaternion; /* -------------------------------------------------------------------------------------------- @@ -37,6 +45,11 @@ private: */ Object m_Data; + /* -------------------------------------------------------------------------------------------- + * Prevent events from triggering themselves. + */ + Uint32 m_CircularLocks; + /* -------------------------------------------------------------------------------------------- * Base constructor. */ @@ -167,6 +180,21 @@ public: */ bool IsStreamedFor(CPlayer & player) const; + /* -------------------------------------------------------------------------------------------- + * Retrieve the current option value of the managed vehicle entity. + */ + bool GetOption(Int32 option_id) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the current option value of the managed vehicle entity. + */ + void SetOption(Int32 option_id, bool toggle); + + /* -------------------------------------------------------------------------------------------- + * Modify the current option value of the managed vehicle entity. + */ + void SetOptionEx(Int32 option_id, bool toggle, Int32 header, Object & payload); + /* -------------------------------------------------------------------------------------------- * Retrieve the synchronization source of the managed vehicle entity. */ @@ -217,6 +245,11 @@ public: */ void SetImmunity(Int32 flags) const; + /* -------------------------------------------------------------------------------------------- + * Explode the managed vehicle entity. + */ + void Explode() const; + /* -------------------------------------------------------------------------------------------- * See whether the managed vehicle entity is wrecked. */ @@ -305,27 +338,27 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the relative speed of the managed vehicle entity. */ - const Vector3 & GetRelSpeed() const; + const Vector3 & GetRelativeSpeed() const; /* -------------------------------------------------------------------------------------------- * Modify the relative speed of the managed vehicle entity. */ - void SetRelSpeed(const Vector3 & vel) const; + void SetRelativeSpeed(const Vector3 & vel) const; /* -------------------------------------------------------------------------------------------- * Modify the relative speed of the managed vehicle entity. */ - void SetRelSpeedEx(Float32 x, Float32 y, Float32 z) const; + void SetRelativeSpeedEx(Float32 x, Float32 y, Float32 z) const; /* -------------------------------------------------------------------------------------------- * Modify the relative speed of the managed vehicle entity. */ - void AddRelSpeed(const Vector3 & vel) const; + void AddRelativeSpeed(const Vector3 & vel) const; /* -------------------------------------------------------------------------------------------- * Modify the relative speed of the managed vehicle entity. */ - void AddRelSpeedEx(Float32 x, Float32 y, Float32 z) const; + void AddRelativeSpeedEx(Float32 x, Float32 y, Float32 z) const; /* -------------------------------------------------------------------------------------------- * Retrieve the turn speed of the managed vehicle entity. @@ -355,42 +388,42 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the relative turn speed of the managed vehicle entity. */ - const Vector3 & GetRelTurnSpeed() const; + const Vector3 & GetRelativeTurnSpeed() const; /* -------------------------------------------------------------------------------------------- * Modify the relative turn speed of the managed vehicle entity. */ - void SetRelTurnSpeed(const Vector3 & vel) const; + void SetRelativeTurnSpeed(const Vector3 & vel) const; /* -------------------------------------------------------------------------------------------- * Modify the relative turn speed of the managed vehicle entity. */ - void SetRelTurnSpeedEx(Float32 x, Float32 y, Float32 z) const; + void SetRelativeTurnSpeedEx(Float32 x, Float32 y, Float32 z) const; /* -------------------------------------------------------------------------------------------- * Modify the relative turn speed of the managed vehicle entity. */ - void AddRelTurnSpeed(const Vector3 & vel) const; + void AddRelativeTurnSpeed(const Vector3 & vel) const; /* -------------------------------------------------------------------------------------------- * Modify the relative turn speed of the managed vehicle entity. */ - void AddRelTurnSpeedEx(Float32 x, Float32 y, Float32 z) const; + void AddRelativeTurnSpeedEx(Float32 x, Float32 y, Float32 z) const; /* -------------------------------------------------------------------------------------------- * Retrieve the spawn position of the managed vehicle entity. */ - const Vector4 & GetSpawnPosition() const; + const Vector3 & GetSpawnPosition() const; /* -------------------------------------------------------------------------------------------- * Modify the spawn position of the managed vehicle entity. */ - void SetSpawnPosition(const Vector4 & pos) const; + void SetSpawnPosition(const Vector3 & pos) const; /* -------------------------------------------------------------------------------------------- * Modify the spawn position of the managed vehicle entity. */ - void SetSpawnPositionEx(Float32 x, Float32 y, Float32 z, Float32 w) const; + void SetSpawnPositionEx(Float32 x, Float32 y, Float32 z) const; /* -------------------------------------------------------------------------------------------- * Retrieve the spawn rotation of the managed vehicle entity. @@ -425,12 +458,12 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the respawn timer of the managed vehicle entity. */ - Uint32 GetRespawnTimer() const; + Uint32 GetIdleRespawnTimer() const; /* -------------------------------------------------------------------------------------------- * Modify the respawn timer of the managed vehicle entity. */ - void SetRespawnTimer(Uint32 timer) const; + void SetIdleRespawnTimer(Uint32 millis) const; /* -------------------------------------------------------------------------------------------- * Retrieve the health of the managed vehicle entity. @@ -467,16 +500,6 @@ public: */ void SetColors(Int32 primary, Int32 secondary) const; - /* -------------------------------------------------------------------------------------------- - * See whether the managed vehicle entity is locked. - */ - bool GetLocked() const; - - /* -------------------------------------------------------------------------------------------- - * Set whether the managed vehicle entity is locked. - */ - void SetLocked(bool toggle) const; - /* -------------------------------------------------------------------------------------------- * Retrieve the part status of the managed vehicle entity. */ @@ -507,26 +530,6 @@ public: */ void SetDamageData(Uint32 data) const; - /* -------------------------------------------------------------------------------------------- - * See whether the managed vehicle entity has alarm. - */ - bool GetAlarm() const; - - /* -------------------------------------------------------------------------------------------- - * Set whether the managed vehicle entity has alarm. - */ - void SetAlarm(bool toggle) const; - - /* -------------------------------------------------------------------------------------------- - * See whether the managed vehicle entity has lights. - */ - bool GetLights() const; - - /* -------------------------------------------------------------------------------------------- - * Set whether the managed vehicle entity has lights. - */ - void SetLights(bool toggle) const; - /* -------------------------------------------------------------------------------------------- * Retrieve the radio of the managed vehicle entity. */ @@ -538,159 +541,274 @@ public: void SetRadio(Int32 radio) const; /* -------------------------------------------------------------------------------------------- - * See whether the managed vehicle entity has radio locked. + * Retrieve the turret rotation of the managed vehicle entity. */ - bool GetRadioLocked() const; + const Vector2 & GetTurretRotation() const; /* -------------------------------------------------------------------------------------------- - * Set whether the managed vehicle entity has radio locked. + * Retrieve the horizontal turret rotation of the managed vehicle entity. */ - void SetRadioLocked(bool toggle) const; + Float32 GetHorizontalTurretRotation() const; /* -------------------------------------------------------------------------------------------- - * See whether the managed vehicle entity is in ghost state. + * Retrieve the vertical turret rotation of the managed vehicle entity. */ - bool GetGhostState() const; - - /* -------------------------------------------------------------------------------------------- - * Set whether the managed vehicle entity is in ghost state. - */ - void SetGhostState(bool toggle) const; - - /* -------------------------------------------------------------------------------------------- - * Reset all the handling rules for the managed vehicle entity. - */ - void ResetHandling() const; - - /* -------------------------------------------------------------------------------------------- - * Reset the specified handling rule for the managed vehicle entity. - */ - void ResetHandling(Int32 rule) const; + Float32 GetVerticalTurretRotation() const; /* -------------------------------------------------------------------------------------------- * See whether the specified handling ruleexists in the managed vehicle entity. */ - bool ExistsHandling(Int32 rule) const; + bool ExistsHandlingRule(Int32 rule) const; /* -------------------------------------------------------------------------------------------- * Retrieve the handling data of the managed vehicle entity. */ - Float32 GetHandlingData(Int32 rule) const; + Float32 GetHandlingRule(Int32 rule) const; /* -------------------------------------------------------------------------------------------- * Modify the handling data of the managed vehicle entity. */ - void SetHandlingData(Int32 rule, Float32 data) const; + void SetHandlingRule(Int32 rule, Float32 data) const; + + /* -------------------------------------------------------------------------------------------- + * Reset the specified handling rule for the managed vehicle entity. + */ + void ResetHandlingRule(Int32 rule) const; + + /* -------------------------------------------------------------------------------------------- + * Reset all the handling rules for the managed vehicle entity. + */ + void ResetHandlings() const; /* -------------------------------------------------------------------------------------------- * Embark the specified player entity into the managed vehicle entity. */ - void Embark(CPlayer & player) const; + bool Embark(CPlayer & player) const; /* -------------------------------------------------------------------------------------------- * Embark the specified player entity into the managed vehicle entity. */ - void Embark(CPlayer & player, Int32 slot, bool allocate, bool warp) const; + bool Embark(CPlayer & player, Int32 slot, bool allocate, bool warp) const; /* -------------------------------------------------------------------------------------------- * Retrieve the position on the x axis of the managed vehicle entity. */ - Float32 GetPosX() const; + Float32 GetPositionX() const; /* -------------------------------------------------------------------------------------------- * Retrieve the position on the y axis of the managed vehicle entity. */ - Float32 GetPosY() const; + Float32 GetPositionY() const; /* -------------------------------------------------------------------------------------------- * Retrieve the position on the z axis of the managed vehicle entity. */ - Float32 GetPosZ() const; + Float32 GetPositionZ() const; /* -------------------------------------------------------------------------------------------- * Modify the position on the x axis of the managed vehicle entity. */ - void SetPosX(Float32 x) const; + void SetPositionX(Float32 x) const; /* -------------------------------------------------------------------------------------------- * Modify the position on the y axis of the managed vehicle entity. */ - void SetPosY(Float32 y) const; + void SetPositionY(Float32 y) const; /* -------------------------------------------------------------------------------------------- * Modify the position on the z axis of the managed vehicle entity. */ - void SetPosZ(Float32 z) const; + void SetPositionZ(Float32 z) const; /* -------------------------------------------------------------------------------------------- * Retrieve the rotation on the x axis of the managed vehicle entity. */ - Float32 GetRotX() const; + Float32 GetRotationX() const; /* -------------------------------------------------------------------------------------------- * Retrieve the rotation on the y axis of the managed vehicle entity. */ - Float32 GetRotY() const; + Float32 GetRotationY() const; /* -------------------------------------------------------------------------------------------- * Retrieve the rotation on the z axis of the managed vehicle entity. */ - Float32 GetRotZ() const; + Float32 GetRotationZ() const; /* -------------------------------------------------------------------------------------------- * Retrieve the rotation amount of the managed vehicle entity. */ - Float32 GetRotW() const; + Float32 GetRotationW() const; /* -------------------------------------------------------------------------------------------- * Modify the rotation on the x axis of the managed vehicle entity. */ - void SetRotX(Float32 x) const; + void SetRotationX(Float32 x) const; /* -------------------------------------------------------------------------------------------- * Modify the rotation on the y axis of the managed vehicle entity. */ - void SetRotY(Float32 y) const; + void SetRotationY(Float32 y) const; /* -------------------------------------------------------------------------------------------- * Modify the rotation on the z axis of the managed vehicle entity. */ - void SetRotZ(Float32 z) const; + void SetRotationZ(Float32 z) const; /* -------------------------------------------------------------------------------------------- * Modify the rotation amount of the managed vehicle entity. */ - void SetRotW(Float32 w) const; + void SetRotationW(Float32 w) const; /* -------------------------------------------------------------------------------------------- * Retrieve the euler rotation on the x axis of the managed vehicle entity. */ - Float32 GetERotX() const; + Float32 GetEulerRotationX() const; /* -------------------------------------------------------------------------------------------- * Retrieve the euler rotation on the y axis of the managed vehicle entity. */ - Float32 GetERotY() const; + Float32 GetEulerRotationY() const; /* -------------------------------------------------------------------------------------------- * Retrieve the euler rotation on the z axis of the managed vehicle entity. */ - Float32 GetERotZ() const; + Float32 GetEulerRotationZ() const; /* -------------------------------------------------------------------------------------------- * Modify the euler rotation on the x axis of the managed vehicle entity. */ - void SetERotX(Float32 x) const; + void SetEulerRotationX(Float32 x) const; /* -------------------------------------------------------------------------------------------- * Modify the euler rotation on the y axis of the managed vehicle entity. */ - void SetERotY(Float32 y) const; + void SetEulerRotationY(Float32 y) const; /* -------------------------------------------------------------------------------------------- * Modify the euler rotation on the z axis of the managed vehicle entity. */ - void SetERotZ(Float32 z) const; + void SetEulerRotationZ(Float32 z) const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the velocity on the x axis of the managed vehicle entity. + */ + Float32 GetSpeedX() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the velocity on the y axis of the managed vehicle entity. + */ + Float32 GetSpeedY() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the velocity on the z axis of the managed vehicle entity. + */ + Float32 GetSpeedZ() const; + + /* -------------------------------------------------------------------------------------------- + * Modify the velocity on the x axis of the managed vehicle entity. + */ + void SetSpeedX(Float32 x) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the velocity on the y axis of the managed vehicle entity. + */ + void SetSpeedY(Float32 y) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the velocity on the z axis of the managed vehicle entity. + */ + void SetSpeedZ(Float32 z) const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the relative velocity on the x axis of the managed vehicle entity. + */ + Float32 GetRelativeSpeedX() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the relative velocity on the y axis of the managed vehicle entity. + */ + Float32 GetRelativeSpeedY() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the relative velocity on the z axis of the managed vehicle entity. + */ + Float32 GetRelativeSpeedZ() const; + + /* -------------------------------------------------------------------------------------------- + * Modify the relative velocity on the x axis of the managed vehicle entity. + */ + void SetRelativeSpeedX(Float32 x) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the relative velocity on the y axis of the managed vehicle entity. + */ + void SetRelativeSpeedY(Float32 y) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the relative velocity on the z axis of the managed vehicle entity. + */ + void SetRelativeSpeedZ(Float32 z) const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the turn velocity on the x axis of the managed vehicle entity. + */ + Float32 GetTurnSpeedX() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the turn velocity on the y axis of the managed vehicle entity. + */ + Float32 GetTurnSpeedY() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the turn velocity on the z axis of the managed vehicle entity. + */ + Float32 GetTurnSpeedZ() const; + + /* -------------------------------------------------------------------------------------------- + * Modify the turn velocity on the x axis of the managed vehicle entity. + */ + void SetTurnSpeedX(Float32 x) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the turn velocity on the y axis of the managed vehicle entity. + */ + void SetTurnSpeedY(Float32 y) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the turn velocity on the z axis of the managed vehicle entity. + */ + void SetTurnSpeedZ(Float32 z) const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the relative turn velocity on the x axis of the managed vehicle entity. + */ + Float32 GetRelativeTurnSpeedX() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the relative turn velocity on the y axis of the managed vehicle entity. + */ + Float32 GetRelativeTurnSpeedY() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the relative turn velocity on the z axis of the managed vehicle entity. + */ + Float32 GetRelativeTurnSpeedZ() const; + + /* -------------------------------------------------------------------------------------------- + * Modify the relative turn velocity on the x axis of the managed vehicle entity. + */ + void SetRelativeTurnSpeedX(Float32 x) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the relative turn velocity on the y axis of the managed vehicle entity. + */ + void SetRelativeTurnSpeedY(Float32 y) const; + + /* -------------------------------------------------------------------------------------------- + * Modify the relative turn velocity on the z axis of the managed vehicle entity. + */ + void SetRelativeTurnSpeedZ(Float32 z) const; }; } // Namespace:: SqMod diff --git a/source/Exports.cpp b/source/Exports.cpp index c33d3a40..67607ef4 100644 --- a/source/Exports.cpp +++ b/source/Exports.cpp @@ -33,20 +33,14 @@ static HSQAPI GetSquirrelAPI() // ------------------------------------------------------------------------------------------------ static HSQUIRRELVM GetSquirrelVM() { - // Do we even have a core instance? - if (_Core) - { - return _Core->GetVM(); - } - // No idea ho we got here but we have to return something! - return NULL; + return Core::Get().GetVM(); } // ------------------------------------------------------------------------------------------------ static SQRESULT SqEx_LoadScript(const SQChar * filepath) { // Attempt to add the specified script to the load queue - if (_Core->LoadScript(filepath)) + if (Core::Get().LoadScript(filepath)) { return SQ_OK; // The script as added or already existed } @@ -286,7 +280,9 @@ void InitExports() g_SqExports.PushTimestamp = SqEx_PushTimestamp; // Export them to the server - _Func->ExportFunctions(_Info->nPluginId, (void **)(&sqexports), sizeof(SQEXPORTS)); + _Func->ExportFunctions(_Info->pluginId, + const_cast< const void ** >(reinterpret_cast< void ** >(&sqexports)), + sizeof(SQEXPORTS)); //vm g_SqAPI.open = sq_open; diff --git a/source/Library/Crypt.cpp b/source/Library/Crypt.cpp index 2dad018a..fad5ff1e 100644 --- a/source/Library/Crypt.cpp +++ b/source/Library/Crypt.cpp @@ -7,231 +7,17 @@ #include #include -// ------------------------------------------------------------------------------------------------ -#include -#include -#include -#include -#include -#include - // ------------------------------------------------------------------------------------------------ namespace SqMod { // ------------------------------------------------------------------------------------------------ -SQInteger AES256::Typename(HSQUIRRELVM vm) -{ - static SQChar name[] = _SC("SqAES256"); - sq_pushstring(vm, name, sizeof(name)); - return 1; -} - -// ------------------------------------------------------------------------------------------------ -AES256::AES256() - : m_Context(), m_Buffer() -{ - aes256_done(&m_Context); -} - -// ------------------------------------------------------------------------------------------------ -AES256::AES256(CSStr key) - : m_Context(), m_Buffer() -{ - Init(key); -} - -// ------------------------------------------------------------------------------------------------ -Int32 AES256::Cmp(const AES256 & o) const -{ - return std::memcmp(m_Buffer, o.m_Buffer, sizeof(m_Buffer)); -} - -// ------------------------------------------------------------------------------------------------ -CSStr AES256::ToString() const -{ - return ToStrF("%s", m_Buffer); -} - -// ------------------------------------------------------------------------------------------------ -CSStr AES256::GetKey() const -{ - return reinterpret_cast< CSStr >(m_Buffer); -} - -// ------------------------------------------------------------------------------------------------ -bool AES256::Init(CSStr key) -{ - // Clear current key, if any - aes256_done(&m_Context); - // Is the specified key empty? - if (!key || *key == '\0') - { - return false; // Leave the context with an empty key - } - // Obtain the specified key size - const Uint32 size = (std::strlen(key) * sizeof(SQChar)); - // See if the key size is accepted - if (size > sizeof(m_Buffer)) - { - STHROWF("The specified key is out of bounds: %u > %u", size, sizeof(m_Buffer)); - } - // Initialize the key buffer to 0 - std::memset(m_Buffer, 0, sizeof(m_Buffer)); - // Copy the key into the key buffer - std::memcpy(m_Buffer, key, size); - // Initialize the context with the specified key - aes256_init(&m_Context, m_Buffer); - // This context was successfully initialized - return true; -} - -// ------------------------------------------------------------------------------------------------ -void AES256::Done() -{ - aes256_done(&m_Context); -} - -// ------------------------------------------------------------------------------------------------ -String AES256::Encrypt(CSStr data) -{ - // Is there any data to encrypt? - if (!data || *data == 0) - { - return String(); - } - // Copy the data into an editable string - String str(data); - // Make sure that we have a size with a multiple of 16 - if ((str.size() % 16) != 0) - { - str.resize(str.size() - (str.size() % 16) + 16); - } - // Encrypt in chunks of 16 characters - for (Uint32 n = 0; n < str.size(); n += 16) - { - aes256_encrypt_ecb(&m_Context, reinterpret_cast< Uint8 * >(&str[n])); - } - // Return ownership of the encrypted string - return std::move(str); -} - -// ------------------------------------------------------------------------------------------------ -String AES256::Decrypt(CSStr data) -{ - // Is there any data to decrypt? - if (!data || *data == 0) - { - return String(); - } - // Copy the data into an editable string - String str(data); - // Make sure that we have a size with a multiple of 16 - if ((str.size() % 16) != 0) - { - str.resize(str.size() - (str.size() % 16) + 16); - } - // Decrypt inc chunks of 16 characters - for (Uint32 n = 0; n < str.size(); n += 16) - { - aes256_decrypt_ecb(&m_Context, reinterpret_cast< Uint8 * >(&str[n])); - } - // Remove null characters in case the string was not a multiple of 16 when encrypted - while (!str.empty() && str.back() == 0) - { - str.pop_back(); - } - // Return ownership of the encrypted string - return std::move(str); -} - -/* ------------------------------------------------------------------------------------------------ - * Utility to avoid creating encoder instances for each call. -*/ -template < class T > struct BaseHash -{ - static T Algo; -}; - -// ------------------------------------------------------------------------------------------------ -template < class T > T BaseHash< T >::Algo; - -/* ------------------------------------------------------------------------------------------------ - * Hash the specified value or the result of a formatted string. -*/ -template < class T > static SQInteger HashF(HSQUIRRELVM vm) -{ - // Attempt to retrieve the value from the stack as a string - StackStrF val(vm, 2); - // Have we failed to retrieve the string? - if (SQ_FAILED(val.mRes)) - { - return val.mRes; // Propagate the error! - } - // Forward the call to the actual implementation and store the string - String str(BaseHash< T >::Algo(val.mPtr)); - // Push the string on the stack - sq_pushstring(vm, str.data(), str.size()); - // At this point we have a valid string on the stack - return 1; -} - -// ================================================================================================ -template < class T > static void RegisterWrapper(Table & hashns, CCStr cname) -{ - typedef HashWrapper< T > Hash; - hashns.Bind(cname, Class< Hash >(hashns.GetVM(), cname) - // Constructors - .Ctor() - // Metamethods - .Func(_SC("_tostring"), &Hash::ToString) - // Properties - .Prop(_SC("Hash"), &Hash::GetHash) - // Functions - .Func(_SC("Reset"), &Hash::Reset) - .Func(_SC("Compute"), &Hash::Compute) - .Func(_SC("GetHash"), &Hash::GetHash) - .Func(_SC("Add"), &Hash::AddStr) - .Func(_SC("AddStr"), &Hash::AddStr) - ); -} +extern void Register_Hash(HSQUIRRELVM vm); +extern void Register_AES(HSQUIRRELVM vm); // ================================================================================================ void Register_Crypt(HSQUIRRELVM vm) { - Table hashns(vm); - RegisterWrapper< CRC32 >(hashns, _SC("CRC32")); - RegisterWrapper< Keccak >(hashns, _SC("Keccak")); - RegisterWrapper< MD5 >(hashns, _SC("MD5")); - RegisterWrapper< SHA1 >(hashns, _SC("SHA1")); - RegisterWrapper< SHA256 >(hashns, _SC("SHA256")); - RegisterWrapper< SHA3 >(hashns, _SC("SHA3")); - - hashns.SquirrelFunc(_SC("GetCRC32"), &HashF< CRC32 >); - hashns.SquirrelFunc(_SC("GetKeccak"), &HashF< Keccak >); - hashns.SquirrelFunc(_SC("GetMD5"), &HashF< MD5 >); - hashns.SquirrelFunc(_SC("GetSHA1"), &HashF< SHA1 >); - hashns.SquirrelFunc(_SC("GetSHA256"), &HashF< SHA256 >); - hashns.SquirrelFunc(_SC("GetSHA3"), &HashF< SHA3 >); - - RootTable(vm).Bind(_SC("SqHash"), hashns); - - RootTable(vm).Bind("SqAES256", Class< AES256 >(vm, "SqAES256") - // Constructors - .Ctor() - .Ctor< CSStr >() - // Metamethods - .Func(_SC("_cmp"), &AES256::Cmp) - .SquirrelFunc(_SC("_typename"), &AES256::Typename) - .Func(_SC("_tostring"), &AES256::ToString) - /* Properties */ - .Prop(_SC("Key"), &AES256::GetKey) - /* Functions */ - .Func(_SC("Init"), &AES256::Init) - .Func(_SC("Done"), &AES256::Done) - .Func(_SC("Encrypt"), &AES256::Encrypt) - .Func(_SC("Decrypt"), &AES256::Decrypt) - ); } } // Namespace:: SqMod diff --git a/source/Library/Crypt.hpp b/source/Library/Crypt.hpp index d3fdee9e..7a0dc71d 100644 --- a/source/Library/Crypt.hpp +++ b/source/Library/Crypt.hpp @@ -4,196 +4,10 @@ // ------------------------------------------------------------------------------------------------ #include "SqBase.hpp" -// ------------------------------------------------------------------------------------------------ -#include - // ------------------------------------------------------------------------------------------------ namespace SqMod { -/* ------------------------------------------------------------------------------------------------ - * Simple class to maintain the state of an encoder. -*/ -template < class T > class HashWrapper -{ -public: - /* -------------------------------------------------------------------------------------------- - * Default constructor. - */ - HashWrapper() - : m_Encoder() - { - /* ... */ - } - - /* -------------------------------------------------------------------------------------------- - * Copy operator. - */ - HashWrapper(const HashWrapper & o) - : m_Encoder(o.m_Encoder) - { - /* ... */ - } - - /* -------------------------------------------------------------------------------------------- - * Destructor. - */ - ~HashWrapper() - { - /* ... */ - } - - /* -------------------------------------------------------------------------------------------- - * Copy assignment operator. - */ - HashWrapper & operator = (const HashWrapper & o) - { - m_Encoder = o.m_Encoder; - return *this; - } - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to convert an instance of this type to a string. - */ - String ToString() - { - return m_Encoder.getHash(); - } - - /* -------------------------------------------------------------------------------------------- - * Reset the encoder state. - */ - void Reset() - { - m_Encoder.reset(); - } - - /* -------------------------------------------------------------------------------------------- - * Compute the hash of the specified string. - */ - String Compute(const String & str) - { - return m_Encoder(str); - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the hash value of the data hashed so far. - */ - String GetHash() - { - return m_Encoder.getHash(); - } - - /* -------------------------------------------------------------------------------------------- - * Add a string value to be hashed. - */ - void AddStr(const String & str) - { - m_Encoder.add(str.data(), str.length() * sizeof(String::value_type)); - } - -private: - - /* -------------------------------------------------------------------------------------------- - * The managed encoder state. - */ - T m_Encoder; -}; - -/* ------------------------------------------------------------------------------------------------ - * Simple wrapper around a the AES encryption context. -*/ -class AES256 -{ -public: - - /* -------------------------------------------------------------------------------------------- - * Default constructor. - */ - AES256(); - - /* -------------------------------------------------------------------------------------------- - * Construct with an explicit key. - */ - AES256(CSStr key); - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. - */ - AES256(const AES256 & o) = default; - - /* -------------------------------------------------------------------------------------------- - * Move constructor. - */ - AES256(AES256 && o) = default; - - /* -------------------------------------------------------------------------------------------- - * Destructor. - */ - ~AES256() = default; - - /* -------------------------------------------------------------------------------------------- - * Copy assignment operator. - */ - AES256 & operator = (const AES256 & o) = default; - - /* -------------------------------------------------------------------------------------------- - * Move assignment operator. - */ - AES256 & operator = (AES256 && o) = default; - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to compare two instances of this type. - */ - Int32 Cmp(const AES256 & o) const; - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to convert an instance of this type to a string. - */ - CSStr ToString() const; - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to retrieve the name from instances of this type. - */ - static SQInteger Typename(HSQUIRRELVM vm); - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated key. - */ - CSStr GetKey() const; - - /* -------------------------------------------------------------------------------------------- - * Initialize the context key. - */ - bool Init(CSStr key); - - /* -------------------------------------------------------------------------------------------- - * Reset the associated context. - */ - void Done(); - - /* -------------------------------------------------------------------------------------------- - * Encrypt the specified string. - */ - String Encrypt(CSStr data); - - /* -------------------------------------------------------------------------------------------- - * Decrypt the specified string. - */ - String Decrypt(CSStr data); - -private: - - /* -------------------------------------------------------------------------------------------- - * The managed encryption context. - */ - aes256_context m_Context; - - /* -------------------------------------------------------------------------------------------- - * The key used to encrypt data. - */ - Uint8 m_Buffer[32]{0}; -}; } // Namespace:: SqMod diff --git a/source/Library/Crypt/AES.cpp b/source/Library/Crypt/AES.cpp new file mode 100644 index 00000000..21b600ef --- /dev/null +++ b/source/Library/Crypt/AES.cpp @@ -0,0 +1,160 @@ +// ------------------------------------------------------------------------------------------------ +#include "Library/Crypt/AES.hpp" +#include "Base/Shared.hpp" +#include "Base/Stack.hpp" + +// ------------------------------------------------------------------------------------------------ +#include +#include + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +// ------------------------------------------------------------------------------------------------ +SQInteger AES256::Typename(HSQUIRRELVM vm) +{ + static SQChar name[] = _SC("SqAES256"); + sq_pushstring(vm, name, sizeof(name)); + return 1; +} + +// ------------------------------------------------------------------------------------------------ +AES256::AES256() + : m_Context(), m_Buffer() +{ + aes256_done(&m_Context); +} + +// ------------------------------------------------------------------------------------------------ +AES256::AES256(CSStr key) + : m_Context(), m_Buffer() +{ + Init(key); +} + +// ------------------------------------------------------------------------------------------------ +Int32 AES256::Cmp(const AES256 & o) const +{ + return std::memcmp(m_Buffer, o.m_Buffer, sizeof(m_Buffer)); +} + +// ------------------------------------------------------------------------------------------------ +CSStr AES256::ToString() const +{ + return ToStrF("%s", m_Buffer); +} + +// ------------------------------------------------------------------------------------------------ +CSStr AES256::GetKey() const +{ + return reinterpret_cast< CSStr >(m_Buffer); +} + +// ------------------------------------------------------------------------------------------------ +bool AES256::Init(CSStr key) +{ + // Clear current key, if any + aes256_done(&m_Context); + // Is the specified key empty? + if (!key || *key == '\0') + { + return false; // Leave the context with an empty key + } + // Obtain the specified key size + const Uint32 size = (std::strlen(key) * sizeof(SQChar)); + // See if the key size is accepted + if (size > sizeof(m_Buffer)) + { + STHROWF("The specified key is out of bounds: %u > %u", size, sizeof(m_Buffer)); + } + // Initialize the key buffer to 0 + std::memset(m_Buffer, 0, sizeof(m_Buffer)); + // Copy the key into the key buffer + std::memcpy(m_Buffer, key, size); + // Initialize the context with the specified key + aes256_init(&m_Context, m_Buffer); + // This context was successfully initialized + return true; +} + +// ------------------------------------------------------------------------------------------------ +void AES256::Done() +{ + aes256_done(&m_Context); +} + +// ------------------------------------------------------------------------------------------------ +String AES256::Encrypt(CSStr data) +{ + // Is there any data to encrypt? + if (!data || *data == 0) + { + return String(); + } + // Copy the data into an editable string + String str(data); + // Make sure that we have a size with a multiple of 16 + if ((str.size() % 16) != 0) + { + str.resize(str.size() - (str.size() % 16) + 16); + } + // Encrypt in chunks of 16 characters + for (Uint32 n = 0; n < str.size(); n += 16) + { + aes256_encrypt_ecb(&m_Context, reinterpret_cast< Uint8 * >(&str[n])); + } + // Return ownership of the encrypted string + return std::move(str); +} + +// ------------------------------------------------------------------------------------------------ +String AES256::Decrypt(CSStr data) +{ + // Is there any data to decrypt? + if (!data || *data == 0) + { + return String(); + } + // Copy the data into an editable string + String str(data); + // Make sure that we have a size with a multiple of 16 + if ((str.size() % 16) != 0) + { + str.resize(str.size() - (str.size() % 16) + 16); + } + // Decrypt inc chunks of 16 characters + for (Uint32 n = 0; n < str.size(); n += 16) + { + aes256_decrypt_ecb(&m_Context, reinterpret_cast< Uint8 * >(&str[n])); + } + // Remove null characters in case the string was not a multiple of 16 when encrypted + while (!str.empty() && str.back() == 0) + { + str.pop_back(); + } + // Return ownership of the encrypted string + return std::move(str); +} + +// ================================================================================================ +void Register_AES(HSQUIRRELVM vm) +{ + RootTable(vm).Bind("SqAES256", Class< AES256 >(vm, "SqAES256") + // Constructors + .Ctor() + .Ctor< CSStr >() + // Metamethods + .Func(_SC("_cmp"), &AES256::Cmp) + .SquirrelFunc(_SC("_typename"), &AES256::Typename) + .Func(_SC("_tostring"), &AES256::ToString) + /* Properties */ + .Prop(_SC("Key"), &AES256::GetKey) + /* Functions */ + .Func(_SC("Init"), &AES256::Init) + .Func(_SC("Done"), &AES256::Done) + .Func(_SC("Encrypt"), &AES256::Encrypt) + .Func(_SC("Decrypt"), &AES256::Decrypt) + ); +} + +} // Namespace:: SqMod diff --git a/source/Library/Crypt/AES.hpp b/source/Library/Crypt/AES.hpp new file mode 100644 index 00000000..0922d808 --- /dev/null +++ b/source/Library/Crypt/AES.hpp @@ -0,0 +1,110 @@ +#ifndef _LIBRARY_CRYPT_AES_HPP_ +#define _LIBRARY_CRYPT_AES_HPP_ + +// ------------------------------------------------------------------------------------------------ +#include "SqBase.hpp" + +// ------------------------------------------------------------------------------------------------ +#include + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +/* ------------------------------------------------------------------------------------------------ + * Simple wrapper around a the AES encryption context. +*/ +class AES256 +{ +public: + + /* -------------------------------------------------------------------------------------------- + * Default constructor. + */ + AES256(); + + /* -------------------------------------------------------------------------------------------- + * Construct with an explicit key. + */ + AES256(CSStr key); + + /* -------------------------------------------------------------------------------------------- + * Copy constructor. + */ + AES256(const AES256 & o) = default; + + /* -------------------------------------------------------------------------------------------- + * Move constructor. + */ + AES256(AES256 && o) = default; + + /* -------------------------------------------------------------------------------------------- + * Destructor. + */ + ~AES256() = default; + + /* -------------------------------------------------------------------------------------------- + * Copy assignment operator. + */ + AES256 & operator = (const AES256 & o) = default; + + /* -------------------------------------------------------------------------------------------- + * Move assignment operator. + */ + AES256 & operator = (AES256 && o) = default; + + /* -------------------------------------------------------------------------------------------- + * Used by the script engine to compare two instances of this type. + */ + Int32 Cmp(const AES256 & o) const; + + /* -------------------------------------------------------------------------------------------- + * Used by the script engine to convert an instance of this type to a string. + */ + CSStr ToString() const; + + /* -------------------------------------------------------------------------------------------- + * Used by the script engine to retrieve the name from instances of this type. + */ + static SQInteger Typename(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Retrieve the associated key. + */ + CSStr GetKey() const; + + /* -------------------------------------------------------------------------------------------- + * Initialize the context key. + */ + bool Init(CSStr key); + + /* -------------------------------------------------------------------------------------------- + * Reset the associated context. + */ + void Done(); + + /* -------------------------------------------------------------------------------------------- + * Encrypt the specified string. + */ + String Encrypt(CSStr data); + + /* -------------------------------------------------------------------------------------------- + * Decrypt the specified string. + */ + String Decrypt(CSStr data); + +private: + + /* -------------------------------------------------------------------------------------------- + * The managed encryption context. + */ + aes256_context m_Context; + + /* -------------------------------------------------------------------------------------------- + * The key used to encrypt data. + */ + Uint8 m_Buffer[32]{0}; +}; + +} // Namespace:: SqMod + +#endif // _LIBRARY_CRYPT_AES_HPP_ diff --git a/source/Library/Crypt/Hash.cpp b/source/Library/Crypt/Hash.cpp new file mode 100644 index 00000000..46242ded --- /dev/null +++ b/source/Library/Crypt/Hash.cpp @@ -0,0 +1,94 @@ +// ------------------------------------------------------------------------------------------------ +#include "Library/Crypt/Hash.hpp" +#include "Base/Shared.hpp" +#include "Base/Stack.hpp" + +// ------------------------------------------------------------------------------------------------ +#include +#include +#include +#include +#include +#include + +// ------------------------------------------------------------------------------------------------ +#include +#include + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +/* ------------------------------------------------------------------------------------------------ + * Utility to avoid creating encoder instances for each call. +*/ +template < class T > struct BaseHash +{ + static T Algo; +}; + +// ------------------------------------------------------------------------------------------------ +template < class T > T BaseHash< T >::Algo; + +/* ------------------------------------------------------------------------------------------------ + * Hash the specified value or the result of a formatted string. +*/ +template < class T > static SQInteger HashF(HSQUIRRELVM vm) +{ + // Attempt to retrieve the value from the stack as a string + StackStrF val(vm, 2); + // Have we failed to retrieve the string? + if (SQ_FAILED(val.mRes)) + { + return val.mRes; // Propagate the error! + } + // Forward the call to the actual implementation and store the string + String str(BaseHash< T >::Algo(val.mPtr)); + // Push the string on the stack + sq_pushstring(vm, str.data(), str.size()); + // At this point we have a valid string on the stack + return 1; +} + +// ================================================================================================ +template < class T > static void RegisterWrapper(Table & hashns, CCStr cname) +{ + typedef HashWrapper< T > Hash; + hashns.Bind(cname, Class< Hash >(hashns.GetVM(), cname) + // Constructors + .Ctor() + // Metamethods + .Func(_SC("_tostring"), &Hash::ToString) + // Properties + .Prop(_SC("Hash"), &Hash::GetHash) + // Functions + .Func(_SC("Reset"), &Hash::Reset) + .Func(_SC("Compute"), &Hash::Compute) + .Func(_SC("GetHash"), &Hash::GetHash) + .Func(_SC("Add"), &Hash::AddStr) + .Func(_SC("AddStr"), &Hash::AddStr) + ); +} + +// ================================================================================================ +void Register_Hash(HSQUIRRELVM vm) +{ + Table hashns(vm); + + RegisterWrapper< CRC32 >(hashns, _SC("CRC32")); + RegisterWrapper< Keccak >(hashns, _SC("Keccak")); + RegisterWrapper< MD5 >(hashns, _SC("MD5")); + RegisterWrapper< SHA1 >(hashns, _SC("SHA1")); + RegisterWrapper< SHA256 >(hashns, _SC("SHA256")); + RegisterWrapper< SHA3 >(hashns, _SC("SHA3")); + + hashns.SquirrelFunc(_SC("GetCRC32"), &HashF< CRC32 >); + hashns.SquirrelFunc(_SC("GetKeccak"), &HashF< Keccak >); + hashns.SquirrelFunc(_SC("GetMD5"), &HashF< MD5 >); + hashns.SquirrelFunc(_SC("GetSHA1"), &HashF< SHA1 >); + hashns.SquirrelFunc(_SC("GetSHA256"), &HashF< SHA256 >); + hashns.SquirrelFunc(_SC("GetSHA3"), &HashF< SHA3 >); + + RootTable(vm).Bind(_SC("SqHash"), hashns); +} + +} // Namespace:: SqMod diff --git a/source/Library/Crypt/Hash.hpp b/source/Library/Crypt/Hash.hpp new file mode 100644 index 00000000..5eb4e009 --- /dev/null +++ b/source/Library/Crypt/Hash.hpp @@ -0,0 +1,102 @@ +#ifndef _LIBRARY_CRYPT_HASH_HPP_ +#define _LIBRARY_CRYPT_HASH_HPP_ + +// ------------------------------------------------------------------------------------------------ +#include "SqBase.hpp" + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +/* ------------------------------------------------------------------------------------------------ + * Simple class to maintain the state of an encoder. +*/ +template < class T > class HashWrapper +{ +public: + + /* -------------------------------------------------------------------------------------------- + * Default constructor. + */ + HashWrapper() + : m_Encoder() + { + /* ... */ + } + + /* -------------------------------------------------------------------------------------------- + * Copy operator. + */ + HashWrapper(const HashWrapper & o) + : m_Encoder(o.m_Encoder) + { + /* ... */ + } + + /* -------------------------------------------------------------------------------------------- + * Destructor. + */ + ~HashWrapper() + { + /* ... */ + } + + /* -------------------------------------------------------------------------------------------- + * Copy assignment operator. + */ + HashWrapper & operator = (const HashWrapper & o) + { + m_Encoder = o.m_Encoder; + return *this; + } + + /* -------------------------------------------------------------------------------------------- + * Used by the script engine to convert an instance of this type to a string. + */ + String ToString() + { + return m_Encoder.getHash(); + } + + /* -------------------------------------------------------------------------------------------- + * Reset the encoder state. + */ + void Reset() + { + m_Encoder.reset(); + } + + /* -------------------------------------------------------------------------------------------- + * Compute the hash of the specified string. + */ + String Compute(const String & str) + { + return m_Encoder(str); + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the hash value of the data hashed so far. + */ + String GetHash() + { + return m_Encoder.getHash(); + } + + /* -------------------------------------------------------------------------------------------- + * Add a string value to be hashed. + */ + void AddStr(const String & str) + { + m_Encoder.add(str.data(), str.length() * sizeof(String::value_type)); + } + +private: + + /* -------------------------------------------------------------------------------------------- + * The managed encoder state. + */ + T m_Encoder; +}; + +} // Namespace:: SqMod + +#endif // _LIBRARY_CRYPT_HASH_HPP_ diff --git a/source/Library/System.cpp b/source/Library/System.cpp new file mode 100644 index 00000000..7e504ef9 --- /dev/null +++ b/source/Library/System.cpp @@ -0,0 +1,109 @@ +// ------------------------------------------------------------------------------------------------ +#include "Library/System.hpp" +#include "Base/Shared.hpp" +#include "Base/Stack.hpp" +#include "Base/Buffer.hpp" + +// ------------------------------------------------------------------------------------------------ +#include +#include +#include +#include +#include + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +// ------------------------------------------------------------------------------------------------ +extern void Register_SysEnv(HSQUIRRELVM vm); +extern void Register_SysPath(HSQUIRRELVM vm); + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqSysExec(HSQUIRRELVM vm) +{ + // Attempt to retrieve the value from the stack as a string + StackStrF val(vm, 2); + // Have we failed to retrieve the string? + if (SQ_FAILED(val.mRes)) + { + return val.mRes; // Propagate the error! + } + // Allocate a temp buffer to retrieve chunks from output + char buffer[128]; + // Allocate a buffer which will contain the final output + Buffer b(128); + // Attempt to open the specified process + FILE * pipe = popen(val.mPtr, "r"); + // The process return status + Int32 status = -1; + // Did we fail to open the process? + if (!pipe) + { + return sq_throwerror(vm, ToStrF("Unable to open process [%s]", val.mPtr)); + } + // Attempt to read process output + try + { + while (!std::feof(pipe)) + { + if (std::fgets(buffer, 128, pipe) != NULL) + { + b.AppendS(buffer); + } + } + } + catch (...) + { + // Close the process + status = pclose(pipe); + // Now throw the error + return sq_throwerror(vm, ToStrF("Unable read process output [%d]", status)); + } + // Close the process and obtain the exit status + status = pclose(pipe); + // Remember the top of the stack + const Int32 top = sq_gettop(vm); + // Create a new table on the stack + sq_newtable(vm); + // Push the element name + sq_pushstring(vm, _SC("Status"), -1); + // Push the element value + sq_pushinteger(vm, status); + // Create the element in the table + SQRESULT res = sq_rawset(vm, -3); + // Check the result + if (SQ_FAILED(res)) + { + // Clean the stack + sq_settop(vm, top); + // Return the error + return res; + } + // Push the element name + sq_pushstring(vm, _SC("Output"), -1); + // Push the element value + sq_pushstring(vm, b.Get< SQChar >(), b.Position()); + // Create the element in the table + res = sq_rawset(vm, -3); + // Check the result + if (SQ_FAILED(res)) + { + // Clean the stack + sq_settop(vm, top); + // Return the error + return res; + } + // Specify that we want to return the table we created + return 1; +} + +// ================================================================================================ +void Register_System(HSQUIRRELVM vm) +{ + Register_SysEnv(vm); + Register_SysPath(vm); + + RootTable(vm).SquirrelFunc(_SC("SysExec"), &SqSysExec); +} + +} // Namespace:: SqMod diff --git a/source/Library/System.hpp b/source/Library/System.hpp new file mode 100644 index 00000000..34225f41 --- /dev/null +++ b/source/Library/System.hpp @@ -0,0 +1,14 @@ +#ifndef _LIBRARY_SYSTEM_HPP_ +#define _LIBRARY_SYSTEM_HPP_ + +// ------------------------------------------------------------------------------------------------ +#include "Base/Shared.hpp" + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + + + +} // Namespace:: SqMod + +#endif // _LIBRARY_SYSTEM_HPP_ \ No newline at end of file diff --git a/source/Library/SysEnv.cpp b/source/Library/System/Environment.cpp similarity index 99% rename from source/Library/SysEnv.cpp rename to source/Library/System/Environment.cpp index 8d6fc49a..9f3e3fcf 100644 --- a/source/Library/SysEnv.cpp +++ b/source/Library/System/Environment.cpp @@ -1,5 +1,5 @@ // ------------------------------------------------------------------------------------------------ -#include "Library/SysEnv.hpp" +#include "Library/System/Environment.hpp" #include "Base/Stack.hpp" // ------------------------------------------------------------------------------------------------ diff --git a/source/Library/SysEnv.hpp b/source/Library/System/Environment.hpp similarity index 100% rename from source/Library/SysEnv.hpp rename to source/Library/System/Environment.hpp diff --git a/source/Library/SysPath.cpp b/source/Library/System/Path.cpp similarity index 99% rename from source/Library/SysPath.cpp rename to source/Library/System/Path.cpp index b4d5a519..dac3d260 100644 --- a/source/Library/SysPath.cpp +++ b/source/Library/System/Path.cpp @@ -1,6 +1,6 @@ // ------------------------------------------------------------------------------------------------ -#include "Library/SysPath.hpp" -#include "Library/SysEnv.hpp" +#include "Library/System/Path.hpp" +#include "Library/System/Environment.hpp" #include "Base/Stack.hpp" // ------------------------------------------------------------------------------------------------ diff --git a/source/Library/SysPath.hpp b/source/Library/System/Path.hpp similarity index 100% rename from source/Library/SysPath.hpp rename to source/Library/System/Path.hpp diff --git a/source/Library/Utils.cpp b/source/Library/Utils.cpp index e69de29b..f084782e 100644 --- a/source/Library/Utils.cpp +++ b/source/Library/Utils.cpp @@ -0,0 +1,16 @@ +// ------------------------------------------------------------------------------------------------ +#include "Library/Utils.hpp" + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +// ------------------------------------------------------------------------------------------------ +extern void Register_Buffer(HSQUIRRELVM vm); + +// ================================================================================================ +void Register_Utils(HSQUIRRELVM vm) +{ + Register_Buffer(vm); +} + +} // Namespace:: SqMod diff --git a/source/Library/Utils.hpp b/source/Library/Utils.hpp index df106feb..94f047a3 100644 --- a/source/Library/Utils.hpp +++ b/source/Library/Utils.hpp @@ -7,34 +7,7 @@ // ------------------------------------------------------------------------------------------------ namespace SqMod { -/* ------------------------------------------------------------------------------------------------ - * -*/ -class Blob -{ - /* -------------------------------------------------------------------------------------------- - * - */ - Blob(const Blob &); - /* -------------------------------------------------------------------------------------------- - * - */ - Blob & operator = (const Blob &); - -public: - - /* -------------------------------------------------------------------------------------------- - * - */ - Blob(); - - /* -------------------------------------------------------------------------------------------- - * - */ - ~Blob(); - -}; } // Namespace:: SqMod diff --git a/source/Library/Utils/BufferInterpreter.cpp b/source/Library/Utils/BufferInterpreter.cpp new file mode 100644 index 00000000..cdeb1cba --- /dev/null +++ b/source/Library/Utils/BufferInterpreter.cpp @@ -0,0 +1,63 @@ +// ------------------------------------------------------------------------------------------------ +#include "Library/Utils/BufferInterpreter.hpp" +#include "Library/Utils/BufferWrapper.hpp" + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +// ------------------------------------------------------------------------------------------------ +const SharedPtr< Buffer > & GetBufferBufferRef(const BufferWrapper & buffer) +{ + return buffer.GetRef(); +} + +// ------------------------------------------------------------------------------------------------ +template < typename T > static void RegisterInterpreter(Table & bns, CSStr cname, CSStr bname) +{ + typedef BufferInterpreter< T > Interpreter; + + bns.Bind(bname, + Class< Interpreter >(bns.GetVM(), cname) + // Constructors + .Ctor() + // Properties + .Prop(_SC("Front"), &Interpreter::GetFront, &Interpreter::SetFront) + .Prop(_SC("Next"), &Interpreter::GetNext, &Interpreter::SetNext) + .Prop(_SC("Back"), &Interpreter::GetBack, &Interpreter::SetBack) + .Prop(_SC("Prev"), &Interpreter::GetPrev, &Interpreter::SetPrev) + .Prop(_SC("Cursor"), &Interpreter::GetCursor, &Interpreter::SetCursor) + .Prop(_SC("Before"), &Interpreter::GetBefore, &Interpreter::SetBefore) + .Prop(_SC("After"), &Interpreter::GetAfter, &Interpreter::SetAfter) + .Prop(_SC("Max"), &Interpreter::GetMax) + .Prop(_SC("Size"), &Interpreter::GetSize) + .Prop(_SC("Capacity"), &Interpreter::GetCapacity) + .Prop(_SC("Position"), &Interpreter::GetPosition) + .Prop(_SC("Remaining"), &Interpreter::GetRemaining) + // Member Methods + .Func(_SC("Use"), &Interpreter::UseBuffer) + .Func(_SC("Get"), &Interpreter::Get) + .Func(_SC("Set"), &Interpreter::Set) + .Func(_SC("Advance"), &Interpreter::Advance) + .Func(_SC("Retreat"), &Interpreter::Retreat) + .Func(_SC("Push"), &Interpreter::Push) + .Func(_SC("Grow"), &Interpreter::Grow) + .Func(_SC("Adjust"), &Interpreter::Adjust) + ); +} + +// ================================================================================================ +void Register_BufferInterpreter(Table & bns) +{ + RegisterInterpreter< Int8 >(bns, _SC("SqBufferInterpreterS8"), _SC("S8Interpreter")); + RegisterInterpreter< Uint8 >(bns, _SC("SqBufferInterpreterU8"), _SC("U8Interpreter")); + RegisterInterpreter< Int16 >(bns, _SC("SqBufferInterpreterS16"), _SC("S16Interpreter")); + RegisterInterpreter< Uint16 >(bns, _SC("SqBufferInterpreterU16"), _SC("U16Interpreter")); + RegisterInterpreter< Int32 >(bns, _SC("SqBufferInterpreterS32"), _SC("S32Interpreter")); + RegisterInterpreter< Uint32 >(bns, _SC("SqBufferInterpreterU32"), _SC("U32Interpreter")); + RegisterInterpreter< Int64 >(bns, _SC("SqBufferInterpreterS64"), _SC("S64Interpreter")); + RegisterInterpreter< Uint64 >(bns, _SC("SqBufferInterpreterU64"), _SC("U64Interpreter")); + RegisterInterpreter< Float32 >(bns, _SC("SqBufferInterpreterF32"), _SC("F32Interpreter")); + RegisterInterpreter< Float64 >(bns, _SC("SqBufferInterpreterF64"), _SC("F64Interpreter")); +} + +} // Namespace:: SqMod diff --git a/source/Library/Utils/BufferInterpreter.hpp b/source/Library/Utils/BufferInterpreter.hpp new file mode 100644 index 00000000..65197dda --- /dev/null +++ b/source/Library/Utils/BufferInterpreter.hpp @@ -0,0 +1,542 @@ +#ifndef _LIBRARY_UTILS_BUFFERINTERPRETER_HPP_ +#define _LIBRARY_UTILS_BUFFERINTERPRETER_HPP_ + +// ------------------------------------------------------------------------------------------------ +#include "Base/Shared.hpp" +#include "Base/Buffer.hpp" + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +// ------------------------------------------------------------------------------------------------ +class BufferWrapper; + +/* ------------------------------------------------------------------------------------------------ + * Used internally to obtain a reference to the memory buffer without including the wrapper header. +*/ +const SharedPtr< Buffer > & GetBufferBufferRef(const BufferWrapper & buffer); + +/* ------------------------------------------------------------------------------------------------ + * Utility class used to interpret a memory buffer in different ways. +*/ +template < typename T > class BufferInterpreter +{ +private: + + // -------------------------------------------------------------------------------------------- + typedef SharedPtr< Buffer > SRef; // Strong reference type to the interpreted memory buffer. + typedef WeakPtr< Buffer > WRef; // Weak reference type to the interpreted memory buffer. + + // -------------------------------------------------------------------------------------------- + WRef m_Buffer; // The interpreted memory buffer. + +public: + + // -------------------------------------------------------------------------------------------- + typedef T Value; // The type of value used to represent a byte. + + // -------------------------------------------------------------------------------------------- + typedef Value & Reference; // A reference to the stored value type. + typedef const Value & ConstRef; // A const reference to the stored value type. + + // -------------------------------------------------------------------------------------------- + typedef Value * Pointer; // A pointer to the stored value type. + typedef const Value * ConstPtr; // A const pointer to the stored value type. + + // -------------------------------------------------------------------------------------------- + typedef Buffer::SzType SzType; // The type used to represent size in general. + +protected: + + /* -------------------------------------------------------------------------------------------- + * Attempt to obtain a strong reference to the memory buffer at all costs. + */ + SRef Validate() const + { + // Did the buffer that we reference expired? + if (m_Buffer.Expired()) + { + STHROWF("Invalid memory buffer reference"); + } + // Obtain a strong reference to it + return m_Buffer.Lock(); + } + + /* -------------------------------------------------------------------------------------------- + * Attempt to obtain a strong reference to a valid memory buffer at all costs. + */ + SRef ValidateDeeper() const + { + // Did the buffer that we reference expired? + if (m_Buffer.Expired()) + { + STHROWF("Invalid memory buffer reference"); + } + // Obtain a strong reference to it + SRef ref = m_Buffer.Lock(); + // Validate the buffer itself + if (!(*ref)) + { + STHROWF("Invalid memory buffer"); + } + // Return the reference + return ref; + } + +public: + + /* -------------------------------------------------------------------------------------------- + * Default constructor. (null) + */ + BufferInterpreter() + : m_Buffer() + { + /* ... */ + } + + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + BufferInterpreter(const WRef & ref) + : m_Buffer(ref) + { + /* ... */ + } + + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + BufferInterpreter(const SRef & ref) + : m_Buffer(ref) + { + /* ... */ + } + + /* -------------------------------------------------------------------------------------------- + * Copy constructor. + */ + BufferInterpreter(const BufferInterpreter & o) = default; + + /* -------------------------------------------------------------------------------------------- + * Move constructor. + */ + BufferInterpreter(BufferInterpreter && o) = default; + + /* -------------------------------------------------------------------------------------------- + * Destructor. + */ + ~BufferInterpreter() = default; + + /* -------------------------------------------------------------------------------------------- + * Copy assignment operator. + */ + BufferInterpreter & operator = (const BufferInterpreter & o) = default; + + /* -------------------------------------------------------------------------------------------- + * Move assignment operator. + */ + BufferInterpreter & operator = (BufferInterpreter && o) = default; + + /* -------------------------------------------------------------------------------------------- + * Retrieve a reference to the managed memory buffer. + */ + const WRef & GetRef() const + { + return m_Buffer; + } + + /* -------------------------------------------------------------------------------------------- + * Assign a different memory buffer to interpret from. + */ + void UseBuffer(const BufferWrapper & buffer) + { + m_Buffer = GetBufferBufferRef(buffer); + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve a certain element type at the specified position. + */ + T Get(SzType n) const + { + // Acquire a reference to the memory buffer + SRef b(Validate()); + // Are we out of the memory buffer range? + if (n >= b->Size< T >()) + { + STHROWF("Index (%u) is out of bounds (%u)", n, b->Size< T >()); + } + // Return the requested element + return b->At< T >(n); + } + + /* -------------------------------------------------------------------------------------------- + * Modify a certain element type at the specified position. + */ + void Set(SzType n, T v) + { + // Acquire a reference to the memory buffer + SRef b(Validate()); + // Are we out of the memory buffer range? + if (n >= b->Size< T >()) + { + STHROWF("Index (%u) is out of bounds (%u)", n, b->Size< T >()); + } + // Return the requested element + b->At< T >(n) = v; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the element at the front of the buffer. + */ + T GetFront() const + { + // Acquire a reference to the memory buffer + SRef b(Validate()); + // Are we out of the memory buffer range? + if (b->Capacity() < sizeof(T)) + { + STHROWF("Value size (%u starting at 0) is out of bounds (%u)", + sizeof(T), b->Capacity()); + } + // Return the requested element + return b->Front< T >(); + } + + /* -------------------------------------------------------------------------------------------- + * Modify the element at the front of the buffer. + */ + void SetFront(T v) + { + // Acquire a reference to the memory buffer + SRef b(Validate()); + // Are we out of the memory buffer range? + if (b->Capacity() < sizeof(T)) + { + STHROWF("Value size (%u starting at 0) is out of bounds (%u)", + sizeof(T), b->Capacity()); + } + // Return the requested element + b->Front< T >() = v; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the element after the first element in the buffer. + */ + T GetNext() const + { + // Acquire a reference to the memory buffer + SRef b(Validate()); + // Are we out of the memory buffer range? + if (b->Capacity() < (sizeof(T) * 2)) + { + STHROWF("Value size (%u starting at %u) is out of bounds (%u)", + sizeof(T), sizeof(T), b->Capacity()); + } + // Return the requested element + return b->Next< T >(); + } + + /* -------------------------------------------------------------------------------------------- + * Modify the element after the first element in the buffer. + */ + void SetNext(T v) + { + // Acquire a reference to the memory buffer + SRef b(Validate()); + // Are we out of the memory buffer range? + if (b->Capacity() < (sizeof(T) * 2)) + { + STHROWF("Value size (%u starting at %u) is out of bounds (%u)", + sizeof(T), sizeof(T), b->Capacity()); + } + // Return the requested element + b->Next< T >() = v; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the element at the back of the buffer. + */ + T GetBack() const + { + // Acquire a reference to the memory buffer + SRef b(Validate()); + // Are we out of the memory buffer range? + if (b->Capacity() < sizeof(T)) + { + STHROWF("Value size (%u starting at 0) is out of bounds (%u)", + sizeof(T), b->Capacity()); + } + // Return the requested element + return b->Back< T >(); + } + + /* -------------------------------------------------------------------------------------------- + * Modify the element at the back of the buffer. + */ + void SetBack(T v) + { + // Acquire a reference to the memory buffer + SRef b(Validate()); + // Are we out of the memory buffer range? + if (b->Capacity() < sizeof(T)) + { + STHROWF("Value size (%u starting at 0) is out of bounds (%u)", + sizeof(T), b->Capacity()); + } + // Return the requested element + b->Back< T >() = v; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the element before the last element in the buffer. + */ + T GetPrev() const + { + // Acquire a reference to the memory buffer + SRef b(Validate()); + // Are we out of the memory buffer range? + if (b->Capacity() < (sizeof(T) * 2)) + { + STHROWF("Value size (%u starting at %u) is out of bounds (%u)", + sizeof(T), sizeof(T), b->Capacity()); + } + // Return the requested element + return b->Prev< T >(); + } + + /* -------------------------------------------------------------------------------------------- + * Modify the element before the last element in the buffer. + */ + void SetPrev(T v) + { + // Acquire a reference to the memory buffer + SRef b(Validate()); + // Are we out of the memory buffer range? + if (b->Capacity() < (sizeof(T) * 2)) + { + STHROWF("Value size (%u starting at %u) is out of bounds (%u)", + sizeof(T), sizeof(T), b->Capacity()); + } + // Return the requested element + b->Prev< T >() = v; + } + + /* -------------------------------------------------------------------------------------------- + * Reposition the edit cursor to the specified number of elements ahead. + */ + void Advance(SzType n) + { + // Acquire a reference to the memory buffer + SRef b(Validate()); + // Perform the requested operation + b->Advance< T >(n); + } + + /* -------------------------------------------------------------------------------------------- + * Reposition the edit cursor to the specified number of elements behind. + */ + void Retreat(SzType n) + { + // Acquire a reference to the memory buffer + SRef b(Validate()); + // Perform the requested operation + b->Retreat< T >(n); + } + + /* -------------------------------------------------------------------------------------------- + * Reposition the edit cursor to a fixed position within the buffer. + */ + void Move(SzType n) + { + // Acquire a reference to the memory buffer + SRef b(Validate()); + // Perform the requested operation + b->Move< T >(n); + } + + /* -------------------------------------------------------------------------------------------- + * Append a value to the current cursor location and advance the cursor. + */ + void Push(T v) + { + // Acquire a reference to the memory buffer + SRef b(Validate()); + // Perform the requested operation + b->Push< T >(v); + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the element at the cursor position. + */ + T GetCursor() const + { + // Acquire a reference to the memory buffer + SRef b(Validate()); + // Are we out of the memory buffer range? + if (b->Position< T >() >= b->Size< T >()) + { + STHROWF("Value size (%u starting at %u) is out of bounds (%u)", + sizeof(T), b->Position(), b->Capacity()); + } + // Return the requested element + return b->Cursor< T >(); + } + + /* -------------------------------------------------------------------------------------------- + * Modify the element at the cursor position. + */ + void SetCursor(T v) + { + // Acquire a reference to the memory buffer + SRef b(Validate()); + // Are we out of the memory buffer range? + if (b->Position< T >() >= b->Size< T >()) + { + STHROWF("Value size (%u starting at %u) is out of bounds (%u)", + sizeof(T), b->Position(), b->Capacity()); + } + // Return the requested element + b->Cursor< T >() = v; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the element before the cursor position. + */ + T GetBefore() const + { + // Acquire a reference to the memory buffer + SRef b(Validate()); + // Are we out of the memory buffer range? + if (b->Position() < sizeof(T)) + { + STHROWF("Value size (%u starting at 0) is out of bounds (%u)", + sizeof(T), b->Capacity()); + } + // Return the requested element + return b->Before< T >(); + } + + /* -------------------------------------------------------------------------------------------- + * Modify the element before the cursor position. + */ + void SetBefore(T v) + { + // Acquire a reference to the memory buffer + SRef b(Validate()); + // Are we out of the memory buffer range? + if (b->Position() < sizeof(T)) + { + STHROWF("Value size (%u starting at 0) is out of bounds (%u)", + sizeof(T), b->Capacity()); + } + // Return the requested element + b->Before< T >() = v; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the element after the cursor position. + */ + T GetAfter() const + { + // Acquire a reference to the memory buffer + SRef b(Validate()); + // Are we out of the memory buffer range? + if (b->Capacity() < sizeof(T) || (b->Position() + sizeof(T)) > (b->Capacity() - sizeof(T))) + { + STHROWF("Value size (%u starting at %u) is out of bounds (%u)", + sizeof(T), b->Position(), b->Capacity()); + } + // Return the requested element + return b->After< T >(); + } + + /* -------------------------------------------------------------------------------------------- + * Modify the element after the cursor position. + */ + void SetAfter(T v) + { + // Acquire a reference to the memory buffer + SRef b(Validate()); + // Are we out of the memory buffer range? + if (b->Capacity() < sizeof(T) || (b->Position() + sizeof(T)) > (b->Capacity() - sizeof(T))) + { + STHROWF("Value size (%u starting at %u) is out of bounds (%u)", + sizeof(T), b->Position(), b->Capacity()); + } + // Return the requested element + b->After< T >() = v; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve maximum elements it can hold for a certain type. + */ + SzType GetMax() const + { + return Buffer::Max< T >(); + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the current buffer capacity in element count. + */ + SzType GetSize() const + { + return Validate()->template Size< T >(); + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the current buffer capacity in byte count. + */ + SzType GetCapacity() const + { + return Validate()->Capacity(); + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the current position of the cursor in the buffer. + */ + SzType GetPosition() const + { + return Validate()->template Position< T >(); + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the amount of unused buffer after the edit cursor. + */ + SzType GetRemaining() const + { + return Validate()->template Remaining< T >(); + } + + /* -------------------------------------------------------------------------------------------- + * Grow the size of the internal buffer by the specified amount of bytes. + */ + void Grow(SzType n) + { + return Validate()->Grow(n * sizeof(T)); + } + + /* -------------------------------------------------------------------------------------------- + * Makes sure there is enough capacity to hold the specified element count. + */ + void Adjust(SzType n) + { + // Acquire a reference to the memory buffer + SRef b(Validate()); + // Attempt to perform the requested operation + try + { + Buffer bkp(b->Adjust(n * sizeof(T))); + // Copy the data into the new buffer + b->Write(0, bkp.Data(), bkp.Capacity()); + b->Move(bkp.Position()); + } + catch (const std::exception & e) + { + STHROWF("%s", e.what()); // Re-package + } + } +}; + +} // Namespace:: SqMod + +#endif // _LIBRARY_UTILS_BUFFERINTERPRETER_HPP_ diff --git a/source/Library/Utils/BufferWrapper.cpp b/source/Library/Utils/BufferWrapper.cpp new file mode 100644 index 00000000..a1b551a9 --- /dev/null +++ b/source/Library/Utils/BufferWrapper.cpp @@ -0,0 +1,357 @@ +// ------------------------------------------------------------------------------------------------ +#include "Library/Utils/BufferWrapper.hpp" +#include "Library/Utils/BufferInterpreter.hpp" +#include "Base/Stack.hpp" + +// ------------------------------------------------------------------------------------------------ +#include + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +// ------------------------------------------------------------------------------------------------ +extern void Register_BufferInterpreter(Table & bns); + +// ------------------------------------------------------------------------------------------------ +Object BufferWrapper::Create(SzType n) +{ + // Attempt to create the requested buffer + try + { + return MakeObject(BufferWrapper(SRef(new Buffer(n)))); + } + catch (const Sqrat::Exception & e) + { + throw e; // Re-throw + } + catch (const std::exception & e) + { + STHROWF("%s", e.what()); // Re-package + } + // Shouldn't really reach this point + return NullObject(); +} + +// ------------------------------------------------------------------------------------------------ +void BufferWrapper::WriteByte(SQInteger val) +{ + // Validate the managed buffer reference + Validate(); + // Perform the requested operation + m_Buffer->Push< Uint8 >(ConvTo< Uint8 >::From(val)); +} + +// ------------------------------------------------------------------------------------------------ +void BufferWrapper::WriteShort(SQInteger val) +{ + // Validate the managed buffer reference + Validate(); + // Perform the requested operation + m_Buffer->Push< Int16 >(ConvTo< Int16 >::From(val)); +} + +// ------------------------------------------------------------------------------------------------ +void BufferWrapper::WriteInt(SQInteger val) +{ + // Validate the managed buffer reference + Validate(); + // Perform the requested operation + m_Buffer->Push< Int32 >(ConvTo< Int32 >::From(val)); +} + +// ------------------------------------------------------------------------------------------------ +void BufferWrapper::WriteFloat(SQFloat val) +{ + // Validate the managed buffer reference + Validate(); + // Perform the requested operation + m_Buffer->Push< Float32 >(ConvTo< Float32 >::From(val)); +} + +// ------------------------------------------------------------------------------------------------ +void BufferWrapper::WriteString(CSStr val) +{ + // Validate the managed buffer reference + Validate(); + // Is the given string value even valid? + if (!val) + { + STHROWF("Invalid string argument: null"); + } + // Calculate the string length + Uint16 length = ConvTo< Uint16 >::From(std::strlen(val)); + // Change the size endianness to big endian + Uint16 size = ((length >> 8) & 0xFF) | ((length & 0xFF) << 8); + // Write the size and then the string contents + m_Buffer->Push< Uint16 >(size); + m_Buffer->AppendS(val, length); +} + +// ------------------------------------------------------------------------------------------------ +void BufferWrapper::WriteRawString(CSStr val) +{ + // Validate the managed buffer reference + Validate(); + // Is the given string value even valid? + if (!val) + { + STHROWF("Invalid string argument: null"); + } + // Calculate the string length + Uint16 length = ConvTo< Uint16 >::From(std::strlen(val)); + // Write the the string contents + m_Buffer->AppendS(val, length); +} + +// ------------------------------------------------------------------------------------------------ +SQInteger BufferWrapper::ReadByte() +{ + // Validate the managed buffer reference + ValidateDeeper(); + // Are we out of the memory buffer range? + if (m_Buffer->Position< Int8 >() >= m_Buffer->Size< Int8 >()) + { + STHROWF("Value size (%u starting at %u) is out of bounds (%u)", + sizeof(Int8), m_Buffer->Position(), m_Buffer->Capacity()); + } + // Read one element from the buffer + const Int8 value = m_Buffer->Cursor< Int8 >(); + // Advance the buffer cursor + m_Buffer->Advance< Int8 >(1); + // Return the requested information + return value; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger BufferWrapper::ReadShort() +{ + // Validate the managed buffer reference + ValidateDeeper(); + // Are we out of the memory buffer range? + if (m_Buffer->Position< Int16 >() >= m_Buffer->Size< Int16 >()) + { + STHROWF("Value size (%u starting at %u) is out of bounds (%u)", + sizeof(Int16), m_Buffer->Position(), m_Buffer->Capacity()); + } + // Read one element from the buffer + const Int16 value = m_Buffer->Cursor< Int16 >(); + // Advance the buffer cursor + m_Buffer->Advance< Int16 >(1); + // Return the requested information + return value; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger BufferWrapper::ReadInt() +{ + // Validate the managed buffer reference + ValidateDeeper(); + // Are we out of the memory buffer range? + if (m_Buffer->Position< Int32 >() >= m_Buffer->Size< Int32 >()) + { + STHROWF("Value size (%u starting at %u) is out of bounds (%u)", + sizeof(Int32), m_Buffer->Position(), m_Buffer->Capacity()); + } + // Read one element from the buffer + const Int32 value = m_Buffer->Cursor< Int32 >(); + // Advance the buffer cursor + m_Buffer->Advance< Int32 >(1); + // Return the requested information + return value; +} + +// ------------------------------------------------------------------------------------------------ +SQFloat BufferWrapper::ReadFloat() +{ + // Validate the managed buffer reference + ValidateDeeper(); + // Are we out of the memory buffer range? + if (m_Buffer->Position< Float32 >() >= m_Buffer->Size< Float32 >()) + { + STHROWF("Value size (%u starting at %u) is out of bounds (%u)", + sizeof(Float32), m_Buffer->Position(), m_Buffer->Capacity()); + } + // Read one element from the buffer + const Float32 value = m_Buffer->Cursor< Float32 >(); + // Advance the buffer cursor + m_Buffer->Advance< Float32 >(1); + // Return the requested information + return value; +} + +// ------------------------------------------------------------------------------------------------ +Object BufferWrapper::ReadString() +{ + // Validate the managed buffer reference + ValidateDeeper(); + // Are we out of the memory buffer range? + if (m_Buffer->Position< Int16 >() >= m_Buffer->Size< Int16 >()) + { + STHROWF("Value size (%u starting at %u) is out of bounds (%u)", + sizeof(Int16), m_Buffer->Position(), m_Buffer->Capacity()); + } + // Read one element from the buffer + Int16 length = m_Buffer->Cursor< Int16 >(); + // Convert the length to little endian + length = ((length >> 8) & 0xFF) | ((length & 0xFF) << 8); + // Validate the obtained length + if ((m_Buffer->Position() + sizeof(Int16) + length) >= m_Buffer->Size()) + { + STHROWF("String size (%u starting at %u) is out of bounds (%u)", + length, m_Buffer->Position() + sizeof(Int16), m_Buffer->Capacity()); + } + // Advance the buffer to the actual string + m_Buffer->Advance< Int16 >(1); + // Remember the current stack size + const StackGuard sg; + // Attempt to create the string as an object + sq_pushstring(DefaultVM::Get(), &m_Buffer->Cursor(), length); + // Advance the cursor after the string + m_Buffer->Advance(length); + // Return the resulted object + return Var< Object >(DefaultVM::Get(), -1).value; +} + +// ------------------------------------------------------------------------------------------------ +Object BufferWrapper::ReadRawString(Uint32 len) +{ + // Validate the managed buffer reference + ValidateDeeper(); + // Validate the obtained length + if ((m_Buffer->Position() + len) >= m_Buffer->Size()) + { + STHROWF("String size (%u starting at %u) is out of bounds (%u)", + len, m_Buffer->Position(), m_Buffer->Capacity()); + } + // Remember the current stack size + const StackGuard sg; + // Attempt to create the string as an object + sq_pushstring(DefaultVM::Get(), &m_Buffer->Cursor(), len); + // Advance the cursor after the string + m_Buffer->Advance(len); + // Return the resulted object + return Var< Object >(DefaultVM::Get(), -1).value; +} + +// ------------------------------------------------------------------------------------------------ +BufferInterpreter< Int8 > BufferWrapper::GetInt8Interpreter() const +{ + return BufferInterpreter< Int8 >(m_Buffer); +} + +// ------------------------------------------------------------------------------------------------ +BufferInterpreter< Uint8 > BufferWrapper::GetUint8Interpreter() const +{ + return BufferInterpreter< Uint8 >(m_Buffer); +} + +// ------------------------------------------------------------------------------------------------ +BufferInterpreter< Int16 > BufferWrapper::GetInt16Interpreter() const +{ + return BufferInterpreter< Int16 >(m_Buffer); +} + +// ------------------------------------------------------------------------------------------------ +BufferInterpreter< Uint16 > BufferWrapper::GetUint16Interpreter() const +{ + return BufferInterpreter< Uint16 >(m_Buffer); +} + +// ------------------------------------------------------------------------------------------------ +BufferInterpreter< Int32 > BufferWrapper::GetInt32Interpreter() const +{ + return BufferInterpreter< Int32 >(m_Buffer); +} + +// ------------------------------------------------------------------------------------------------ +BufferInterpreter< Uint32 > BufferWrapper::GetUint32Interpreter() const +{ + return BufferInterpreter< Uint32 >(m_Buffer); +} + +// ------------------------------------------------------------------------------------------------ +BufferInterpreter< Int64 > BufferWrapper::GetInt64Interpreter() const +{ + return BufferInterpreter< Int64 >(m_Buffer); +} + +// ------------------------------------------------------------------------------------------------ +BufferInterpreter< Uint64 > BufferWrapper::GetUint64Interpreter() const +{ + return BufferInterpreter< Uint64 >(m_Buffer); +} + +// ------------------------------------------------------------------------------------------------ +BufferInterpreter< Float32 > BufferWrapper::GetFloat32Interpreter() const +{ + return BufferInterpreter< Float32 >(m_Buffer); +} + +// ------------------------------------------------------------------------------------------------ +BufferInterpreter< Float64 > BufferWrapper::GetFloat64Interpreter() const +{ + return BufferInterpreter< Float64 >(m_Buffer); +} + +// ================================================================================================ +void Register_Buffer(HSQUIRRELVM vm) +{ + Table bns(vm); + + bns.Bind(_SC("Wrapper"), + Class< BufferWrapper >(vm, _SC("SqBufferWrapper")) + // Constructors + .Ctor() + // Properties + .Prop(_SC("Front"), &BufferWrapper::GetFront, &BufferWrapper::SetFront) + .Prop(_SC("Next"), &BufferWrapper::GetNext, &BufferWrapper::SetNext) + .Prop(_SC("Back"), &BufferWrapper::GetBack, &BufferWrapper::SetBack) + .Prop(_SC("Prev"), &BufferWrapper::GetPrev, &BufferWrapper::SetPrev) + .Prop(_SC("Cursor"), &BufferWrapper::GetCursor, &BufferWrapper::SetCursor) + .Prop(_SC("Before"), &BufferWrapper::GetBefore, &BufferWrapper::SetBefore) + .Prop(_SC("After"), &BufferWrapper::GetAfter, &BufferWrapper::SetAfter) + .Prop(_SC("Max"), &BufferWrapper::GetMax) + .Prop(_SC("Size"), &BufferWrapper::GetSize) + .Prop(_SC("Capacity"), &BufferWrapper::GetCapacity) + .Prop(_SC("Position"), &BufferWrapper::GetPosition) + .Prop(_SC("Remaining"), &BufferWrapper::GetRemaining) + .Prop(_SC("Int8"), &BufferWrapper::GetInt8Interpreter) + .Prop(_SC("Uint8"), &BufferWrapper::GetUint8Interpreter) + .Prop(_SC("Int16"), &BufferWrapper::GetInt16Interpreter) + .Prop(_SC("Uint16"), &BufferWrapper::GetUint16Interpreter) + .Prop(_SC("Int32"), &BufferWrapper::GetInt32Interpreter) + .Prop(_SC("Uint32"), &BufferWrapper::GetUint32Interpreter) + .Prop(_SC("Int64"), &BufferWrapper::GetInt64Interpreter) + .Prop(_SC("Uint64"), &BufferWrapper::GetUint64Interpreter) + .Prop(_SC("Float32"), &BufferWrapper::GetFloat32Interpreter) + .Prop(_SC("Float64"), &BufferWrapper::GetFloat64Interpreter) + // Member Methods + .Func(_SC("Get"), &BufferWrapper::Get) + .Func(_SC("Set"), &BufferWrapper::Set) + .Func(_SC("Advance"), &BufferWrapper::Advance) + .Func(_SC("Retreat"), &BufferWrapper::Retreat) + .Func(_SC("Push"), &BufferWrapper::Push) + .Func(_SC("Grow"), &BufferWrapper::Grow) + .Func(_SC("Adjust"), &BufferWrapper::Adjust) + .Func(_SC("WriteByte"), &BufferWrapper::WriteByte) + .Func(_SC("WriteShort"), &BufferWrapper::WriteShort) + .Func(_SC("WriteInt"), &BufferWrapper::WriteInt) + .Func(_SC("WriteFloat"), &BufferWrapper::WriteFloat) + .Func(_SC("WriteString"), &BufferWrapper::WriteString) + .Func(_SC("WriteRawString"), &BufferWrapper::WriteRawString) + .Func(_SC("ReadByte"), &BufferWrapper::ReadByte) + .Func(_SC("ReadShort"), &BufferWrapper::ReadShort) + .Func(_SC("ReadInt"), &BufferWrapper::ReadInt) + .Func(_SC("ReadFloat"), &BufferWrapper::ReadFloat) + .Func(_SC("ReadString"), &BufferWrapper::ReadString) + .Func(_SC("ReadRawString"), &BufferWrapper::ReadRawString) + ); + + Register_BufferInterpreter(bns); + + bns.Func(_SC("Create"), &BufferWrapper::Create); + + RootTable(vm).Bind(_SC("SqBuffer"), bns); +} + +} // Namespace:: SqMod diff --git a/source/Library/Utils/BufferWrapper.hpp b/source/Library/Utils/BufferWrapper.hpp new file mode 100644 index 00000000..021f0757 --- /dev/null +++ b/source/Library/Utils/BufferWrapper.hpp @@ -0,0 +1,644 @@ +#ifndef _LIBRARY_UTILS_BUFFERWRAPPER_HPP_ +#define _LIBRARY_UTILS_BUFFERWRAPPER_HPP_ + +// ------------------------------------------------------------------------------------------------ +#include "Base/Shared.hpp" +#include "Base/Buffer.hpp" + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +// ------------------------------------------------------------------------------------------------ +template < typename T > class BufferInterpreter; + +/* ------------------------------------------------------------------------------------------------ + * Squirrel wrapper for the shared buffer class. +*/ +class BufferWrapper +{ +private: + + // -------------------------------------------------------------------------------------------- + typedef SharedPtr< Buffer > SRef; // Strong reference type to the managed memory buffer. + typedef WeakPtr< Buffer > WRef; // Weak reference type to the managed memory buffer. + + // -------------------------------------------------------------------------------------------- + SRef m_Buffer; // The managed memory buffer. + +public: + + // -------------------------------------------------------------------------------------------- + typedef Buffer::Value Value; // The type of value used to represent a byte. + + // -------------------------------------------------------------------------------------------- + typedef Value & Reference; // A reference to the stored value type. + typedef const Value & ConstRef; // A const reference to the stored value type. + + // -------------------------------------------------------------------------------------------- + typedef Value * Pointer; // A pointer to the stored value type. + typedef const Value * ConstPtr; // A const pointer to the stored value type. + + // -------------------------------------------------------------------------------------------- + typedef Buffer::SzType SzType; // The type used to represent size in general. + +public: + + /* -------------------------------------------------------------------------------------------- + * Create a memory buffer with the requested size. + */ + static Object Create(SzType n); + + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + BufferWrapper(const SRef & ref) + : m_Buffer(ref) + { + /* ... */ + } + + /* -------------------------------------------------------------------------------------------- + * Buffer constructor. + */ + BufferWrapper(Buffer && b) + : m_Buffer(new Buffer(std::move(b))) + { + /* ... */ + } + + /* -------------------------------------------------------------------------------------------- + * Copy constructor. + */ + BufferWrapper(const BufferWrapper & o) = default; + + /* -------------------------------------------------------------------------------------------- + * Move constructor. + */ + BufferWrapper(BufferWrapper && o) = default; + + /* -------------------------------------------------------------------------------------------- + * Destructor. + */ + ~BufferWrapper() = default; + + /* -------------------------------------------------------------------------------------------- + * Copy assignment operator. + */ + BufferWrapper & operator = (const BufferWrapper & o) = default; + + /* -------------------------------------------------------------------------------------------- + * Move assignment operator. + */ + BufferWrapper & operator = (BufferWrapper && o) = default; + + /* -------------------------------------------------------------------------------------------- + * Retrieve a reference to the managed memory buffer. + */ + const SRef & GetRef() const + { + return m_Buffer; + } + + /* -------------------------------------------------------------------------------------------- + * Validate the managed memory buffer reference. + */ + void Validate() const + { + // Do we even point to a valid buffer? + if (!m_Buffer) + { + STHROWF("Invalid memory buffer reference"); + } + } + + /* -------------------------------------------------------------------------------------------- + * Validate the managed memory buffer reference and the buffer itself. + */ + void ValidateDeeper() const + { + // Do we even point to a valid buffer? + if (!m_Buffer) + { + STHROWF("Invalid memory buffer reference"); + } + // Validate the buffer itself + else if (!(*m_Buffer)) + { + STHROWF("Invalid memory buffer"); + } + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve a certain element type at the specified position. + */ + Value Get(SzType n) const + { + // Validate the managed buffer reference + Validate(); + // Are we out of the memory buffer range? + if (n >= m_Buffer->Size()) + { + STHROWF("Index (%u) is out of bounds (%u)", n, m_Buffer->Size()); + } + // Return the requested element + return m_Buffer->At(n); + } + + /* -------------------------------------------------------------------------------------------- + * Modify a certain element type at the specified position. + */ + void Set(SzType n, Value v) + { + // Validate the managed buffer reference + Validate(); + // Are we out of the memory buffer range? + if (n >= m_Buffer->Size()) + { + STHROWF("Index (%u) is out of bounds (%u)", n, m_Buffer->Size()); + } + // Return the requested element + m_Buffer->At(n) = v; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the element at the front of the buffer. + */ + Value GetFront() const + { + // Validate the managed buffer reference + Validate(); + // Are we out of the memory buffer range? + if (m_Buffer->Capacity() < sizeof(Value)) + { + STHROWF("Value size (%u starting at 0) is out of bounds (%u)", + sizeof(Value), m_Buffer->Capacity()); + } + // Return the requested element + return m_Buffer->Front(); + } + + /* -------------------------------------------------------------------------------------------- + * Modify the element at the front of the buffer. + */ + void SetFront(Value v) + { + // Validate the managed buffer reference + Validate(); + // Are we out of the memory buffer range? + if (m_Buffer->Capacity() < sizeof(Value)) + { + STHROWF("Value size (%u starting at 0) is out of bounds (%u)", + sizeof(Value), m_Buffer->Capacity()); + } + // Return the requested element + m_Buffer->Front() = v; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the element after the first element in the buffer. + */ + Value GetNext() const + { + // Validate the managed buffer reference + Validate(); + // Are we out of the memory buffer range? + if (m_Buffer->Capacity() < (sizeof(Value) * 2)) + { + STHROWF("Value size (%u starting at %u) is out of bounds (%u)", + sizeof(Value), sizeof(Value), m_Buffer->Capacity()); + } + // Return the requested element + return m_Buffer->Next(); + } + + /* -------------------------------------------------------------------------------------------- + * Modify the element after the first element in the buffer. + */ + void SetNext(Value v) + { + // Validate the managed buffer reference + Validate(); + // Are we out of the memory buffer range? + if (m_Buffer->Capacity() < (sizeof(Value) * 2)) + { + STHROWF("Value size (%u starting at %u) is out of bounds (%u)", + sizeof(Value), sizeof(Value), m_Buffer->Capacity()); + } + // Return the requested element + m_Buffer->Next() = v; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the element at the back of the buffer. + */ + Value GetBack() const + { + // Validate the managed buffer reference + Validate(); + // Are we out of the memory buffer range? + if (m_Buffer->Capacity() < sizeof(Value)) + { + STHROWF("Value size (%u starting at 0) is out of bounds (%u)", + sizeof(Value), m_Buffer->Capacity()); + } + // Return the requested element + return m_Buffer->Back(); + } + + /* -------------------------------------------------------------------------------------------- + * Modify the element at the back of the buffer. + */ + void SetBack(Value v) + { + // Validate the managed buffer reference + Validate(); + // Are we out of the memory buffer range? + if (m_Buffer->Capacity() < sizeof(Value)) + { + STHROWF("Value size (%u starting at 0) is out of bounds (%u)", + sizeof(Value), m_Buffer->Capacity()); + } + // Return the requested element + m_Buffer->Back() = v; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the element before the last element in the buffer. + */ + Value GetPrev() const + { + // Validate the managed buffer reference + Validate(); + // Are we out of the memory buffer range? + if (m_Buffer->Capacity() < (sizeof(Value) * 2)) + { + STHROWF("Value size (%u starting at %u) is out of bounds (%u)", + sizeof(Value), sizeof(Value), m_Buffer->Capacity()); + } + // Return the requested element + return m_Buffer->Prev(); + } + + /* -------------------------------------------------------------------------------------------- + * Modify the element before the last element in the buffer. + */ + void SetPrev(Value v) + { + // Validate the managed buffer reference + Validate(); + // Are we out of the memory buffer range? + if (m_Buffer->Capacity() < (sizeof(Value) * 2)) + { + STHROWF("Value size (%u starting at %u) is out of bounds (%u)", + sizeof(Value), sizeof(Value), m_Buffer->Capacity()); + } + // Return the requested element + m_Buffer->Prev() = v; + } + + /* -------------------------------------------------------------------------------------------- + * Reposition the edit cursor to the specified number of elements ahead. + */ + void Advance(SzType n) + { + // Validate the managed buffer reference + Validate(); + // Perform the requested operation + m_Buffer->Advance(n); + } + + /* -------------------------------------------------------------------------------------------- + * Reposition the edit cursor to the specified number of elements behind. + */ + void Retreat(SzType n) + { + // Validate the managed buffer reference + Validate(); + // Perform the requested operation + m_Buffer->Retreat(n); + } + + /* -------------------------------------------------------------------------------------------- + * Reposition the edit cursor to a fixed position within the buffer. + */ + void Move(SzType n) + { + // Validate the managed buffer reference + Validate(); + // Perform the requested operation + m_Buffer->Move(n); + } + + /* -------------------------------------------------------------------------------------------- + * Append a value to the current cursor location and advance the cursor. + */ + void Push(Value v) + { + // Validate the managed buffer reference + Validate(); + // Perform the requested operation + m_Buffer->Push(v); + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the element at the cursor position. + */ + Value GetCursor() const + { + // Validate the managed buffer reference + Validate(); + // Are we out of the memory buffer range? + if (m_Buffer->Position() >= m_Buffer->Size()) + { + STHROWF("Value size (%u starting at %u) is out of bounds (%u)", + sizeof(Value), m_Buffer->Position(), m_Buffer->Capacity()); + } + // Return the requested element + return m_Buffer->Cursor(); + } + + /* -------------------------------------------------------------------------------------------- + * Modify the element at the cursor position. + */ + void SetCursor(Value v) + { + // Validate the managed buffer reference + Validate(); + // Are we out of the memory buffer range? + if (m_Buffer->Position() >= m_Buffer->Size()) + { + STHROWF("Value size (%u starting at %u) is out of bounds (%u)", + sizeof(Value), m_Buffer->Position(), m_Buffer->Capacity()); + } + // Return the requested element + m_Buffer->Cursor() = v; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the element before the cursor position. + */ + Value GetBefore() const + { + // Validate the managed buffer reference + Validate(); + // Are we out of the memory buffer range? + if (m_Buffer->Position() < sizeof(Value)) + { + STHROWF("Value size (%u starting at 0) is out of bounds (%u)", + sizeof(Value), m_Buffer->Capacity()); + } + // Return the requested element + return m_Buffer->Before(); + } + + /* -------------------------------------------------------------------------------------------- + * Modify the element before the cursor position. + */ + void SetBefore(Value v) + { + // Validate the managed buffer reference + Validate(); + // Are we out of the memory buffer range? + if (m_Buffer->Position() < sizeof(Value)) + { + STHROWF("Value size (%u starting at 0) is out of bounds (%u)", + sizeof(Value), m_Buffer->Capacity()); + } + // Return the requested element + m_Buffer->Before() = v; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the element after the cursor position. + */ + Value GetAfter() const + { + // Validate the managed buffer reference + Validate(); + // Are we out of the memory buffer range? + if (m_Buffer->Capacity() < sizeof(Value) || + (m_Buffer->Position() + sizeof(Value)) > (m_Buffer->Capacity() - sizeof(Value))) + { + STHROWF("Value size (%u starting at %u) is out of bounds (%u)", + sizeof(Value), m_Buffer->Position(), m_Buffer->Capacity()); + } + // Return the requested element + return m_Buffer->After(); + } + + /* -------------------------------------------------------------------------------------------- + * Modify the element after the cursor position. + */ + void SetAfter(Value v) + { + // Validate the managed buffer reference + Validate(); + // Are we out of the memory buffer range? + if (m_Buffer->Capacity() < sizeof(Value) || + (m_Buffer->Position() + sizeof(Value)) > (m_Buffer->Capacity() - sizeof(Value))) + { + STHROWF("Value size (%u starting at %u) is out of bounds (%u)", + sizeof(Value), m_Buffer->Position(), m_Buffer->Capacity()); + } + // Return the requested element + m_Buffer->After() = v; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve maximum elements it can hold for a certain type. + */ + SzType GetMax() const + { + return Buffer::Max(); + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the current buffer capacity in element count. + */ + SzType GetSize() const + { + // Validate the managed buffer reference + Validate(); + // Return the requested information + return m_Buffer->Size(); + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the current buffer capacity in byte count. + */ + SzType GetCapacity() const + { + // Validate the managed buffer reference + Validate(); + // Return the requested information + return m_Buffer->Capacity(); + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the current position of the cursor in the buffer. + */ + SzType GetPosition() const + { + // Validate the managed buffer reference + Validate(); + // Return the requested information + return m_Buffer->Position(); + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the amount of unused buffer after the edit cursor. + */ + SzType GetRemaining() const + { + // Validate the managed buffer reference + Validate(); + // Return the requested information + return m_Buffer->Remaining(); + } + + /* -------------------------------------------------------------------------------------------- + * Grow the size of the internal buffer by the specified amount of bytes. + */ + void Grow(SzType n) + { + // Validate the managed buffer reference + Validate(); + // Perform the requested operation + return m_Buffer->Grow(n * sizeof(Value)); + } + + /* -------------------------------------------------------------------------------------------- + * Makes sure there is enough capacity to hold the specified element count. + */ + void Adjust(SzType n) + { + // Validate the managed buffer reference + Validate(); + // Attempt to perform the requested operation + try + { + Buffer bkp(m_Buffer->Adjust(n * sizeof(Value))); + // Copy the data into the new buffer + m_Buffer->Write(0, bkp.Data(), bkp.Capacity()); + m_Buffer->Move(bkp.Position()); + } + catch (const std::exception & e) + { + STHROWF("%s", e.what()); // Re-package + } + } + + /* -------------------------------------------------------------------------------------------- + * Write a 8 bit byte to the stream buffer. + */ + void WriteByte(SQInteger val); + + /* -------------------------------------------------------------------------------------------- + * Write a 16 bit short to the stream buffer. + */ + void WriteShort(SQInteger val); + + /* -------------------------------------------------------------------------------------------- + * Write a 32 bit integer to the stream buffer. + */ + void WriteInt(SQInteger val); + + /* -------------------------------------------------------------------------------------------- + * Write a 32 bit float to the stream buffer. + */ + void WriteFloat(SQFloat val); + + /* -------------------------------------------------------------------------------------------- + * Write a string to the stream buffer. + */ + void WriteString(CSStr val); + + /* -------------------------------------------------------------------------------------------- + * Write a raw string to the stream buffer. + */ + void WriteRawString(CSStr val); + + /* -------------------------------------------------------------------------------------------- + * Read a 8 bit byte to the stream buffer. + */ + SQInteger ReadByte(); + + /* -------------------------------------------------------------------------------------------- + * Read a 16 bit short to the stream buffer. + */ + SQInteger ReadShort(); + + /* -------------------------------------------------------------------------------------------- + * Read a 32 bit integer to the stream buffer. + */ + SQInteger ReadInt(); + + /* -------------------------------------------------------------------------------------------- + * Read a 32 bit float to the stream buffer. + */ + SQFloat ReadFloat(); + + /* -------------------------------------------------------------------------------------------- + * Read a string to the stream buffer. + */ + Object ReadString(); + + /* -------------------------------------------------------------------------------------------- + * Read a raw string to the stream buffer. + */ + Object ReadRawString(Uint32 len); + + /* -------------------------------------------------------------------------------------------- + * Retrieve a signed 8 bit interpreter to this buffer. + */ + BufferInterpreter< Int8 > GetInt8Interpreter() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve an unsigned 8 bit interpreter to this buffer. + */ + BufferInterpreter< Uint8 > GetUint8Interpreter() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve a signed 16 bit interpreter to this buffer. + */ + BufferInterpreter< Int16 > GetInt16Interpreter() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve an unsigned 16 bit interpreter to this buffer. + */ + BufferInterpreter< Uint16 > GetUint16Interpreter() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve a signed 32 bit interpreter to this buffer. + */ + BufferInterpreter< Int32 > GetInt32Interpreter() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve an unsigned 32 bit interpreter to this buffer. + */ + BufferInterpreter< Uint32 > GetUint32Interpreter() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve a signed 64 bit interpreter to this buffer. + */ + BufferInterpreter< Int64 > GetInt64Interpreter() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve an unsigned 64 bit interpreter to this buffer. + */ + BufferInterpreter< Uint64 > GetUint64Interpreter() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve a 32 bit floating point interpreter to this buffer. + */ + BufferInterpreter< Float32 > GetFloat32Interpreter() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve a 64 bit floating point interpreter to this buffer. + */ + BufferInterpreter< Float64 > GetFloat64Interpreter() const; +}; + +} // Namespace:: SqMod + +#endif // _LIBRARY_UTILS_BUFFERWRAPPER_HPP_ diff --git a/source/Logger.cpp b/source/Logger.cpp index 8ba42c54..db752ae9 100644 --- a/source/Logger.cpp +++ b/source/Logger.cpp @@ -1,22 +1,26 @@ // ------------------------------------------------------------------------------------------------ #include "Logger.hpp" -#include "Core.hpp" // ------------------------------------------------------------------------------------------------ -#include -#include -#include +#include +#include +#include +#include // ------------------------------------------------------------------------------------------------ -namespace { +#include +// ------------------------------------------------------------------------------------------------ #ifdef SQMOD_OS_WINDOWS // ------------------------------------------------------------------------------------------------ #include +// ------------------------------------------------------------------------------------------------ +namespace { + /* ------------------------------------------------------------------------------------------------ - * ... + * Common windows colors. */ enum { @@ -38,84 +42,188 @@ enum }; /* ------------------------------------------------------------------------------------------------ - * ... + * Logging colors. */ enum { LC_DBG = LC_LIGHT_BLUE, - LC_USER = LC_GRAY, + LC_USR = LC_GRAY, LC_SCS = LC_LIGHT_GREEN, LC_INF = LC_LIGHT_CYAN, LC_WRN = LC_LIGHT_YELLOW, - LC_ERR = LC_LIGHT_MAGENTA, - LC_FTL = LC_LIGHT_RED + LC_ERR = LC_LIGHT_RED, + LC_FTL = LC_LIGHT_MAGENTA }; -#endif // SQMOD_OS_WINDOWS +/* ------------------------------------------------------------------------------------------------ + * Identify the associated message color. +*/ +inline WORD GetLevelColor(BYTE level) +{ + switch (level) + { + case SqMod::LOGL_DBG: return LC_DBG; + case SqMod::LOGL_USR: return LC_USR; + case SqMod::LOGL_SCS: return LC_SCS; + case SqMod::LOGL_INF: return LC_INF; + case SqMod::LOGL_WRN: return LC_WRN; + case SqMod::LOGL_ERR: return LC_ERR; + case SqMod::LOGL_FTL: return LC_FTL; + default: return LC_NORMAL; + } +} } // Namespace:: +#endif // SQMOD_OS_WINDOWS + // ------------------------------------------------------------------------------------------------ namespace SqMod { -// -------------------------------------------------------------------------------------------- -SQMOD_MANAGEDPTR_TYPE(Logger) _Log = SQMOD_MANAGEDPTR_MAKE(Logger, nullptr); - /* ------------------------------------------------------------------------------------------------ - * ... + * Identify the message prefix. */ -inline CCStr GetLevelTag(Uint8 type) +static inline CCStr GetLevelTag(Uint8 level) { - switch (type) + switch (level) { - case LL_DBG: return "[DBG]"; - case LL_USR: return "[USR]"; - case LL_SCS: return "[SCS]"; - case LL_INF: return "[INF]"; - case LL_WRN: return "[WRN]"; - case LL_ERR: return "[ERR]"; - case LL_FTL: return "[FTL]"; + case LOGL_DBG: return "[DBG]"; + case LOGL_USR: return "[USR]"; + case LOGL_SCS: return "[SCS]"; + case LOGL_INF: return "[INF]"; + case LOGL_WRN: return "[WRN]"; + case LOGL_ERR: return "[ERR]"; + case LOGL_FTL: return "[FTL]"; default: return "[UNK]"; } } -#ifdef SQMOD_OS_WINDOWS - /* ------------------------------------------------------------------------------------------------ - * ... + * Identify the message prefix and color. */ -inline Uint16 GetLevelColor(Uint8 type) +static inline CCStr GetColoredLevelTag(Uint8 level) { - switch (type) + switch (level) { - case LL_DBG: return LC_DBG; - case LL_USR: return LC_USER; - case LL_SCS: return LC_SCS; - case LL_INF: return LC_INF; - case LL_WRN: return LC_WRN; - case LL_ERR: return LC_ERR; - case LL_FTL: return LC_FTL; - default: return LC_NORMAL; + case LOGL_DBG: return "\033[21;94m[[DBG]\033[0m"; + case LOGL_USR: return "\033[21;37m[[USR]\033[0m"; + case LOGL_SCS: return "\033[21;92m[[SCS]\033[0m"; + case LOGL_INF: return "\033[21;96m[[INF]\033[0m"; + case LOGL_WRN: return "\033[21;93m[[WRN]\033[0m"; + case LOGL_ERR: return "\033[21;91m[[ERR]\033[0m"; + case LOGL_FTL: return "\033[21;95m[[FTL]\033[0m"; + default: return "\033[21;0m[[UNK]\033[0m"; } } -#else /* ------------------------------------------------------------------------------------------------ - * ... + * Output a logging message to the console window. */ -inline CCStr GetLevelColor(Uint8 /*type*/) +static inline void OutputConsoleMessage(Uint8 level, bool sub, CCStr tms, CCStr msg) { - return g_EmptyStr; +#ifdef SQMOD_OS_WINDOWS + HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE); + CONSOLE_SCREEN_BUFFER_INFO csb_state; + GetConsoleScreenBufferInfo(hstdout, &csb_state); + SetConsoleTextAttribute(hstdout, GetLevelColor(level)); + if (tms) + { + std::printf("%s %s ", GetLevelTag(level), tms); + } + else + { + std::printf("%s ", GetLevelTag(level)); + } + SetConsoleTextAttribute(hstdout, sub ? LC_NORMAL : LC_WHITE); + std::puts(msg); + SetConsoleTextAttribute(hstdout, csb_state.wAttributes); +#else + if (tms) + { + std::printf("%s %s ", GetColoredLevelTag(level), tms); + } + else + { + std::printf("%s ", GetColoredLevelTag(level)); + } + std::puts(msg); +#endif // SQMOD_OS_WINDOWS } -#endif // SQMOD_OS_WINDOWS +/* -------------------------------------------------------------------------------------------- + * Raw console message output. +*/ +static inline void OutputMessageImpl(CCStr msg, va_list args) +{ +#if defined(WIN32) || defined(_WIN32) + HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE); + + CONSOLE_SCREEN_BUFFER_INFO csb_before; + GetConsoleScreenBufferInfo( hstdout, &csb_before); + SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN); + std::printf("[SQMOD] "); + + SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); + std::vprintf(msg, args); + std::puts(""); + + SetConsoleTextAttribute(hstdout, csb_before.wAttributes); +#else + std::printf("\033[21;32m[SQMOD]\033[0m"); + std::vprintf(msg, args); + std::puts(""); +#endif +} + +/* -------------------------------------------------------------------------------------------- + * Raw console error output. +*/ +static inline void OutputErrorImpl(CCStr msg, va_list args) +{ +#if defined(WIN32) || defined(_WIN32) + HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE); + + CONSOLE_SCREEN_BUFFER_INFO csb_before; + GetConsoleScreenBufferInfo( hstdout, &csb_before); + SetConsoleTextAttribute(hstdout, FOREGROUND_RED | FOREGROUND_INTENSITY); + std::printf("[SQMOD] "); + + SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); + std::vprintf(msg, args); + std::puts(""); + + SetConsoleTextAttribute(hstdout, csb_before.wAttributes); +#else + std::printf("\033[21;91m[SQMOD]\033[0m"); + std::vprintf(msg, args); + std::puts(""); +#endif +} + +/* ------------------------------------------------------------------------------------------------ + * Identify the associated message color. +*/ +static inline CCStr GetTimeStampStr() +{ + static CharT tmbuff[80]; + std::time_t t = std::time(nullptr); + std::strftime(tmbuff, sizeof(tmbuff), "%Y-%m-%d %H:%M:%S", std::localtime(&t)); + // Return the resulted buffer + return tmbuff; +} + +// ------------------------------------------------------------------------------------------------ +Logger Logger::s_Inst; // ------------------------------------------------------------------------------------------------ Logger::Logger() - : m_Buffer(4096) - , m_TmBuff() - , m_Levels(LL_ANY) - , m_Time(false) + : m_Buffer() + , m_ConsoleLevels(LOGL_ANY) + , m_LogFileLevels(~LOGL_DBG) + , m_ConsoleTime(false) + , m_LogFileTime(true) + , m_File(nullptr) + , m_Filename() { /* ... */ } @@ -123,57 +231,174 @@ Logger::Logger() // ------------------------------------------------------------------------------------------------ Logger::~Logger() { - /* ... */ + Close(); } // ------------------------------------------------------------------------------------------------ -void Logger::Send(Uint8 type, bool sub, CCStr fmt, va_list args) +void Logger::Close() { - if (!(m_Levels & type)) - return; - m_Buffer.WriteF(0, fmt, args); - Proccess(type, sub); + // Is there a file handle to close? + if (m_File) + { + // Flush buffered data + std::fflush(m_File); + // Close the file handle + std::fclose(m_File); + // Prevent further use of this file handle + m_File = nullptr; + } } // ------------------------------------------------------------------------------------------------ -void Logger::Message(Uint8 type, bool sub, CCStr fmt, ...) +void Logger::SetLogFilename(CCStr filename) { - if (!(m_Levels & type)) - return; - va_list args; - va_start(args, fmt); - m_Buffer.WriteF(0, fmt, args); - Proccess(type, sub); - va_end(args); + // Close the current logging file, if any + Close(); + // Clear the current name + m_Filename.clear(); + // Was there a name specified? + if (!filename || *filename == '\0') + { + return; // We're done here! + } + // Make sure the internal buffer has some memory + m_Buffer.Adjust(1024); + // Generate the filename using the current timestamp + std::time_t t = std::time(nullptr); + std::strftime(m_Buffer.Data(), m_Buffer.Size(), filename, std::localtime(&t)); + // Is the resulted filename valid? + if (m_Buffer.At(0) != '\0') + { + m_Filename.assign(m_Buffer.Data()); + } + else + { + return; // We're done here! + } + // Attempt to open the file for writing + m_File = std::fopen(m_Filename.c_str(), "w"); + // See if the file could be opened + if (!m_File) + { + OutputError("Unable to open the log file (%s) : %s", m_Filename.c_str(), std::strerror(errno)); + } +} + +// ------------------------------------------------------------------------------------------------ +void Logger::Initialize(CCStr filename) +{ + // Close the logging file + Close(); + // Allocate some memory in the buffer + m_Buffer.Adjust(1024); + // Set the log file name and open the file if necessary + SetLogFilename(filename); +} + +// ------------------------------------------------------------------------------------------------ +void Logger::Terminate() +{ + // Release all the buffer resources and references + m_Buffer.ResetAll(); +} + +// ------------------------------------------------------------------------------------------------ +void Logger::Proccess(Uint8 level, bool sub) +{ + // Obtain the time-stamp if necessary + CCStr tms = (m_ConsoleTime || m_LogFileTime) ? GetTimeStampStr() : nullptr; + // Are we allowed to send this message level to console? + if (m_ConsoleLevels & level) + { + OutputConsoleMessage(level, sub, (m_ConsoleTime ? tms : nullptr), m_Buffer.Get()); + } + // Are we allowed to write it to a file? + if (m_File && (m_LogFileLevels & level)) + { + // Write the level tag + std::fputs(GetLevelTag(level), m_File); + std::fputc(' ', m_File); + // Should we include the time-stamp? + if (m_LogFileTime && tms) + { + std::fputs(tms, m_File); + std::fputc(' ', m_File); + } + // Write the message + std::fputs(m_Buffer.Get(), m_File); + // Append a new line + std::fputc('\n', m_File); + } +} + +// ------------------------------------------------------------------------------------------------ +void Logger::Send(Uint8 level, bool sub, CCStr fmt, va_list args) +{ + // Is this level even allowed? + if ((m_ConsoleLevels & level) || (m_LogFileLevels & level)) + { + // Generate the message in the buffer + m_Buffer.WriteF(0, fmt, args); + // Process the message in the buffer + Proccess(level, sub); + } +} + +// ------------------------------------------------------------------------------------------------ +void Logger::Write(Uint8 level, bool sub, CCStr fmt, ...) +{ + if ((m_ConsoleLevels & level) || (m_LogFileLevels & level)) + { + // Initialize the variable argument list + va_list args; + va_start(args, fmt); + // Generate the message in the buffer + m_Buffer.WriteF(0, fmt, args); + // Finalize the variable argument list + va_end(args); + // Process the message in the buffer + Proccess(level, sub); + } } // ------------------------------------------------------------------------------------------------ void Logger::Debug(CCStr fmt, ...) { + // Initialize the variable argument list va_list args; va_start(args, fmt); + // Forward the call to the actual debug function Debug(fmt, args); + // Finalize the variable argument list va_end(args); } void Logger::Debug(CCStr fmt, va_list args) { + using namespace Sqrat; + // Retrieve the default Squirrel VM HSQUIRRELVM vm = DefaultVM::Get(); + // Used to acquire SQStackInfos si; + // Write the message to the buffer Int32 ret = m_Buffer.WriteF(0, fmt, args); - + // Obtain information about the current stack level if (SQ_SUCCEEDED(sq_stackinfos(vm, 1, &si))) + { m_Buffer.WriteF(ret, "\n[\n=>Location: %s\n=>Line: %d\n=>Function: %s\n]" , si.source ? si.source : _SC("unknown") , si.line , si.funcname ? si.funcname : _SC("unknown")); + } else + { m_Buffer.WriteF(ret, "\n[\n=>Location: unknown\n=>Line: unknown\n=>Function: unknown\n]"); - - Proccess(LL_ERR, true); - + } + // Process the message in the buffer + Proccess(LOGL_ERR, true); + // Begin the traceback process ret = m_Buffer.WriteF(0, "Traceback:\n[\n"); - + // Traceback the function call for (Int32 level = 1; SQ_SUCCEEDED(sq_stackinfos(vm, level, &si)); ++level) { ret += m_Buffer.WriteF(ret, "=> [%d] %s (%d) [%s]\n", level @@ -181,20 +406,22 @@ void Logger::Debug(CCStr fmt, va_list args) , si.line , si.funcname ? si.funcname : _SC("unknown")); } - + // End the function call traceback m_Buffer.WriteF(ret, "]"); - Proccess(LL_INF, true); - - CCStr s_ = 0, name = 0; + // Process the message in the buffer + Proccess(LOGL_INF, true); + // Temporary variables to retrieve stack information + CSStr s_ = 0, name = 0; SQInteger i_, seq = 0; SQFloat f_; SQUserPointer p_; - + // Begin the local variables information ret = m_Buffer.WriteF(0, "Locals:\n[\n"); - + // Process each stack level for (Int32 level = 0; level < 10; level++) { seq = 0; + // Display all locals in the current stack level while((name = sq_getlocal(vm, level, seq))) { ++seq; @@ -260,43 +487,10 @@ void Logger::Debug(CCStr fmt, va_list args) sq_pop(vm, 1); } } - + // End the variables information m_Buffer.WriteF(ret, "]"); - Proccess(LL_INF, true); -} - -// ------------------------------------------------------------------------------------------------ -void Logger::Proccess(Uint8 type, bool sub) -{ - if (m_Time) - { - time_t rawtime; - struct tm * timeinfo; - time(&rawtime); - timeinfo = localtime(&rawtime); - strftime(m_TmBuff, 80, "%Y-%m-%d %H:%M:%S", timeinfo); - } - else - m_TmBuff[0] = 0; -#ifdef SQMOD_OS_WINDOWS - HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE); - CONSOLE_SCREEN_BUFFER_INFO csb_state; - GetConsoleScreenBufferInfo(hstdout, &csb_state); - SetConsoleTextAttribute(hstdout, GetLevelColor(type)); - if (m_Time) - printf("%s %s ", GetLevelTag(type), m_TmBuff); - else - printf("%s ", GetLevelTag(type)); - SetConsoleTextAttribute(hstdout, sub ? LC_NORMAL : LC_WHITE); - puts(m_Buffer.Data()); - SetConsoleTextAttribute(hstdout, csb_state.wAttributes); -#else - if (m_Time) - printf("%s %s ", GetLevelTag(type), m_TmBuff); - else - printf("%s ", GetLevelTag(type)); - puts(m_Buffer.Data()); -#endif // SQMOD_OS_WINDOWS + // Process the message in the buffer + Proccess(LOGL_INF, true); } // ------------------------------------------------------------------------------------------------ @@ -305,115 +499,65 @@ void Logger::Proccess(Uint8 type, bool sub) */ { /* */ va_list args; /* */ va_start(args, fmt); /* -*/ if (_Log) /* -*/ _Log->Send(L_, S_, fmt, args); /* -*/ else /* -*/ vprintf(fmt, args); /* +*/ Logger::Get().Send(L_, S_, fmt, args); /* */ va_end(args); /* */ } /* */ // ------------------------------------------------------------------------------------------------ -SQMOD_LOG(LogDbg, LL_DBG, false) -SQMOD_LOG(LogUsr, LL_USR, false) -SQMOD_LOG(LogScs, LL_SCS, false) -SQMOD_LOG(LogInf, LL_INF, false) -SQMOD_LOG(LogWrn, LL_WRN, false) -SQMOD_LOG(LogErr, LL_ERR, false) -SQMOD_LOG(LogFtl, LL_FTL, false) +SQMOD_LOG(LogDbg, LOGL_DBG, false) +SQMOD_LOG(LogUsr, LOGL_USR, false) +SQMOD_LOG(LogScs, LOGL_SCS, false) +SQMOD_LOG(LogInf, LOGL_INF, false) +SQMOD_LOG(LogWrn, LOGL_WRN, false) +SQMOD_LOG(LogErr, LOGL_ERR, false) +SQMOD_LOG(LogFtl, LOGL_FTL, false) // ------------------------------------------------------------------------------------------------ -SQMOD_LOG(LogSDbg, LL_DBG, true) -SQMOD_LOG(LogSUsr, LL_USR, true) -SQMOD_LOG(LogSScs, LL_SCS, true) -SQMOD_LOG(LogSInf, LL_INF, true) -SQMOD_LOG(LogSWrn, LL_WRN, true) -SQMOD_LOG(LogSErr, LL_ERR, true) -SQMOD_LOG(LogSFtl, LL_FTL, true) +SQMOD_LOG(LogSDbg, LOGL_DBG, true) +SQMOD_LOG(LogSUsr, LOGL_USR, true) +SQMOD_LOG(LogSScs, LOGL_SCS, true) +SQMOD_LOG(LogSInf, LOGL_INF, true) +SQMOD_LOG(LogSWrn, LOGL_WRN, true) +SQMOD_LOG(LogSErr, LOGL_ERR, true) +SQMOD_LOG(LogSFtl, LOGL_FTL, true) // ------------------------------------------------------------------------------------------------ #define SQMOD_CLOG(N_, L_, S_) /* */bool N_(bool c, CCStr fmt, ...) /* */ { /* */ if (!c) /* -*/ return c; /* +*/ { /* +*/ return c; /* +*/ } /* */ va_list args; /* */ va_start(args, fmt); /* -*/ if (_Log) /* -*/ _Log->Send(L_, S_, fmt, args); /* -*/ else /* -*/ vprintf(fmt, args); /* +*/ Logger::Get().Send(L_, S_, fmt, args); /* */ va_end(args); /* */ return c; /* */ } /* */ // ------------------------------------------------------------------------------------------------ -SQMOD_CLOG(cLogDbg, LL_DBG, false) -SQMOD_CLOG(cLogUsr, LL_USR, false) -SQMOD_CLOG(cLogScs, LL_SCS, false) -SQMOD_CLOG(cLogInf, LL_INF, false) -SQMOD_CLOG(cLogWrn, LL_WRN, false) -SQMOD_CLOG(cLogErr, LL_ERR, false) -SQMOD_CLOG(cLogFtl, LL_FTL, false) +SQMOD_CLOG(cLogDbg, LOGL_DBG, false) +SQMOD_CLOG(cLogUsr, LOGL_USR, false) +SQMOD_CLOG(cLogScs, LOGL_SCS, false) +SQMOD_CLOG(cLogInf, LOGL_INF, false) +SQMOD_CLOG(cLogWrn, LOGL_WRN, false) +SQMOD_CLOG(cLogErr, LOGL_ERR, false) +SQMOD_CLOG(cLogFtl, LOGL_FTL, false) // ------------------------------------------------------------------------------------------------ -SQMOD_CLOG(cLogSDbg, LL_DBG, true) -SQMOD_CLOG(cLogSUsr, LL_USR, true) -SQMOD_CLOG(cLogSScs, LL_SCS, true) -SQMOD_CLOG(cLogSInf, LL_INF, true) -SQMOD_CLOG(cLogSWrn, LL_WRN, true) -SQMOD_CLOG(cLogSErr, LL_ERR, true) -SQMOD_CLOG(cLogSFtl, LL_FTL, true) +SQMOD_CLOG(cLogSDbg, LOGL_DBG, true) +SQMOD_CLOG(cLogSUsr, LOGL_USR, true) +SQMOD_CLOG(cLogSScs, LOGL_SCS, true) +SQMOD_CLOG(cLogSInf, LOGL_INF, true) +SQMOD_CLOG(cLogSWrn, LOGL_WRN, true) +SQMOD_CLOG(cLogSErr, LOGL_ERR, true) +SQMOD_CLOG(cLogSFtl, LOGL_FTL, true) // -------------------------------------------------------------------------------------------- -void OutputMessageImpl(const char * msg, va_list args) -{ -#if defined(WIN32) || defined(_WIN32) - HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE); - - CONSOLE_SCREEN_BUFFER_INFO csb_before; - GetConsoleScreenBufferInfo( hstdout, &csb_before); - SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN); - printf("[SQMOD] "); - - SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); - vprintf(msg, args); - puts(""); - - SetConsoleTextAttribute(hstdout, csb_before.wAttributes); -#else - printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27); - vprintf(msg, args); - puts(""); -#endif -} - -// -------------------------------------------------------------------------------------------- -void OutputErrorImpl(const char * msg, va_list args) -{ -#if defined(WIN32) || defined(_WIN32) - HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE); - - CONSOLE_SCREEN_BUFFER_INFO csb_before; - GetConsoleScreenBufferInfo( hstdout, &csb_before); - SetConsoleTextAttribute(hstdout, FOREGROUND_RED | FOREGROUND_INTENSITY); - printf("[SQMOD] "); - - SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); - vprintf(msg, args); - puts(""); - - SetConsoleTextAttribute(hstdout, csb_before.wAttributes); -#else - printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27); - vprintf(msg, args); - puts(""); -#endif -} - -// -------------------------------------------------------------------------------------------- -void OutputDebug(const char * msg, ...) +void OutputDebug(CCStr msg, ...) { #ifdef _DEBUG // Initialize the arguments list @@ -429,7 +573,7 @@ void OutputDebug(const char * msg, ...) } // -------------------------------------------------------------------------------------------- -void OutputMessage(const char * msg, ...) +void OutputMessage(CCStr msg, ...) { // Initialize the arguments list va_list args; @@ -441,7 +585,7 @@ void OutputMessage(const char * msg, ...) } // -------------------------------------------------------------------------------------------- -void OutputError(const char * msg, ...) +void OutputError(CCStr msg, ...) { // Initialize the arguments list va_list args; diff --git a/source/Logger.hpp b/source/Logger.hpp index 56fc5e06..18bbfbdc 100644 --- a/source/Logger.hpp +++ b/source/Logger.hpp @@ -2,99 +2,301 @@ #define _LOGGER_HPP_ // ------------------------------------------------------------------------------------------------ -#include "Base/Shared.hpp" +#include "SqBase.hpp" #include "Base/Buffer.hpp" +// ------------------------------------------------------------------------------------------------ +#include +#include + // ------------------------------------------------------------------------------------------------ namespace SqMod { -// ------------------------------------------------------------------------------------------------ +/* ------------------------------------------------------------------------------------------------ + * Supported levels of logging. +*/ enum LogLvl { - LL_NIL = (1 << 0), - LL_DBG = (1 << 1), - LL_USR = (1 << 2), - LL_SCS = (1 << 3), - LL_INF = (1 << 4), - LL_WRN = (1 << 5), - LL_ERR = (1 << 6), - LL_FTL = (1 << 7), - LL_ANY = 0xFF + LOGL_NIL = (1 << 0), + LOGL_DBG = (1 << 1), + LOGL_USR = (1 << 2), + LOGL_SCS = (1 << 3), + LOGL_INF = (1 << 4), + LOGL_WRN = (1 << 5), + LOGL_ERR = (1 << 6), + LOGL_FTL = (1 << 7), + LOGL_ANY = 0xFF }; -// -------------------------------------------------------------------------------------------- -extern SQMOD_MANAGEDPTR_TYPE(Logger) _Log; - -// ------------------------------------------------------------------------------------------------ +/* ------------------------------------------------------------------------------------------------ + * Class responsible for logging output. +*/ class Logger { -protected: +private: // -------------------------------------------------------------------------------------------- + static Logger s_Inst; // Logger instance. + + /* -------------------------------------------------------------------------------------------- + * Default constructor. + */ Logger(); - // -------------------------------------------------------------------------------------------- + /* -------------------------------------------------------------------------------------------- + * Copy constructor. (disabled) + */ Logger(const Logger & o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Move constructor. (disabled) + */ Logger(Logger && o) = delete; - // -------------------------------------------------------------------------------------------- - Logger & operator= (const Logger & o) = delete; - Logger & operator= (Logger && o) = delete; - -public: - - // -------------------------------------------------------------------------------------------- + /* -------------------------------------------------------------------------------------------- + * Destructor. + */ ~Logger(); - // -------------------------------------------------------------------------------------------- - static Logger * Get() - { - if (!_Log) - { - return _Log = SQMOD_MANAGEDPTR_MAKE(Logger, new Logger()); - } + /* -------------------------------------------------------------------------------------------- + * Copy assignment operator. (disabled) + */ + Logger & operator = (const Logger & o) = delete; - return SQMOD_MANAGEDPTR_GET(_Log); - } - - // -------------------------------------------------------------------------------------------- - void ToggleTime(bool enabled) { m_Time = enabled; } - bool HasTime() const { return m_Time; } - - // -------------------------------------------------------------------------------------------- - void SetLevels(Uint8 levels) { m_Levels = levels; } - Uint8 GetLevels() const { return m_Levels; } - - // -------------------------------------------------------------------------------------------- - void EnableLevel(Uint8 level) { m_Levels |= level; } - void DisableLevel(Uint8 level) { if (m_Levels & level) m_Levels ^= level; } - - // -------------------------------------------------------------------------------------------- - void Send(Uint8 type, bool sub, CCStr fmt, va_list args); - - // -------------------------------------------------------------------------------------------- - void Message(Uint8 type, bool sub, CCStr fmt, ...); - - // -------------------------------------------------------------------------------------------- - void Debug(CCStr fmt, ...); - void Debug(CCStr fmt, va_list args); - -protected: - - // -------------------------------------------------------------------------------------------- - void Proccess(Uint8 type, bool sub); + /* -------------------------------------------------------------------------------------------- + * Move assignment operator. (disabled) + */ + Logger & operator = (Logger && o) = delete; private: // -------------------------------------------------------------------------------------------- - Buffer m_Buffer; - SQChar m_TmBuff[80]; + Buffer m_Buffer; // Common buffer where the message is written. // -------------------------------------------------------------------------------------------- - Uint8 m_Levels; - bool m_Time; + Uint8 m_ConsoleLevels; // The levels allowed to be outputted to console. + Uint8 m_LogFileLevels; // The levels allowed to be outputted to log file. + + // -------------------------------------------------------------------------------------------- + bool m_ConsoleTime; // Whether console messages should be timestamped. + bool m_LogFileTime; // Whether log file messages should be timestamped. + + // -------------------------------------------------------------------------------------------- + std::FILE* m_File; // Handle to the file where the logs should be saved. + std::string m_Filename; // The name of the file where the logs are saved. + +protected: + + /* -------------------------------------------------------------------------------------------- + * Process the message in the internal buffer. + */ + void Proccess(Uint8 level, bool sub); + +public: + + /* -------------------------------------------------------------------------------------------- + * Retrieve the logger instance. + */ + static Logger & Get() + { + return s_Inst; + } + + /* -------------------------------------------------------------------------------------------- + * Flush buffered data and close the logging file. + */ + void Close(); + + /* -------------------------------------------------------------------------------------------- + * Initialize the logging utility. + */ + void Initialize(CCStr filename); + + /* -------------------------------------------------------------------------------------------- + * Terminate the logging utility. + */ + void Terminate(); + + /* -------------------------------------------------------------------------------------------- + * Enable or disable console message time stamping. + */ + void ToggleConsoleTime(bool enabled) + { + m_ConsoleTime = enabled; + } + + /* -------------------------------------------------------------------------------------------- + * See whether console message time stamping is enabled. + */ + bool ConsoleHasTime() const + { + return m_ConsoleTime; + } + + /* -------------------------------------------------------------------------------------------- + * Enable or disable log file message time stamping. + */ + void ToggleLogFileTime(bool enabled) + { + m_LogFileTime = enabled; + } + + /* -------------------------------------------------------------------------------------------- + * See whether log file message time stamping is enabled. + */ + bool LogFileHasTime() const + { + return m_LogFileTime; + } + + /* -------------------------------------------------------------------------------------------- + * Set the console level flags. + */ + void SetConsoleLevels(Uint8 levels) + { + m_ConsoleLevels = levels; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the console level flags. + */ + Uint8 GetConsoleLevels() const + { + return m_ConsoleLevels; + } + + /* -------------------------------------------------------------------------------------------- + * Set the log file level flags. + */ + void SetLogFileLevels(Uint8 levels) + { + m_LogFileLevels = levels; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the log file level flags. + */ + Uint8 GetLogFileLevels() const + { + return m_LogFileLevels; + } + + /* -------------------------------------------------------------------------------------------- + * Enable a certain console logging level. + */ + void EnableConsoleLevel(Uint8 level) + { + m_ConsoleLevels |= level; + } + + /* -------------------------------------------------------------------------------------------- + * Disable a certain console logging level. + */ + void DisableConsoleLevel(Uint8 level) + { + if (m_ConsoleLevels & level) + { + m_ConsoleLevels ^= level; + } + } + + /* -------------------------------------------------------------------------------------------- + * Toggle a certain console logging level. + */ + void ToggleConsoleLevel(Uint8 level, bool toggle) + { + if (toggle) + { + EnableConsoleLevel(level); + } + else + { + DisableConsoleLevel(level); + } + } + + /* -------------------------------------------------------------------------------------------- + * Enable a certain log file logging level. + */ + void EnableLogFileLevel(Uint8 level) + { + m_LogFileLevels |= level; + } + + /* -------------------------------------------------------------------------------------------- + * Disable a certain log file logging level. + */ + void DisableLogFileLevel(Uint8 level) + { + m_LogFileLevels |= level; + m_LogFileLevels ^= level; + } + + /* -------------------------------------------------------------------------------------------- + * Toggle a certain log file logging level. + */ + void ToggleLogFileLevel(Uint8 level, bool toggle) + { + if (toggle) + { + EnableLogFileLevel(level); + } + else + { + DisableLogFileLevel(level); + } + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the log file name. + */ + const std::string & GetLogFilename() const + { + return m_Filename; + } + + /* -------------------------------------------------------------------------------------------- + * Modify the log file name. + */ + void SetLogFilename(CCStr filename); + + /* -------------------------------------------------------------------------------------------- + * Send a log message. + */ + void Send(Uint8 level, bool sub, CCStr fmt, va_list args); + + /* -------------------------------------------------------------------------------------------- + * Write a log message. + */ + void Write(Uint8 level, bool sub, CCStr fmt, ...); + + /* -------------------------------------------------------------------------------------------- + * Generate a debug message. + */ + void Debug(CCStr fmt, ...); + + /* -------------------------------------------------------------------------------------------- + * Generate a debug message. + */ + void Debug(CCStr fmt, va_list args); + }; +/* ------------------------------------------------------------------------------------------------ + * Raw console message output. +*/ +void OutputDebug(CCStr msg, ...); + +/* ------------------------------------------------------------------------------------------------ + * Raw console message output. +*/ +void OutputMessage(CCStr msg, ...); + +/* ------------------------------------------------------------------------------------------------ + * Raw console message output. +*/ +void OutputError(CCStr msg, ...); + } // Namespace:: SqMod #endif // _LOGGER_HPP_ diff --git a/source/Main.cpp b/source/Main.cpp index 67ac3793..863eb370 100644 --- a/source/Main.cpp +++ b/source/Main.cpp @@ -1,11 +1,10 @@ -// -------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------ #include "Logger.hpp" #include "Core.hpp" -#include "Command.hpp" #include "SqMod.h" // ------------------------------------------------------------------------------------------------ -#include +#include // ------------------------------------------------------------------------------------------------ namespace SqMod { @@ -18,7 +17,9 @@ static Object g_ReloadPayload; // ------------------------------------------------------------------------------------------------ extern void InitExports(); -// ------------------------------------------------------------------------------------------------ +/* ------------------------------------------------------------------------------------------------ + * Perform a scripts reload at the end of the current event. +*/ void EnableReload(Int32 header, Object & payload) { g_Reload = true; @@ -26,6 +27,9 @@ void EnableReload(Int32 header, Object & payload) g_ReloadPayload = payload; } +/* ------------------------------------------------------------------------------------------------ + * Do not perform a scripts reload at the end of the current event. +*/ void DisableReload() { g_Reload = false; @@ -33,81 +37,907 @@ void DisableReload() g_ReloadPayload.Release(); } -// ------------------------------------------------------------------------------------------------ +/* ------------------------------------------------------------------------------------------------ + * Will the scripts be reloaded at the end of the current event? +*/ bool ReloadEnabled() { return g_Reload; } -// ------------------------------------------------------------------------------------------------ +/* ------------------------------------------------------------------------------------------------ + * Retrieve the payload that will be sent to the reload callback. +*/ +Object & ReloadPayload() +{ + return g_ReloadPayload; +} -} // Namespace:: SqMod +/* ------------------------------------------------------------------------------------------------ + * Helper class to make sure that the reload is disabled and the payload is released. +*/ +struct ReloadGuard +{ + ~ReloadGuard() + { + DisableReload(); + } +}; -// ------------------------------------------------------------------------------------------------ -using namespace SqMod; - -// ------------------------------------------------------------------------------------------------ -void BindCallbacks(); -void UnbindCallbacks(); - -// ------------------------------------------------------------------------------------------------ +/* ------------------------------------------------------------------------------------------------ + * Perform the actual reload. +*/ void DoReload() { - // Disable reloading in case of failure - g_Reload = false; + // Disable reloading at the end of this function + const ReloadGuard rg; // Allow reloading by default - _Core->SetState(1); + Core::Get().SetState(1); // Emit the reload event - _Core->EmitScriptReload(g_ReloadHeader, g_ReloadPayload); - // Release the specified payload, if any - DisableReload(); + Core::Get().EmitScriptReload(g_ReloadHeader, g_ReloadPayload); // Are we allowed to reload? - if (!_Core->GetState()) + if (!Core::Get().GetState()) { return; } // Terminate the current VM and release resources - _Core->Terminate(); + Core::Get().Terminate(); // Attempt to initialize it the central core - if (!_Core->Init()) + if (!Core::Get().Initialize()) { throw std::runtime_error("Unable to initialize plugin central core"); } // Attempt to load resources - else if (!_Core->Load()) + else if (!Core::Get().Execute()) { - throw std::runtime_error("Unable to load plugin central core"); + throw std::runtime_error("Unable to load the plugin resources properly"); } - // Prevent recursive reloading - DisableReload(); } +/* ------------------------------------------------------------------------------------------------ + * Bind all server callbacks. +*/ +void BindCallbacks(); + +/* ------------------------------------------------------------------------------------------------ + * Unbind all server callbacks. +*/ +void UnbindCallbacks(); + +// -------------------------------------------------------------------------------------------- +#define SQMOD_CATCH_EVENT_EXCEPTION(ev) /* +*/ catch (const Sqrat::Exception & e) /* +*/ { /* +*/ LogErr("Squirrel exception caught (" #ev ") event"); /* +*/ LogInf("Message: %s", e.Message().c_str()); /* +*/ } /* +*/ catch (const std::exception & e) /* +*/ { /* +*/ LogErr("Program exception caught (" #ev ") event"); /* +*/ LogInf("Message: %s", e.what()); /* +*/ } /* +*/ catch (...) /* +*/ { /* +*/ LogErr("Unknown exception caught (" #ev ") event"); /* +*/ } /* +*/ + +// -------------------------------------------------------------------------------------------- +#define SQMOD_RELOAD_CHECK(exp) /*if (exp) DoReload();*/ + // ------------------------------------------------------------------------------------------------ -void DestroyComponents() +static uint8_t OnServerInitialise(void) { - // Destroy command component - if (_Cmd) + // Mark the initialization as successful by default + Core::Get().SetState(SQMOD_SUCCESS); + // Attempt to forward the event + try { - SQMOD_MANAGEDPTR_DEL(CmdManager, _Cmd); - _Cmd = SQMOD_MANAGEDPTR_MAKE(CmdManager, nullptr); - } - // Destroy core component - if (_Core) - { - SQMOD_MANAGEDPTR_DEL(Core, _Core); - _Core = SQMOD_MANAGEDPTR_MAKE(Core, nullptr); - } - // Destroy logger component - if (_Log) - { - SQMOD_MANAGEDPTR_DEL(Logger, _Log); - _Log = SQMOD_MANAGEDPTR_MAKE(Logger, nullptr); + // Signal outside plug-ins to do fetch our proxies + _Func->SendPluginCommand(0xDABBAD00, "%d", SQMOD_API_VER); + // Attempt to load the module core + if (Core::Get().Execute()) + { + Core::Get().EmitServerStartup(); + } + else + { + LogFtl("Unable to load the plugin resources properly"); + // Failed to initialize + return SQMOD_FAILURE; + } } + SQMOD_CATCH_EVENT_EXCEPTION(OnServerInitialise) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) + // Return the last known plug-in state + return Core::Get().GetState(); } // ------------------------------------------------------------------------------------------------ +static void OnServerShutdown(void) +{ + // Attempt to forward the event + try + { + // Tell the script that the server is shutting down + Core::Get().EmitServerShutdown(); + // Deallocate and release everything obtained at startup + Core::Get().Terminate(); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnServerShutdown) + // See if a reload was requested (quite useless here but why not) + SQMOD_RELOAD_CHECK(false) + // The server still triggers callbacks and we deallocated everything! + UnbindCallbacks(); +} + +// ------------------------------------------------------------------------------------------------ +static void OnServerFrame(float elapsed_time) +{ + // Attempt to forward the event + try + { + Core::Get().EmitServerFrame(elapsed_time); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnServerFrame) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static uint8_t OnPluginCommand(uint32_t command_identifier, CCStr message) +{ + // Mark the initialization as successful by default + Core::Get().SetState(SQMOD_SUCCESS); + // Attempt to forward the event + try + { + Core::Get().EmitPluginCommand(command_identifier, message); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPluginCommand) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) + // Return the last known plug-in state + return Core::Get().GetState(); +} + +// ------------------------------------------------------------------------------------------------ +static uint8_t OnIncomingConnection(CStr player_name, size_t name_buffer_size, + CCStr user_password, CCStr ip_address) +{ + // Mark the initialization as successful by default + Core::Get().SetState(SQMOD_SUCCESS); + // Attempt to forward the event + try + { + Core::Get().EmitIncomingConnection(player_name, name_buffer_size, user_password, ip_address); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnIncomingConnection) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) + // Return the last known plug-in state + return Core::Get().GetState(); +} + +// ------------------------------------------------------------------------------------------------ +static void OnClientScriptData(int32_t player_id, const uint8_t * data, size_t size) +{ + // Attempt to forward the event + try + { + Core::Get().EmitClientScriptData(player_id, data, size); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnClientScriptData) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnPlayerConnect(int32_t player_id) +{ + // Attempt to forward the event + try + { + Core::Get().ConnectPlayer(player_id, SQMOD_CREATE_AUTOMATIC, NullObject()); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerConnect) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnPlayerDisconnect(int32_t player_id, vcmpDisconnectReason reason) +{ + // Attempt to forward the event + try + { + Core::Get().DisconnectPlayer(player_id, reason, NullObject()); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerDisconnect) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static uint8_t OnPlayerRequestClass(int32_t player_id, int32_t offset) +{ + // Mark the initialization as successful by default + Core::Get().SetState(SQMOD_SUCCESS); + // Attempt to forward the event + try + { + Core::Get().EmitPlayerRequestClass(player_id, offset); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerRequestClass) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) + // Return the last known plug-in state + return Core::Get().GetState(); +} + +// ------------------------------------------------------------------------------------------------ +static uint8_t OnPlayerRequestSpawn(int32_t player_id) +{ + // Mark the initialization as successful by default + Core::Get().SetState(SQMOD_SUCCESS); + // Attempt to forward the event + try + { + Core::Get().EmitPlayerRequestSpawn(player_id); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerRequestSpawn) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) + // Return the last known plug-in state + return Core::Get().GetState(); +} + +// ------------------------------------------------------------------------------------------------ +static void OnPlayerSpawn(int32_t player_id) +{ + // Attempt to forward the event + try + { + Core::Get().EmitPlayerSpawn(player_id); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerSpawn) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnPlayerDeath(int32_t player_id, int32_t killer_id, int32_t reason, vcmpBodyPart body_part) +{ + // Attempt to forward the event + try + { + if (_Func->IsPlayerConnected(killer_id)) + { + const int32_t pt = _Func->GetPlayerTeam(player_id), kt = _Func->GetPlayerTeam(killer_id); + Core::Get().EmitPlayerKilled(player_id, killer_id, reason, body_part, + (pt == kt && pt >= 0 && kt >= 0)); + } + else + { + Core::Get().EmitPlayerWasted(player_id, reason); + } + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerDeath) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnPlayerUpdate(int32_t player_id, vcmpPlayerUpdate update_type) +{ + // Attempt to forward the event + try + { + Core::Get().EmitPlayerUpdate(player_id, update_type); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerUpdate) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static uint8_t OnPlayerRequestEnterVehicle(int32_t player_id, int32_t vehicle_id, int32_t slot_index) +{ + // Mark the initialization as successful by default + Core::Get().SetState(SQMOD_SUCCESS); + // Attempt to forward the event + try + { + Core::Get().EmitPlayerEmbarking(player_id, vehicle_id, slot_index); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerRequestEnterVehicle) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) + // Return the last known plug-in state + return Core::Get().GetState(); +} + +// ------------------------------------------------------------------------------------------------ +static void OnPlayerEnterVehicle(int32_t player_id, int32_t vehicle_id, int32_t slot_index) +{ + // Attempt to forward the event + try + { + Core::Get().EmitPlayerEmbarked(player_id, vehicle_id, slot_index); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerEnterVehicle) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnPlayerExitVehicle(int32_t player_id, int32_t vehicle_id) +{ + // Attempt to forward the event + try + { + Core::Get().EmitPlayerDisembark(player_id, vehicle_id); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerExitVehicle) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnPlayerNameChange(int32_t player_id, CCStr old_name, CCStr new_name) +{ + // Attempt to forward the event + try + { + Core::Get().EmitPlayerRename(player_id, old_name, new_name); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerNameChange) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnPlayerStateChange(int32_t player_id, vcmpPlayerState old_state, vcmpPlayerState new_state) +{ + // Attempt to forward the event + try + { + Core::Get().EmitPlayerState(player_id, old_state, new_state); + // Identify the current state and trigger the listeners specific to that + switch (new_state) + { + case vcmpPlayerStateNone: + Core::Get().EmitStateNone(player_id, old_state); + break; + case vcmpPlayerStateNormal: + Core::Get().EmitStateNormal(player_id, old_state); + break; + case vcmpPlayerStateAim: + Core::Get().EmitStateAim(player_id, old_state); + break; + case vcmpPlayerStateDriver: + Core::Get().EmitStateDriver(player_id, old_state); + break; + case vcmpPlayerStatePassenger: + Core::Get().EmitStatePassenger(player_id, old_state); + break; + case vcmpPlayerStateEnterDriver: + Core::Get().EmitStateEnterDriver(player_id, old_state); + break; + case vcmpPlayerStateEnterPassenger: + Core::Get().EmitStateEnterPassenger(player_id, old_state); + break; + case vcmpPlayerStateExit: + Core::Get().EmitStateExit(player_id, old_state); + break; + case vcmpPlayerStateUnspawned: + Core::Get().EmitStateUnspawned(player_id, old_state); + break; + default: LogErr("Unknown player state change: %d", static_cast< Int32 >(new_state)); + } + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerStateChange) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnPlayerActionChange(int32_t player_id, int32_t old_action, int32_t new_action) +{ + // Attempt to forward the event + try + { + Core::Get().EmitPlayerAction(player_id, old_action, new_action); + // Identify the current action and trigger the listeners specific to that + switch (new_action) + { + case SQMOD_PLAYER_ACTION_NONE: + Core::Get().EmitActionNone(player_id, old_action); + break; + case SQMOD_PLAYER_ACTION_NORMAL: + Core::Get().EmitActionNormal(player_id, old_action); + break; + case SQMOD_PLAYER_ACTION_AIMING: + Core::Get().EmitActionAiming(player_id, old_action); + break; + case SQMOD_PLAYER_ACTION_SHOOTING: + Core::Get().EmitActionShooting(player_id, old_action); + break; + case SQMOD_PLAYER_ACTION_JUMPING: + Core::Get().EmitActionJumping(player_id, old_action); + break; + case SQMOD_PLAYER_ACTION_LYING_ON_GROUND: + Core::Get().EmitActionLieDown(player_id, old_action); + break; + case SQMOD_PLAYER_ACTION_GETTING_UP: + Core::Get().EmitActionGettingUp(player_id, old_action); + break; + case SQMOD_PLAYER_ACTION_JUMPING_FROM_VEHICLE: + Core::Get().EmitActionJumpVehicle(player_id, old_action); + break; + case SQMOD_PLAYER_ACTION_DRIVING: + Core::Get().EmitActionDriving(player_id, old_action); + break; + case SQMOD_PLAYER_ACTION_DYING: + Core::Get().EmitActionDying(player_id, old_action); + break; + case SQMOD_PLAYER_ACTION_WASTED: + Core::Get().EmitActionWasted(player_id, old_action); + break; + case SQMOD_PLAYER_ACTION_ENTERING_VEHICLE: + Core::Get().EmitActionEmbarking(player_id, old_action); + break; + case SQMOD_PLAYER_ACTION_EXITING_VEHICLE: + Core::Get().EmitActionDisembarking(player_id, old_action); + break; + } + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerActionChange) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnPlayerOnFireChange(int32_t player_id, uint8_t is_on_fire) +{ + // Attempt to forward the event + try + { + Core::Get().EmitPlayerBurning(player_id, is_on_fire); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerOnFireChange) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnPlayerCrouchChange(int32_t player_id, uint8_t is_crouching) +{ + // Attempt to forward the event + try + { + Core::Get().EmitPlayerCrouching(player_id, is_crouching); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerCrouchChange) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnPlayerGameKeysChange(int32_t player_id, uint32_t old_keys, uint32_t new_keys) +{ + // Attempt to forward the event + try + { + Core::Get().EmitPlayerGameKeys(player_id, old_keys, new_keys); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerGameKeysChange) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnPlayerBeginTyping(int32_t player_id) +{ + // Attempt to forward the event + try + { + Core::Get().EmitPlayerStartTyping(player_id); + } + SQMOD_CATCH_EVENT_EXCEPTION(PlayerBeginTyping) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnPlayerEndTyping(int32_t player_id) +{ + // Attempt to forward the event + try + { + Core::Get().EmitPlayerStopTyping(player_id); + } + SQMOD_CATCH_EVENT_EXCEPTION(PlayerEndTyping) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnPlayerAwayChange(int32_t player_id, uint8_t is_away) +{ + // Attempt to forward the event + try + { + Core::Get().EmitPlayerAway(player_id, is_away); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerAwayChange) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static uint8_t OnPlayerMessage(int32_t player_id, CCStr message) +{ + // Mark the initialization as successful by default + Core::Get().SetState(SQMOD_SUCCESS); + // Attempt to forward the event + try + { + Core::Get().EmitPlayerMessage(player_id, message); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerMessage) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) + // Return the last known plug-in state + return Core::Get().GetState(); +} + +// ------------------------------------------------------------------------------------------------ +static uint8_t OnPlayerCommand(int32_t player_id, CCStr message) +{ + // Mark the initialization as successful by default + Core::Get().SetState(SQMOD_SUCCESS); + // Attempt to forward the event + try + { + Core::Get().EmitPlayerCommand(player_id, message); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerCommand) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) + // Return the last known plug-in state + return Core::Get().GetState(); +} + +// ------------------------------------------------------------------------------------------------ +static uint8_t OnPlayerPrivateMessage(int32_t player_id, int32_t target_player_id, CCStr message) +{ + // Mark the initialization as successful by default + Core::Get().SetState(SQMOD_SUCCESS); + // Attempt to forward the event + try + { + Core::Get().EmitPlayerPrivateMessage(player_id, target_player_id, message); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerPrivateMessage) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) + // Return the last known plug-in state + return Core::Get().GetState(); +} + +// ------------------------------------------------------------------------------------------------ +static void OnPlayerKeyBindDown(int32_t player_id, int32_t bind_id) +{ + // Attempt to forward the event + try + { + Core::Get().EmitPlayerKeyPress(player_id, bind_id); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerKeyBindDown) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnPlayerKeyBindUp(int32_t player_id, int32_t bind_id) +{ + // Attempt to forward the event + try + { + Core::Get().EmitPlayerKeyRelease(player_id, bind_id); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerKeyBindUp) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnPlayerSpectate(int32_t player_id, int32_t target_player_id) +{ + // Attempt to forward the event + try + { + Core::Get().EmitPlayerSpectate(player_id, target_player_id); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerSpectate) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnPlayerCrashReport(int32_t player_id, CCStr report) +{ + // Attempt to forward the event + try + { + Core::Get().EmitPlayerCrashreport(player_id, report); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerCrashReport) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnVehicleUpdate(int32_t vehicle_id, vcmpVehicleUpdate update_type) +{ + // Attempt to forward the event + try + { + Core::Get().EmitVehicleUpdate(vehicle_id, update_type); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnVehicleUpdate) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnVehicleExplode(int32_t vehicle_id) +{ + // Attempt to forward the event + try + { + Core::Get().EmitVehicleExplode(vehicle_id); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnVehicleExplode) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnVehicleRespawn(int32_t vehicle_id) +{ + // Attempt to forward the event + try + { + Core::Get().EmitVehicleRespawn(vehicle_id); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnVehicleRespawn) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnObjectShot(int32_t object_id, int32_t player_id, int32_t weapon_id) +{ + // Attempt to forward the event + try + { + Core::Get().EmitObjectShot(object_id, player_id, weapon_id); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnObjectShot) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnObjectTouched(int32_t object_id, int32_t player_id) +{ + // Attempt to forward the event + try + { + Core::Get().EmitObjectTouched(object_id, player_id); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnObjectTouched) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static uint8_t OnPickupPickAttempt(int32_t pickup_id, int32_t player_id) +{ + // Mark the initialization as successful by default + Core::Get().SetState(SQMOD_SUCCESS); + // Attempt to forward the event + try + { + Core::Get().EmitPickupClaimed(pickup_id, player_id); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPickupPickAttempt) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) + // Return the last known plug-in state + return Core::Get().GetState(); +} + +// ------------------------------------------------------------------------------------------------ +static void OnPickupPicked(int32_t pickup_id, int32_t player_id) +{ + // Attempt to forward the event + try + { + Core::Get().EmitPickupCollected(pickup_id, player_id); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPickupPicked) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnPickupRespawn(int32_t pickup_id) +{ + // Attempt to forward the event + try + { + Core::Get().EmitPickupRespawn(pickup_id); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnPickupRespawn) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnCheckpointEntered(int32_t checkpoint_id, int32_t player_id) +{ + // Attempt to forward the event + try + { + Core::Get().EmitCheckpointEntered(checkpoint_id, player_id); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnCheckpointEntered) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnCheckpointExited(int32_t checkpoint_id, int32_t player_id) +{ + // Attempt to forward the event + try + { + Core::Get().EmitCheckpointExited(checkpoint_id, player_id); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnCheckpointExited) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnEntityPoolChange(vcmpEntityPool entity_type, int32_t entity_id, uint8_t is_deleted) +{ + // Attempt to forward the event + try + { + Core::Get().EmitEntityPool(entity_type, entity_id, is_deleted); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnEntityPoolChange) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + +// ------------------------------------------------------------------------------------------------ +static void OnServerPerformanceReport(size_t /*entry_count*/, CCStr * /*descriptions*/, uint64_t * /*times*/) +{ + // Ignored for now... +} + +// ------------------------------------------------------------------------------------------------ +void BindCallbacks() +{ + _Clbk->OnServerInitialise = OnServerInitialise; + _Clbk->OnServerShutdown = OnServerShutdown; + _Clbk->OnServerFrame = OnServerFrame; + _Clbk->OnPluginCommand = OnPluginCommand; + _Clbk->OnIncomingConnection = OnIncomingConnection; + _Clbk->OnClientScriptData = OnClientScriptData; + _Clbk->OnPlayerConnect = OnPlayerConnect; + _Clbk->OnPlayerDisconnect = OnPlayerDisconnect; + _Clbk->OnPlayerRequestClass = OnPlayerRequestClass; + _Clbk->OnPlayerRequestSpawn = OnPlayerRequestSpawn; + _Clbk->OnPlayerSpawn = OnPlayerSpawn; + _Clbk->OnPlayerDeath = OnPlayerDeath; + _Clbk->OnPlayerUpdate = OnPlayerUpdate; + _Clbk->OnPlayerRequestEnterVehicle = OnPlayerRequestEnterVehicle; + _Clbk->OnPlayerEnterVehicle = OnPlayerEnterVehicle; + _Clbk->OnPlayerExitVehicle = OnPlayerExitVehicle; + _Clbk->OnPlayerNameChange = OnPlayerNameChange; + _Clbk->OnPlayerStateChange = OnPlayerStateChange; + _Clbk->OnPlayerActionChange = OnPlayerActionChange; + _Clbk->OnPlayerOnFireChange = OnPlayerOnFireChange; + _Clbk->OnPlayerCrouchChange = OnPlayerCrouchChange; + _Clbk->OnPlayerGameKeysChange = OnPlayerGameKeysChange; + _Clbk->OnPlayerBeginTyping = OnPlayerBeginTyping; + _Clbk->OnPlayerEndTyping = OnPlayerEndTyping; + _Clbk->OnPlayerAwayChange = OnPlayerAwayChange; + _Clbk->OnPlayerMessage = OnPlayerMessage; + _Clbk->OnPlayerCommand = OnPlayerCommand; + _Clbk->OnPlayerPrivateMessage = OnPlayerPrivateMessage; + _Clbk->OnPlayerKeyBindDown = OnPlayerKeyBindDown; + _Clbk->OnPlayerKeyBindUp = OnPlayerKeyBindUp; + _Clbk->OnPlayerSpectate = OnPlayerSpectate; + _Clbk->OnPlayerCrashReport = OnPlayerCrashReport; + _Clbk->OnVehicleUpdate = OnVehicleUpdate; + _Clbk->OnVehicleExplode = OnVehicleExplode; + _Clbk->OnVehicleRespawn = OnVehicleRespawn; + _Clbk->OnObjectShot = OnObjectShot; + _Clbk->OnObjectTouched = OnObjectTouched; + _Clbk->OnPickupPickAttempt = OnPickupPickAttempt; + _Clbk->OnPickupPicked = OnPickupPicked; + _Clbk->OnPickupRespawn = OnPickupRespawn; + _Clbk->OnCheckpointEntered = OnCheckpointEntered; + _Clbk->OnCheckpointExited = OnCheckpointExited; + _Clbk->OnEntityPoolChange = OnEntityPoolChange; + _Clbk->OnServerPerformanceReport = OnServerPerformanceReport; +} + +// ------------------------------------------------------------------------------------------------ +void UnbindCallbacks() +{ + _Clbk->OnServerInitialise = nullptr; + _Clbk->OnServerShutdown = nullptr; + _Clbk->OnServerFrame = nullptr; + _Clbk->OnPluginCommand = nullptr; + _Clbk->OnIncomingConnection = nullptr; + _Clbk->OnClientScriptData = nullptr; + _Clbk->OnPlayerConnect = nullptr; + _Clbk->OnPlayerDisconnect = nullptr; + _Clbk->OnPlayerRequestClass = nullptr; + _Clbk->OnPlayerRequestSpawn = nullptr; + _Clbk->OnPlayerSpawn = nullptr; + _Clbk->OnPlayerDeath = nullptr; + _Clbk->OnPlayerUpdate = nullptr; + _Clbk->OnPlayerRequestEnterVehicle = nullptr; + _Clbk->OnPlayerEnterVehicle = nullptr; + _Clbk->OnPlayerExitVehicle = nullptr; + _Clbk->OnPlayerNameChange = nullptr; + _Clbk->OnPlayerStateChange = nullptr; + _Clbk->OnPlayerActionChange = nullptr; + _Clbk->OnPlayerOnFireChange = nullptr; + _Clbk->OnPlayerCrouchChange = nullptr; + _Clbk->OnPlayerGameKeysChange = nullptr; + _Clbk->OnPlayerBeginTyping = nullptr; + _Clbk->OnPlayerEndTyping = nullptr; + _Clbk->OnPlayerAwayChange = nullptr; + _Clbk->OnPlayerMessage = nullptr; + _Clbk->OnPlayerCommand = nullptr; + _Clbk->OnPlayerPrivateMessage = nullptr; + _Clbk->OnPlayerKeyBindDown = nullptr; + _Clbk->OnPlayerKeyBindUp = nullptr; + _Clbk->OnPlayerSpectate = nullptr; + _Clbk->OnPlayerCrashReport = nullptr; + _Clbk->OnVehicleUpdate = nullptr; + _Clbk->OnVehicleExplode = nullptr; + _Clbk->OnVehicleRespawn = nullptr; + _Clbk->OnObjectShot = nullptr; + _Clbk->OnObjectTouched = nullptr; + _Clbk->OnPickupPickAttempt = nullptr; + _Clbk->OnPickupPicked = nullptr; + _Clbk->OnPickupRespawn = nullptr; + _Clbk->OnCheckpointEntered = nullptr; + _Clbk->OnCheckpointExited = nullptr; + _Clbk->OnEntityPoolChange = nullptr; + _Clbk->OnServerPerformanceReport = nullptr; +} + +} // Namespace:: SqMod + +/* ------------------------------------------------------------------------------------------------ + * Plugiun initialization procedure. +*/ SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs * funcs, PluginCallbacks * calls, PluginInfo * info) { + using namespace SqMod; // Output plugin header puts(""); OutputMessage("--------------------------------------------------------------------"); @@ -116,860 +946,33 @@ SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs * funcs, PluginCallback OutputMessage("Legal: %s", SQMOD_COPYRIGHT); OutputMessage("--------------------------------------------------------------------"); puts(""); - - // Verify that core components are working - if (!Logger::Get()) - { - puts("[SQMOD] Unable to start because the logging class could not be instantiated"); - return SQMOD_FAILURE; - } - if (!Core::Get()) - { - DestroyComponents(); - puts("[SQMOD] Unable to start because the central core class could not be instantiated"); - return SQMOD_FAILURE; - } - if (!CmdManager::Get()) - { - DestroyComponents(); - puts("[SQMOD] Unable to start because the command class could not be instantiated"); - return SQMOD_FAILURE; - } // Store server proxies _Func = funcs; _Clbk = calls; _Info = info; - // Assign plugin information - _Info->uPluginVer = SQMOD_VERSION; - strcpy(_Info->szName, SQMOD_HOST_NAME); - // Attempt to initialize the plugin - if (!_Core->Init()) + // Assign plugin version + _Info->pluginVersion = SQMOD_VERSION; + _Info->apiMajorVersion = PLUGIN_API_MAJOR; + _Info->apiMinorVersion = PLUGIN_API_MINOR; + // Assign the plugin name + std::snprintf(_Info->name, sizeof(_Info->name), "%s", SQMOD_HOST_NAME); + // Attempt to initialize the logger before anything else + Logger::Get().Initialize(nullptr); + // Attempt to initialize the plugin core + if (!Core::Get().Initialize()) { - LogFtl("The plugin failed to initialize"); - _Core->Terminate(); - DestroyComponents(); - return SQMOD_FAILURE; - } - else if (_Clbk) - BindCallbacks(); - else - { - _Core->Terminate(); - DestroyComponents(); - LogFtl("Unable to start because the server callbacks are missing"); + LogFtl("Unable to initialize the plug-in central core"); + // Attempt to terminate + Core::Get().Terminate(); + // Stop here! return SQMOD_FAILURE; } + // Bind to server callbacks + BindCallbacks(); // Attempt to initialize the plugin exports InitExports(); - // Notify that the plugin was successfully loaded - OutputMessage("Successfully loaded %s", SQMOD_NAME); // Dummy spacing puts(""); // Initialization was successful return SQMOD_SUCCESS; } - -// -------------------------------------------------------------------------------------------- -#define SQMOD_CATCH_EVENT_EXCEPTION(ev) /* -*/ catch (const Sqrat::Exception & e) /* -*/ { /* -*/ LogErr("Squirrel exception caught during (" #ev ") event"); /* -*/ LogInf("Message: %s", e.Message().c_str()); /* -*/ } /* -*/ catch (const std::exception & e) /* -*/ { /* -*/ LogErr("Program exception caught during (" #ev ") event"); /* -*/ LogInf("Message: %s", e.what()); /* -*/ } /* -*/ catch (...) /* -*/ { /* -*/ LogErr("Unknown exception caught during (" #ev ") event"); /* -*/ } /* -*/ - -// -------------------------------------------------------------------------------------------- -#define SQMOD_RELOAD_CHECK if (g_Reload) DoReload(); - -// -------------------------------------------------------------------------------------------- -static int VC_InitServer(void) -{ - // Don't even try to initialize if there's no core instance - if (!_Core) - { - return SQMOD_FAILURE; - } - // Mark the initialization as successful by default - _Core->SetState(1); - // Attempt to forward the event - try - { - - // Obtain the API version as a string - String apiver(ToStrF("%d", SQMOD_API_VER)); - // Signal outside plug-ins to do fetch our proxies - _Func->SendCustomCommand(0xDABBAD00, apiver.c_str()); - // Attempt to load the module core - if (_Core->Load()) - { - _Core->EmitServerStartup(); - } - else - { - LogFtl("Unable to load the plugin resources properly"); - } - } - SQMOD_CATCH_EVENT_EXCEPTION(InitServer) - // See if a reload was requested - SQMOD_RELOAD_CHECK - // Return the last known plug-in state - return _Core->GetState(); -} - -static void VC_ShutdownServer(void) -{ - // Don't even try to de-initialize if there's no core instance - if (!_Core) - { - return; - } - // Attempt to forward the event - try - { - _Core->EmitServerShutdown(); - // Deallocate and release everything obtained at startup - _Core->Terminate(); - // The server still triggers callbacks and we deallocated everything! - UnbindCallbacks(); - // Destroy components - DestroyComponents(); - } - SQMOD_CATCH_EVENT_EXCEPTION(ShutdownServer) - // See if a reload was requested (quite useless here but why not) - SQMOD_RELOAD_CHECK -} - -static void VC_Frame(float delta) -{ - // Attempt to forward the event - try - { - _Core->EmitServerFrame(delta); - } - SQMOD_CATCH_EVENT_EXCEPTION(Frame) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_PlayerConnect(int player) -{ - // Attempt to forward the event - try - { - _Core->ConnectPlayer(player, SQMOD_CREATE_AUTOMATIC, NullObject()); - } - SQMOD_CATCH_EVENT_EXCEPTION(PlayerConnect) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_PlayerDisconnect(int player, int reason) -{ - // Attempt to forward the event - try - { - _Core->DisconnectPlayer(player, reason, NullObject()); - } - SQMOD_CATCH_EVENT_EXCEPTION(PlayerDisconnect) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_PlayerBeginTyping(int player) -{ - // Attempt to forward the event - try - { - _Core->EmitPlayerStartTyping(player); - } - SQMOD_CATCH_EVENT_EXCEPTION(PlayerBeginTyping) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_PlayerEndTyping(int player) -{ - // Attempt to forward the event - try - { - _Core->EmitPlayerStopTyping(player); - } - SQMOD_CATCH_EVENT_EXCEPTION(PlayerEndTyping) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static int VC_PlayerRequestClass(int player, int offset) -{ - // Mark the initialization as successful by default - _Core->SetState(SQMOD_SUCCESS); - // Attempt to forward the event - try - { - _Core->EmitPlayerRequestClass(player, offset); - } - SQMOD_CATCH_EVENT_EXCEPTION(PlayerEndTyping) - // See if a reload was requested - SQMOD_RELOAD_CHECK - // Return the last known plug-in state - return _Core->GetState(); -} - -static int VC_PlayerRequestSpawn(int player) -{ - // Mark the initialization as successful by default - _Core->SetState(SQMOD_SUCCESS); - // Attempt to forward the event - try - { - _Core->EmitPlayerRequestSpawn(player); - } - SQMOD_CATCH_EVENT_EXCEPTION(PlayerRequestSpawn) - // See if a reload was requested - SQMOD_RELOAD_CHECK - // Return the last known plug-in state - return _Core->GetState(); -} - -static void VC_PlayerSpawn(int player) -{ - // Attempt to forward the event - try - { - _Core->EmitPlayerSpawn(player); - } - SQMOD_CATCH_EVENT_EXCEPTION(PlayerSpawn) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_PlayerDeath(int player, int killer, int reason, int body_part) -{ - // Attempt to forward the event - try - { - if (_Func->IsPlayerConnected(killer)) - { - _Core->EmitPlayerKilled(player, killer, reason, body_part); - } - else - { - _Core->EmitPlayerWasted(player, reason); - } - } - SQMOD_CATCH_EVENT_EXCEPTION(PlayerDeath) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_PlayerUpdate(int player, int type) -{ - // Attempt to forward the event - try - { - _Core->EmitPlayerUpdate(player, type); - } - SQMOD_CATCH_EVENT_EXCEPTION(PlayerUpdate) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static int VC_PlayerRequestEnter(int player, int vehicle, int slot) -{ - // Mark the initialization as successful by default - _Core->SetState(SQMOD_SUCCESS); - // Attempt to forward the event - try - { - _Core->EmitPlayerEmbarking(player, vehicle, slot); - } - SQMOD_CATCH_EVENT_EXCEPTION(PlayerRequestEnter) - // See if a reload was requested - SQMOD_RELOAD_CHECK - // Return the last known plug-in state - return _Core->GetState(); -} - -static void VC_PlayerEnterVehicle(int player, int vehicle, int slot) -{ - // Attempt to forward the event - try - { - _Core->EmitPlayerEmbarked(player, vehicle, slot); - } - SQMOD_CATCH_EVENT_EXCEPTION(PlayerEnterVehicle) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_PlayerExitVehicle(int player, int vehicle) -{ - // Attempt to forward the event - try - { - _Core->EmitPlayerDisembark(player, vehicle); - } - SQMOD_CATCH_EVENT_EXCEPTION(PlayerExitVehicle) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static int VC_PickupClaimPicked(int pickup, int player) -{ - // Mark the initialization as successful by default - _Core->SetState(SQMOD_SUCCESS); - // Attempt to forward the event - try - { - _Core->EmitPickupClaimed(player, pickup); - } - SQMOD_CATCH_EVENT_EXCEPTION(PickupClaimPicked) - // See if a reload was requested - SQMOD_RELOAD_CHECK - // Return the last known plug-in state - return _Core->GetState(); -} - -static void VC_PickupPickedUp(int pickup, int player) -{ - // Attempt to forward the event - try - { - _Core->EmitPickupCollected(player, pickup); - } - SQMOD_CATCH_EVENT_EXCEPTION(PickupPickedUp) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_PickupRespawn(int pickup) -{ - // Attempt to forward the event - try - { - _Core->EmitPickupRespawn(pickup); - } - SQMOD_CATCH_EVENT_EXCEPTION(PickupRespawn) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_VehicleUpdate(int vehicle, int type) -{ - // Attempt to forward the event - try - { - _Core->EmitVehicleUpdate(vehicle, type); - } - SQMOD_CATCH_EVENT_EXCEPTION(VehicleUpdate) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_VehicleExplode(int vehicle) -{ - // Attempt to forward the event - try - { - _Core->EmitVehicleExplode(vehicle); - } - SQMOD_CATCH_EVENT_EXCEPTION(VehicleExplode) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_VehicleRespawn(int vehicle) -{ - // Attempt to forward the event - try - { - _Core->EmitVehicleRespawn(vehicle); - } - SQMOD_CATCH_EVENT_EXCEPTION(VehicleRespawn) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_ObjectShot(int object, int player, int weapon) -{ - // Attempt to forward the event - try - { - _Core->EmitObjectShot(player, object, weapon); - } - SQMOD_CATCH_EVENT_EXCEPTION(ObjectShot) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_ObjectBump(int object, int player) -{ - // Attempt to forward the event - try - { - _Core->EmitObjectBump(player, object); - } - SQMOD_CATCH_EVENT_EXCEPTION(ObjectBump) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static int VC_PublicMessage(int player, const char * text) -{ - // Mark the initialization as successful by default - _Core->SetState(SQMOD_SUCCESS); - // Attempt to forward the event - try - { - _Core->EmitPlayerChat(player, text); - } - SQMOD_CATCH_EVENT_EXCEPTION(PublicMessage) - // See if a reload was requested - SQMOD_RELOAD_CHECK - // Return the last known plug-in state - return _Core->GetState(); -} - -static int VC_CommandMessage(int player, const char * text) -{ - // Mark the initialization as successful by default - _Core->SetState(SQMOD_SUCCESS); - // Attempt to forward the event - try - { - _Core->EmitPlayerCommand(player, text); - } - SQMOD_CATCH_EVENT_EXCEPTION(CommandMessage) - // See if a reload was requested - SQMOD_RELOAD_CHECK - // Return the last known plug-in state - return _Core->GetState(); -} - -static int VC_PrivateMessage(int player, int target, const char * text) -{ - // Mark the initialization as successful by default - _Core->SetState(SQMOD_SUCCESS); - // Attempt to forward the event - try - { - _Core->EmitPlayerMessage(player, target, text); - } - SQMOD_CATCH_EVENT_EXCEPTION(PrivateMessage) - // See if a reload was requested - SQMOD_RELOAD_CHECK - // Return the last known plug-in state - return _Core->GetState(); -} - -static int VC_InternalCommand(unsigned int type, const char * text) -{ - // Mark the initialization as successful by default - _Core->SetState(SQMOD_SUCCESS); - // Attempt to forward the event - try - { - _Core->EmitInternalCommand(type, text); - } - SQMOD_CATCH_EVENT_EXCEPTION(InternalCommand) - // See if a reload was requested - SQMOD_RELOAD_CHECK - // Return the last known plug-in state - return _Core->GetState(); -} - -static int VC_LoginAttempt(char * name, const char * passwd, const char * address) -{ - // Mark the initialization as successful by default - _Core->SetState(SQMOD_SUCCESS); - // Attempt to forward the event - try - { - _Core->EmitLoginAttempt(name, passwd, address); - } - SQMOD_CATCH_EVENT_EXCEPTION(LoginAttempt) - // See if a reload was requested - SQMOD_RELOAD_CHECK - // Return the last known plug-in state - return _Core->GetState(); -} - -static void VC_EntityPool(int type, int id, unsigned int deleted) -{ - // Attempt to forward the event - try - { - _Core->EmitEntityPool(type, id, static_cast< bool >(deleted)); - } - SQMOD_CATCH_EVENT_EXCEPTION(EntityPool) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_KeyBindDown(int player, int bind) -{ - // Attempt to forward the event - try - { - _Core->EmitPlayerKeyPress(player, bind); - } - SQMOD_CATCH_EVENT_EXCEPTION(KeyBindDown) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_KeyBindUp(int player, int bind) -{ - // Attempt to forward the event - try - { - _Core->EmitPlayerKeyRelease(player, bind); - } - SQMOD_CATCH_EVENT_EXCEPTION(KeyBindUp) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_PlayerAway(int player, unsigned int status) -{ - // Attempt to forward the event - try - { - _Core->EmitPlayerAway(player, static_cast< bool >(status)); - } - SQMOD_CATCH_EVENT_EXCEPTION(PlayerAway) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_PlayerSpectate(int player, int target) -{ - // Attempt to forward the event - try - { - _Core->EmitPlayerSpectate(player, target); - } - SQMOD_CATCH_EVENT_EXCEPTION(PlayerSpectate) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_PlayerCrashReport(int player, const char * report) -{ - // Attempt to forward the event - try - { - _Core->EmitPlayerCrashreport(player, report); - } - SQMOD_CATCH_EVENT_EXCEPTION(PlayerCrashReport) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_ServerPerformanceReport(int /*count*/, const char ** /*description*/, unsigned long long * /*millis*/) -{ - // Ignored for now... -} - -static void VC_PlayerName(int player, const char * previous, const char * current) -{ - // Attempt to forward the event - try - { - _Core->EmitPlayerRename(player, previous, current); - } - SQMOD_CATCH_EVENT_EXCEPTION(PlayerName) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_PlayerState(int player, int previous, int current) -{ - // Attempt to forward the event - try - { - _Core->EmitPlayerState(player, previous, current); - // Identify the current state and trigger the listeners specific to that - switch (current) - { - case SQMOD_PLAYER_STATE_NONE: - _Core->EmitStateNone(player, previous); - break; - case SQMOD_PLAYER_STATE_NORMAL: - _Core->EmitStateNormal(player, previous); - break; - case SQMOD_PLAYER_STATE_SHOOTING: - _Core->EmitStateShooting(player, previous); - break; - case SQMOD_PLAYER_STATE_DRIVER: - _Core->EmitStateDriver(player, previous); - break; - case SQMOD_PLAYER_STATE_PASSENGER: - _Core->EmitStatePassenger(player, previous); - break; - case SQMOD_PLAYER_STATE_ENTERING_AS_DRIVER: - _Core->EmitStateEnterDriver(player, previous); - break; - case SQMOD_PLAYER_STATE_ENTERING_AS_PASSENGER: - _Core->EmitStateEnterPassenger(player, previous); - break; - case SQMOD_PLAYER_STATE_EXITING_VEHICLE: - _Core->EmitStateExitVehicle(player, previous); - break; - case SQMOD_PLAYER_STATE_UNSPAWNED: - _Core->EmitStateUnspawned(player, previous); - break; - } - } - SQMOD_CATCH_EVENT_EXCEPTION(PlayerState) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_PlayerAction(int player, int previous, int current) -{ - // Attempt to forward the event - try - { - _Core->EmitPlayerAction(player, previous, current); - // Identify the current action and trigger the listeners specific to that - switch (current) - { - case SQMOD_PLAYER_ACTION_NONE: - _Core->EmitActionNone(player, previous); - break; - case SQMOD_PLAYER_ACTION_NORMAL: - _Core->EmitActionNormal(player, previous); - break; - case SQMOD_PLAYER_ACTION_AIMING: - _Core->EmitActionAiming(player, previous); - break; - case SQMOD_PLAYER_ACTION_SHOOTING: - _Core->EmitActionShooting(player, previous); - break; - case SQMOD_PLAYER_ACTION_JUMPING: - _Core->EmitActionJumping(player, previous); - break; - case SQMOD_PLAYER_ACTION_LYING_ON_GROUND: - _Core->EmitActionLieDown(player, previous); - break; - case SQMOD_PLAYER_ACTION_GETTING_UP: - _Core->EmitActionGettingUp(player, previous); - break; - case SQMOD_PLAYER_ACTION_JUMPING_FROM_VEHICLE: - _Core->EmitActionJumpVehicle(player, previous); - break; - case SQMOD_PLAYER_ACTION_DRIVING: - _Core->EmitActionDriving(player, previous); - break; - case SQMOD_PLAYER_ACTION_DYING: - _Core->EmitActionDying(player, previous); - break; - case SQMOD_PLAYER_ACTION_WASTED: - _Core->EmitActionWasted(player, previous); - break; - case SQMOD_PLAYER_ACTION_ENTERING_VEHICLE: - _Core->EmitActionEmbarking(player, previous); - break; - case SQMOD_PLAYER_ACTION_EXITING_VEHICLE: - _Core->EmitActionDisembarking(player, previous); - break; - } - } - SQMOD_CATCH_EVENT_EXCEPTION(PlayerAction) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_PlayerOnFire(int player, unsigned int state) -{ - // Attempt to forward the event - try - { - _Core->EmitPlayerBurning(player, static_cast< bool >(state)); - } - SQMOD_CATCH_EVENT_EXCEPTION(PlayerOnFire) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_PlayerCrouch(int player, unsigned int state) -{ - // Attempt to forward the event - try - { - _Core->EmitPlayerCrouching(player, static_cast< bool >(state)); - } - SQMOD_CATCH_EVENT_EXCEPTION(PlayerCrouch) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_PlayerGameKeys(int player, int previous, int current) -{ - // Attempt to forward the event - try - { - _Core->EmitPlayerGameKeys(player, previous, current); - } - SQMOD_CATCH_EVENT_EXCEPTION(PlayerGameKeys) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_OnCheckpointEntered(int checkpoint, int player) -{ - // Attempt to forward the event - try - { - _Core->EmitCheckpointEntered(player, checkpoint); - } - SQMOD_CATCH_EVENT_EXCEPTION(CheckpointEntered) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_OnCheckpointExited(int checkpoint, int player) -{ - // Attempt to forward the event - try - { - _Core->EmitCheckpointExited(player, checkpoint); - } - SQMOD_CATCH_EVENT_EXCEPTION(CheckpointExited) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_OnSphereEntered(int sphere, int player) -{ - // Attempt to forward the event - try - { - _Core->EmitForcefieldEntered(player, sphere); - } - SQMOD_CATCH_EVENT_EXCEPTION(SphereEntered) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -static void VC_OnSphereExited(int sphere, int player) -{ - // Attempt to forward the event - try - { - _Core->EmitForcefieldExited(player, sphere); - } - SQMOD_CATCH_EVENT_EXCEPTION(SphereExited) - // See if a reload was requested - SQMOD_RELOAD_CHECK -} - -// ------------------------------------------------------------------------------------------------ -void BindCallbacks() -{ - _Clbk->OnInitServer = VC_InitServer; - _Clbk->OnShutdownServer = VC_ShutdownServer; - _Clbk->OnFrame = VC_Frame; - _Clbk->OnPlayerConnect = VC_PlayerConnect; - _Clbk->OnPlayerDisconnect = VC_PlayerDisconnect; - _Clbk->OnPlayerBeginTyping = VC_PlayerBeginTyping; - _Clbk->OnPlayerEndTyping = VC_PlayerEndTyping; - _Clbk->OnPlayerRequestClass = VC_PlayerRequestClass; - _Clbk->OnPlayerRequestSpawn = VC_PlayerRequestSpawn; - _Clbk->OnPlayerSpawn = VC_PlayerSpawn; - _Clbk->OnPlayerDeath = VC_PlayerDeath; - _Clbk->OnPlayerUpdate = VC_PlayerUpdate; - _Clbk->OnPlayerRequestEnter = VC_PlayerRequestEnter; - _Clbk->OnPlayerEnterVehicle = VC_PlayerEnterVehicle; - _Clbk->OnPlayerExitVehicle = VC_PlayerExitVehicle; - _Clbk->OnPickupClaimPicked = VC_PickupClaimPicked; - _Clbk->OnPickupPickedUp = VC_PickupPickedUp; - _Clbk->OnPickupRespawn = VC_PickupRespawn; - _Clbk->OnVehicleUpdate = VC_VehicleUpdate; - _Clbk->OnVehicleExplode = VC_VehicleExplode; - _Clbk->OnVehicleRespawn = VC_VehicleRespawn; - _Clbk->OnObjectShot = VC_ObjectShot; - _Clbk->OnObjectBump = VC_ObjectBump; - _Clbk->OnPublicMessage = VC_PublicMessage; - _Clbk->OnCommandMessage = VC_CommandMessage; - _Clbk->OnPrivateMessage = VC_PrivateMessage; - _Clbk->OnInternalCommand = VC_InternalCommand; - _Clbk->OnLoginAttempt = VC_LoginAttempt; - _Clbk->OnEntityPoolChange = VC_EntityPool; - _Clbk->OnKeyBindDown = VC_KeyBindDown; - _Clbk->OnKeyBindUp = VC_KeyBindUp; - _Clbk->OnPlayerAwayChange = VC_PlayerAway; - _Clbk->OnPlayerSpectate = VC_PlayerSpectate; - _Clbk->OnPlayerCrashReport = VC_PlayerCrashReport; - _Clbk->OnServerPerformanceReport = VC_ServerPerformanceReport; - _Clbk->OnPlayerNameChange = VC_PlayerName; - _Clbk->OnPlayerStateChange = VC_PlayerState; - _Clbk->OnPlayerActionChange = VC_PlayerAction; - _Clbk->OnPlayerOnFireChange = VC_PlayerOnFire; - _Clbk->OnPlayerCrouchChange = VC_PlayerCrouch; - _Clbk->OnPlayerGameKeysChange = VC_PlayerGameKeys; - _Clbk->OnCheckpointEntered = VC_OnCheckpointEntered; - _Clbk->OnCheckpointExited = VC_OnCheckpointExited; - _Clbk->OnSphereEntered = VC_OnSphereEntered; - _Clbk->OnSphereExited = VC_OnSphereExited; -} - -// ------------------------------------------------------------------------------------------------ -void UnbindCallbacks() -{ - _Clbk->OnInitServer = nullptr; - _Clbk->OnShutdownServer = nullptr; - _Clbk->OnFrame = nullptr; - _Clbk->OnPlayerConnect = nullptr; - _Clbk->OnPlayerDisconnect = nullptr; - _Clbk->OnPlayerBeginTyping = nullptr; - _Clbk->OnPlayerEndTyping = nullptr; - _Clbk->OnPlayerRequestClass = nullptr; - _Clbk->OnPlayerRequestSpawn = nullptr; - _Clbk->OnPlayerSpawn = nullptr; - _Clbk->OnPlayerDeath = nullptr; - _Clbk->OnPlayerUpdate = nullptr; - _Clbk->OnPlayerRequestEnter = nullptr; - _Clbk->OnPlayerEnterVehicle = nullptr; - _Clbk->OnPlayerExitVehicle = nullptr; - _Clbk->OnPickupClaimPicked = nullptr; - _Clbk->OnPickupPickedUp = nullptr; - _Clbk->OnPickupRespawn = nullptr; - _Clbk->OnVehicleUpdate = nullptr; - _Clbk->OnVehicleExplode = nullptr; - _Clbk->OnVehicleRespawn = nullptr; - _Clbk->OnObjectShot = nullptr; - _Clbk->OnObjectBump = nullptr; - _Clbk->OnPublicMessage = nullptr; - _Clbk->OnCommandMessage = nullptr; - _Clbk->OnPrivateMessage = nullptr; - _Clbk->OnInternalCommand = nullptr; - _Clbk->OnLoginAttempt = nullptr; - _Clbk->OnEntityPoolChange = nullptr; - _Clbk->OnKeyBindDown = nullptr; - _Clbk->OnKeyBindUp = nullptr; - _Clbk->OnPlayerAwayChange = nullptr; - _Clbk->OnPlayerSpectate = nullptr; - _Clbk->OnPlayerCrashReport = nullptr; - _Clbk->OnServerPerformanceReport = nullptr; - _Clbk->OnPlayerNameChange = nullptr; - _Clbk->OnPlayerStateChange = nullptr; - _Clbk->OnPlayerActionChange = nullptr; - _Clbk->OnPlayerOnFireChange = nullptr; - _Clbk->OnPlayerCrouchChange = nullptr; - _Clbk->OnPlayerGameKeysChange = nullptr; - _Clbk->OnCheckpointEntered = nullptr; - _Clbk->OnCheckpointExited = nullptr; - _Clbk->OnSphereEntered = nullptr; - _Clbk->OnSphereExited = nullptr; -} diff --git a/source/Misc.cpp b/source/Misc.cpp index ca3399ed..011b628e 100644 --- a/source/Misc.cpp +++ b/source/Misc.cpp @@ -1,6 +1,7 @@ // ------------------------------------------------------------------------------------------------ #include "Core.hpp" #include "Logger.hpp" +#include "Base/Stack.hpp" // ------------------------------------------------------------------------------------------------ #include @@ -14,94 +15,76 @@ extern void DisableReload(); extern bool ReloadEnabled(); // ------------------------------------------------------------------------------------------------ -static Object & GetBlip(Int32 id) { return _Core->GetBlip(id).mObj; } -static Object & GetCheckpoint(Int32 id) { return _Core->GetCheckpoint(id).mObj; } -static Object & GetForcefield(Int32 id) { return _Core->GetForcefield(id).mObj; } -static Object & GetKeybind(Int32 id) { return _Core->GetKeybind(id).mObj; } -static Object & GetObject(Int32 id) { return _Core->GetObject(id).mObj; } -static Object & GetPickup(Int32 id) { return _Core->GetPickup(id).mObj; } -static Object & GetPlayer(Int32 id) { return _Core->GetPlayer(id).mObj; } -static Object & GetSprite(Int32 id) { return _Core->GetSprite(id).mObj; } -static Object & GetTextdraw(Int32 id) { return _Core->GetTextdraw(id).mObj; } -static Object & GetVehicle(Int32 id) { return _Core->GetVehicle(id).mObj; } +static Object & GetBlip(Int32 id) { return Core::Get().GetBlip(id).mObj; } +static Object & GetCheckpoint(Int32 id) { return Core::Get().GetCheckpoint(id).mObj; } +static Object & GetKeybind(Int32 id) { return Core::Get().GetKeybind(id).mObj; } +static Object & GetObject(Int32 id) { return Core::Get().GetObject(id).mObj; } +static Object & GetPickup(Int32 id) { return Core::Get().GetPickup(id).mObj; } +static Object & GetPlayer(Int32 id) { return Core::Get().GetPlayer(id).mObj; } +static Object & GetVehicle(Int32 id) { return Core::Get().GetVehicle(id).mObj; } // ------------------------------------------------------------------------------------------------ static bool DelBlip(Int32 id, Int32 header, Object & payload) { - return _Core->DelBlip(id, header, payload); + return Core::Get().DelBlip(id, header, payload); } static bool DelCheckpoint(Int32 id, Int32 header, Object & payload) { - return _Core->DelCheckpoint(id, header, payload); -} - -static bool DelForcefield(Int32 id, Int32 header, Object & payload) -{ - return _Core->DelForcefield(id, header, payload); + return Core::Get().DelCheckpoint(id, header, payload); } static bool DelKeybind(Int32 id, Int32 header, Object & payload) { - return _Core->DelKeybind(id, header, payload); + return Core::Get().DelKeybind(id, header, payload); } static bool DelObject(Int32 id, Int32 header, Object & payload) { - return _Core->DelObject(id, header, payload); + return Core::Get().DelObject(id, header, payload); } static bool DelPickup(Int32 id, Int32 header, Object & payload) { - return _Core->DelPickup(id, header, payload); -} - -static bool DelSprite(Int32 id, Int32 header, Object & payload) -{ - return _Core->DelSprite(id, header, payload); -} - -static bool DelTextdraw(Int32 id, Int32 header, Object & payload) -{ - return _Core->DelTextdraw(id, header, payload); + return Core::Get().DelPickup(id, header, payload); } static bool DelVehicle(Int32 id, Int32 header, Object & payload) { - return _Core->DelVehicle(id, header, payload); + return Core::Get().DelVehicle(id, header, payload); } // ------------------------------------------------------------------------------------------------ static void BindEvent(Int32 id, Object & env, Function & func) { - _Core->BindEvent(id, env, func); + Core::Get().BindEvent(id, env, func); } // ------------------------------------------------------------------------------------------------ static Int32 GetState() { - return _Core->GetState(); + return Core::Get().GetState(); } static void SetState(Int32 value) { - return _Core->SetState(value); + return Core::Get().SetState(value); } // ------------------------------------------------------------------------------------------------ static CSStr GetOption(CSStr name) { - return _Core->GetOption(name); + return Core::Get().GetOption(name); } static CSStr GetOptionOr(CSStr name, CSStr value) { - return _Core->GetOption(name, value); + return Core::Get().GetOption(name, value); } static void SetOption(CSStr name, CSStr value) { - return _Core->SetOption(name, value); + return Core::Get().SetOption(name, value); } // ------------------------------------------------------------------------------------------------ @@ -145,22 +128,16 @@ void Register_Core(HSQUIRRELVM vm) .Func(_SC("SetOption"), &SetOption) .Func(_SC("GetBlip"), &GetBlip) .Func(_SC("GetCheckpoint"), &GetCheckpoint) - .Func(_SC("GetForcefield"), &GetForcefield) .Func(_SC("GetKeybind"), &GetKeybind) .Func(_SC("GetObject"), &GetObject) .Func(_SC("GetPickup"), &GetPickup) .Func(_SC("GetPlayer"), &GetPlayer) - .Func(_SC("GetSprite"), &GetSprite) - .Func(_SC("GetTextdraw"), &GetTextdraw) .Func(_SC("GetVehicle"), &GetVehicle) .Func(_SC("DestroyBlip"), &DelBlip) .Func(_SC("DestroyCheckpoint"), &DelCheckpoint) - .Func(_SC("DestroyForcefield"), &DelForcefield) .Func(_SC("DestroyKeybind"), &DelKeybind) .Func(_SC("DestroyObject"), &DelObject) .Func(_SC("DestroyPickup"), &DelPickup) - .Func(_SC("DestroySprite"), &DelSprite) - .Func(_SC("DestroyTextdraw"), &DelTextdraw) .Func(_SC("DestroyVehicle"), &DelVehicle) ); } @@ -174,35 +151,17 @@ template < Uint8 L, bool S > static SQInteger LogBasicMessage(HSQUIRRELVM vm) { return sq_throwerror(vm, "Missing message value"); } - // Do we have enough values to call the format function? - else if (top > 2) + // Attempt to generate the string value + StackStrF val(vm, 2); + // Have we failed to retrieve the string? + if (SQ_FAILED(val.mRes)) { - SStr msg = NULL; - SQInteger len = 0; - // Attempt to generate the specified string format - SQRESULT ret = sqstd_format(vm, 2, &len, &msg); - // Did the format failed? - if (SQ_FAILED(ret)) - { - return ret; // Propagate the exception - } - // Log the resulted string value - _Log->Message(L, S, "%s", msg); - } - else - { - // Attempt to retrieve the value from the stack as a string - Var< CSStr > msg(vm, 2); - // See if the obtained value is a valid string - if (!msg.value) - { - return sq_throwerror(vm, "Unable to retrieve the value"); - } - // Log the resulted string value - _Log->Message(L, S, "%s", msg.value); + return val.mRes; // Propagate the error! } + // Forward the resulted string value to the logger + Logger::Get().Write(L, S, "%s", val.mPtr); // This function does not return a value - return 1; + return 0; } // ================================================================================================ @@ -210,20 +169,20 @@ void Register_Log(HSQUIRRELVM vm) { RootTable(vm) .Bind(_SC("SqLog"), Table(vm) - .SquirrelFunc(_SC("Dbg"), &LogBasicMessage< LL_DBG, false >) - .SquirrelFunc(_SC("Usr"), &LogBasicMessage< LL_USR, false >) - .SquirrelFunc(_SC("Scs"), &LogBasicMessage< LL_SCS, false >) - .SquirrelFunc(_SC("Inf"), &LogBasicMessage< LL_INF, false >) - .SquirrelFunc(_SC("Wrn"), &LogBasicMessage< LL_WRN, false >) - .SquirrelFunc(_SC("Err"), &LogBasicMessage< LL_ERR, false >) - .SquirrelFunc(_SC("Ftl"), &LogBasicMessage< LL_FTL, false >) - .SquirrelFunc(_SC("SDbg"), &LogBasicMessage< LL_DBG, true >) - .SquirrelFunc(_SC("SUsr"), &LogBasicMessage< LL_USR, true >) - .SquirrelFunc(_SC("SScs"), &LogBasicMessage< LL_SCS, true >) - .SquirrelFunc(_SC("SInf"), &LogBasicMessage< LL_INF, true >) - .SquirrelFunc(_SC("SWrn"), &LogBasicMessage< LL_WRN, true >) - .SquirrelFunc(_SC("SErr"), &LogBasicMessage< LL_ERR, true >) - .SquirrelFunc(_SC("SFtl"), &LogBasicMessage< LL_FTL, true >) + .SquirrelFunc(_SC("Dbg"), &LogBasicMessage< LOGL_DBG, false >) + .SquirrelFunc(_SC("Usr"), &LogBasicMessage< LOGL_USR, false >) + .SquirrelFunc(_SC("Scs"), &LogBasicMessage< LOGL_SCS, false >) + .SquirrelFunc(_SC("Inf"), &LogBasicMessage< LOGL_INF, false >) + .SquirrelFunc(_SC("Wrn"), &LogBasicMessage< LOGL_WRN, false >) + .SquirrelFunc(_SC("Err"), &LogBasicMessage< LOGL_ERR, false >) + .SquirrelFunc(_SC("Ftl"), &LogBasicMessage< LOGL_FTL, false >) + .SquirrelFunc(_SC("SDbg"), &LogBasicMessage< LOGL_DBG, true >) + .SquirrelFunc(_SC("SUsr"), &LogBasicMessage< LOGL_USR, true >) + .SquirrelFunc(_SC("SScs"), &LogBasicMessage< LOGL_SCS, true >) + .SquirrelFunc(_SC("SInf"), &LogBasicMessage< LOGL_INF, true >) + .SquirrelFunc(_SC("SWrn"), &LogBasicMessage< LOGL_WRN, true >) + .SquirrelFunc(_SC("SErr"), &LogBasicMessage< LOGL_ERR, true >) + .SquirrelFunc(_SC("SFtl"), &LogBasicMessage< LOGL_FTL, true >) ); } diff --git a/source/Misc/Functions.cpp b/source/Misc/Functions.cpp index c133ed3f..98dd2e57 100644 --- a/source/Misc/Functions.cpp +++ b/source/Misc/Functions.cpp @@ -1,17 +1,21 @@ // ------------------------------------------------------------------------------------------------ #include "Misc/Functions.hpp" +#include "Base/Shared.hpp" +#include "Base/Stack.hpp" +#include "Base/Color3.hpp" +#include "Base/Vector2.hpp" #include "Base/Vector3.hpp" -#include "Library/Numeric.hpp" - -// ------------------------------------------------------------------------------------------------ -#include -#include +#include "Entity/Player.hpp" +#include "Core.hpp" // ------------------------------------------------------------------------------------------------ namespace SqMod { // ------------------------------------------------------------------------------------------------ -static ServerSettings g_SvSettings; +static ServerSettings g_SvSettings; +static PluginInfo g_PluginInfo; + +// ------------------------------------------------------------------------------------------------ static SQChar g_SvNameBuff[SQMOD_SVNAMELENGTH] = {0}; static SQChar g_PasswdBuff[SQMOD_PASSWDLENGTH] = {0}; static SQChar g_GmNameBuff[SQMOD_GMNAMELENGTH] = {0}; @@ -72,65 +76,166 @@ static String CS_Keycode_Names[] = {"", /* index 0 is not used */ }; // ------------------------------------------------------------------------------------------------ -CCStr GetKeyCodeName(Uint8 keycode) -{ return CS_Keycode_Names[keycode].c_str(); } -void SetKeyCodeName(Uint8 keycode, CCStr name) -{ CS_Keycode_Names[keycode].assign(name); } +CSStr GetKeyCodeName(Uint8 keycode) +{ + return CS_Keycode_Names[keycode].c_str(); +} // ------------------------------------------------------------------------------------------------ -Uint32 GetPluginVersion() -{ return SQMOD_VERSION; } -CCStr GetPluginVersionStr() -{ return SQMOD_VERSION_STR; } -CCStr GetPluginName() -{ return SQMOD_NAME; } -CCStr GetPluginAuthor() -{ return SQMOD_AUTHOR; } -Int32 GetPluginID() -{ return _Info->nPluginId; } -Uint32 GetNumberOfPlugins() -{ return _Func->GetNumberOfPlugins(); } -Int32 FindPlugin(CCStr name) -{ return _Func->FindPlugin(const_cast< CStr >(name)); } +void SetKeyCodeName(Uint8 keycode, CSStr name) +{ + CS_Keycode_Names[keycode].assign(name); +} // ------------------------------------------------------------------------------------------------ Uint32 GetServerVersion() -{ return _Func->GetServerVersion(); } +{ + return _Func->GetServerVersion(); +} + +// ------------------------------------------------------------------------------------------------ +Table GetServerSettings() +{ + // Update the server settings structure + _Func->GetServerSettings(&g_SvSettings); + // Allocate a script table + Table tbl; + // Add the structure members to the script table + tbl.SetValue(_SC("Name"), g_SvSettings.serverName); + tbl.SetValue(_SC("MaxPlayers"), g_SvSettings.maxPlayers); + tbl.SetValue(_SC("Port"), g_SvSettings.port); + tbl.SetValue(_SC("Flags"), g_SvSettings.flags); + // Return the resulted table + return tbl; +} + +// ------------------------------------------------------------------------------------------------ +Uint32 GetNumberOfPlugins() +{ + return _Func->GetNumberOfPlugins(); +} + +// ------------------------------------------------------------------------------------------------ +Table GetPluginInfo(Int32 plugin_id) +{ + // Attempt to update the plug-in info structure + if (_Func->GetPluginInfo(plugin_id, &g_PluginInfo) == vcmpErrorNoSuchEntity) + { + STHROWF("Unknown plug-in identifier: %d", plugin_id); + } + // Allocate a script table + Table tbl; + // Add the structure members to the script table + tbl.SetValue(_SC("Id"), g_PluginInfo.pluginId); + tbl.SetValue(_SC("Name"), g_PluginInfo.name); + tbl.SetValue(_SC("Version"), g_PluginInfo.pluginVersion); + tbl.SetValue(_SC("MajorAPI"), g_PluginInfo.apiMajorVersion); + tbl.SetValue(_SC("MinorAPI"), g_PluginInfo.apiMinorVersion); + // Return the resulted table + return tbl; +} + +// ------------------------------------------------------------------------------------------------ +Int32 FindPlugin(CSStr name) +{ + return _Func->FindPlugin(name); +} + +// ------------------------------------------------------------------------------------------------ +void SendPluginCommand(Uint32 identifier, CSStr payload) +{ + _Func->SendPluginCommand(identifier, payload); +} + +// ------------------------------------------------------------------------------------------------ +const ULongInt & GetTime() +{ + return GetULongInt(_Func->GetTime()); +} + +// ------------------------------------------------------------------------------------------------ +SQInteger SendLogMessage(HSQUIRRELVM vm) +{ + const Int32 top = sq_gettop(vm); + // Was the message value specified? + if (top <= 1) + { + return sq_throwerror(vm, "Missing message value"); + } + // Attempt to generate the string value + StackStrF val(vm, 2); + // Have we failed to retrieve the string? + if (SQ_FAILED(val.mRes)) + { + return val.mRes; // Propagate the error! + } + // Forward the resulted string value + else if (_Func->LogMessage("%s", val.mPtr) == vcmpErrorTooLargeInput) + { + STHROWF("Input is too big"); + } + // This function does not return a value + return 0; +} + +// ------------------------------------------------------------------------------------------------ +Int32 GetLastError() +{ + return _Func->GetLastError(); +} + +// ------------------------------------------------------------------------------------------------ +Uint32 GetPluginVersion() +{ + return SQMOD_VERSION; +} + +// ------------------------------------------------------------------------------------------------ +CSStr GetPluginVersionStr() +{ + return SQMOD_VERSION_STR; +} + +// ------------------------------------------------------------------------------------------------ +CSStr GetPluginName() +{ + return SQMOD_NAME; +} + +// ------------------------------------------------------------------------------------------------ +CSStr GetPluginAuthor() +{ + return SQMOD_AUTHOR; +} + +// ------------------------------------------------------------------------------------------------ +Int32 GetPluginID() +{ + return _Info->pluginId; +} // ------------------------------------------------------------------------------------------------ Uint32 GetServerPort() { + // Update the server settings structure _Func->GetServerSettings(&g_SvSettings); - return g_SvSettings.uPort; + // Return the requested information + return g_SvSettings.port; } +// ------------------------------------------------------------------------------------------------ Uint32 GetServerFlags() { + // Update the server settings structure _Func->GetServerSettings(&g_SvSettings); - return g_SvSettings.uFlags; + // Return the requested information + return g_SvSettings.flags; } // ------------------------------------------------------------------------------------------------ -void SetServerName(CCStr name) -{ _Func->SetServerName(name); } -CCStr GetServerName() +Int32 GetMaxPlayers(void) { - _Func->GetServerName(g_SvNameBuff, SQMOD_SVNAMELENGTH); - return g_SvNameBuff; -} - -// ------------------------------------------------------------------------------------------------ -ULongInt GetTime() -{ - std::uint64_t time = 0; - _Func->GetTime(&time); - return ULongInt(time); -} - -// ------------------------------------------------------------------------------------------------ -void SendCustomCommand(Uint32 type, CCStr cmd) -{ - _Func->SendCustomCommand(type, cmd); + return _Func->GetMaxPlayers(); } // ------------------------------------------------------------------------------------------------ @@ -139,39 +244,534 @@ void SetMaxPlayers(Int32 max) _Func->SetMaxPlayers(max); } -Int32 GetMaxPlayers(void) +// ------------------------------------------------------------------------------------------------ +CSStr GetServerName() { - return _Func->GetMaxPlayers(); + // Populate the buffer + if (_Func->GetServerName(g_SvNameBuff, SQMOD_SVNAMELENGTH) == vcmpErrorBufferTooSmall) + { + STHROWF("Server name was too big for the available buffer: %u", sizeof(g_SvNameBuff)); + } + // Return the result + return g_SvNameBuff; } // ------------------------------------------------------------------------------------------------ -void SetServerPassword(CCStr passwd) -{ _Func->SetServerPassword(const_cast< CStr >(passwd)); } -CCStr GetServerPassword() +void SetServerName(CSStr name) { - _Func->GetServerPassword(g_PasswdBuff, SQMOD_PASSWDLENGTH); + _Func->SetServerName(name); +} + +// ------------------------------------------------------------------------------------------------ +CSStr GetServerPassword() +{ + // Populate the buffer + if (_Func->GetServerPassword(g_PasswdBuff, SQMOD_PASSWDLENGTH) == vcmpErrorBufferTooSmall) + { + STHROWF("Server password was too big for the available buffer: %u", sizeof(g_PasswdBuff)); + } + // Return the result return g_PasswdBuff; } // ------------------------------------------------------------------------------------------------ -void SetGameModeText(CCStr text) -{ _Func->SetGameModeText(text); } -CCStr GetGameModeText() +void SetServerPassword(CSStr passwd) { - _Func->GetGameModeText(g_GmNameBuff, SQMOD_GMNAMELENGTH); + _Func->SetServerPassword(passwd); +} + +// ------------------------------------------------------------------------------------------------ +CSStr GetGameModeText() +{ + // Populate the buffer + if (_Func->GetGameModeText(g_GmNameBuff, SQMOD_GMNAMELENGTH) == vcmpErrorBufferTooSmall) + { + STHROWF("Game-mode text was too big for the available buffer: %u", sizeof(g_GmNameBuff)); + } + // Return the result return g_GmNameBuff; } // ------------------------------------------------------------------------------------------------ -Int32 PlaySound(Int32 world, Int32 sound, const Vector3 & pos) -{ return _Func->PlaySound(world, sound, pos.x, pos.y, pos.z); } -Int32 PlaySoundEx(Int32 world, Int32 sound, Float32 x, Float32 y, Float32 z) -{ return _Func->PlaySound(world, sound, x, y, z); } +void SetGameModeText(CSStr text) +{ + _Func->SetGameModeText(text); +} // ------------------------------------------------------------------------------------------------ -Int32 AddRadioStream(Int32 id, CCStr name, CCStr url, bool listed) -{ return _Func->AddRadioStream(id, name, url, listed); } -Int32 RemoveRadioStream(Int32 id) -{ return _Func->RemoveRadioStream(id); } +void CreateRadioStream(CSStr name, CSStr url, bool listed) +{ + if (_Func->AddRadioStream(-1, name, url, listed) == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Invalid radio stream identifier"); + } +} + +// ------------------------------------------------------------------------------------------------ +void CreateRadioStreamEx(Int32 id, CSStr name, CSStr url, bool listed) +{ + if (_Func->AddRadioStream(id, name, url, listed) == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Invalid radio stream identifier"); + } +} + +// ------------------------------------------------------------------------------------------------ +void RemoveRadioStream(Int32 id) +{ + if (_Func->RemoveRadioStream(id) == vcmpErrorNoSuchEntity) + { + STHROWF("No such radio stream exists"); + } +} + +// ------------------------------------------------------------------------------------------------ +void ShutdownServer() +{ + _Func->ShutdownServer(); +} + +// ------------------------------------------------------------------------------------------------ +bool GetServerOption(Int32 option_id) +{ + // Attempt to obtain the current value of the specified option + const bool value = _Func->GetServerOption(static_cast< vcmpServerOption >(option_id)); + // Check for errors + if (_Func->GetLastError() == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Unknown option identifier: %d", option_id); + } + // Return the obtained value + return value; +} + +// ------------------------------------------------------------------------------------------------ +void SetServerOption(Int32 option_id, bool toggle) +{ + if (_Func->SetServerOption(static_cast< vcmpServerOption >(option_id), + toggle) == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Unknown option identifier: %d", option_id); + } + else + { + Core::Get().EmitServerOption(option_id, toggle, 0, NullObject()); + } +} + +// ------------------------------------------------------------------------------------------------ +void SetServerOptionEx(Int32 option_id, bool toggle, Int32 header, Object & payload) +{ + if (_Func->SetServerOption(static_cast< vcmpServerOption >(option_id), + toggle) == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Unknown option identifier: %d", option_id); + } + else + { + Core::Get().EmitServerOption(option_id, toggle, header, payload); + } +} + +// ------------------------------------------------------------------------------------------------ +Table GetWorldBounds() +{ + Vector2 max, min; + // Retrieve the current world bounds + _Func->GetWorldBounds(&max.x, &min.x, &max.y, &min.y); + // Allocate a script table + Table tbl; + // Populate the table with the obtained values + tbl.SetValue(_SC("max"), max); + tbl.SetValue(_SC("min"), min); + // Return the result + return tbl; +} + +// ------------------------------------------------------------------------------------------------ +void SetWorldBounds(const Vector2 & max, const Vector2 & min) +{ + _Func->SetWorldBounds(max.x, min.x, max.y, min.y); +} + +// ------------------------------------------------------------------------------------------------ +void SetWorldBoundsEx(Float32 max_x, Float32 max_y, Float32 min_x, Float32 min_y) +{ + _Func->SetWorldBounds(max_x, min_x, max_y, min_y); +} + +Table GetWastedSettings() +{ + Uint32 fc, dt, ft, cfs, cft; + Float32 fis, fos; + Color3 c; + // Retrieve the current wasted settings bounds + _Func->GetWastedSettings(&dt, &ft, &fis, &fos, &fc, &cfs, &cft); + // Convert the packed color + c.SetRGB(fc); + // Allocate a script table + Table tbl; + // Populate the table with the obtained values + tbl.SetValue(_SC("DeathTimerOut"), dt); + tbl.SetValue(_SC("FadeTimer"), ft); + tbl.SetValue(_SC("FadeInSpeed"), fis); + tbl.SetValue(_SC("FadeOutSpeed"), fos); + tbl.SetValue(_SC("FadeColour"), c); + tbl.SetValue(_SC("CorpseFadeStart"), cfs); + tbl.SetValue(_SC("CorpseFadeTime"), cft); + // Return the result + return tbl; +} + +// ------------------------------------------------------------------------------------------------ +void SetWastedSettings(Uint32 dt, Uint32 ft, Float32 fis, Float32 fos, + const Color3 & fc, Uint32 cfs, Uint32 cft) +{ + _Func->SetWastedSettings(dt, ft, fis, fos, fc.GetRGB(), cfs, cft); +} + +// ------------------------------------------------------------------------------------------------ +Uint32 GetTimeRate(void) +{ + return _Func->GetTimeRate(); +} + +// ------------------------------------------------------------------------------------------------ +void SetTimeRate(Uint32 rate) +{ + _Func->SetTimeRate(rate); +} + +// ------------------------------------------------------------------------------------------------ +Int32 GetHour(void) +{ + return _Func->GetHour(); +} + +// ------------------------------------------------------------------------------------------------ +void SetHour(Int32 hour) +{ + _Func->SetHour(hour); +} + +// ------------------------------------------------------------------------------------------------ +Int32 GetMinute(void) +{ + return _Func->GetMinute(); +} + +// ------------------------------------------------------------------------------------------------ +void SetMinute(Int32 minute) +{ + _Func->SetMinute(minute); +} + +// ------------------------------------------------------------------------------------------------ +Int32 GetWeather(void) +{ + return _Func->GetWeather(); +} + +// ------------------------------------------------------------------------------------------------ +void SetWeather(Int32 weather) +{ + _Func->SetWeather(weather); +} + +// ------------------------------------------------------------------------------------------------ +Float32 GetGravity(void) +{ + return _Func->GetGravity(); +} + +// ------------------------------------------------------------------------------------------------ +void SetGravity(Float32 gravity) +{ + _Func->SetGravity(gravity); +} + +// ------------------------------------------------------------------------------------------------ +Float32 GetGameSpeed(void) +{ + return _Func->GetGameSpeed(); +} + +// ------------------------------------------------------------------------------------------------ +void SetGameSpeed(Float32 speed) +{ + _Func->SetGameSpeed(speed); +} + +// ------------------------------------------------------------------------------------------------ +Float32 GetWaterLevel(void) +{ + return _Func->GetWaterLevel(); +} + +// ------------------------------------------------------------------------------------------------ +void SetWaterLevel(Float32 level) +{ + _Func->SetWaterLevel(level); +} + +// ------------------------------------------------------------------------------------------------ +Float32 GetMaximumFlightAltitude(void) +{ + return _Func->GetMaximumFlightAltitude(); +} + +// ------------------------------------------------------------------------------------------------ +void SetMaximumFlightAltitude(Float32 height) +{ + _Func->SetMaximumFlightAltitude(height); +} + +// ------------------------------------------------------------------------------------------------ +Int32 GetKillCommandDelay(void) +{ + return _Func->GetKillCommandDelay(); +} + +// ------------------------------------------------------------------------------------------------ +void SetKillCommandDelay(Int32 delay) +{ + _Func->SetKillCommandDelay(delay); +} + +// ------------------------------------------------------------------------------------------------ +Float32 GetVehiclesForcedRespawnHeight(void) +{ + return _Func->GetVehiclesForcedRespawnHeight(); +} + +// ------------------------------------------------------------------------------------------------ +void SetVehiclesForcedRespawnHeight(Float32 height) +{ + _Func->SetVehiclesForcedRespawnHeight(height); +} + +// ------------------------------------------------------------------------------------------------ +void CreateExplosion(Int32 world, Int32 type, const Vector3 & pos, CPlayer & source, bool grounded) +{ + // Validate the specified player + source.Validate(); + // Perform the requested operation + if (_Func->CreateExplosion(world, type, pos.x, pos.y, pos.z, + source.GetID(), grounded) == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Argument value out of bounds"); + } +} + +// ------------------------------------------------------------------------------------------------ +void CreateExplosionEx(Int32 world, Int32 type, Float32 x, Float32 y, Float32 z, CPlayer & source, bool grounded) +{ + // Validate the specified player + source.Validate(); + // Perform the requested operation + if (_Func->CreateExplosion(world, type, x, y, z, + source.GetID(), grounded) == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Argument value out of bounds"); + } +} + +// ------------------------------------------------------------------------------------------------ +void PlaySound(Int32 world, Int32 sound, const Vector3 & pos) +{ + if (_Func->PlaySound(world, sound, pos.x, pos.y, pos.z) == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Argument value out of bounds"); + } +} + +// ------------------------------------------------------------------------------------------------ +void PlaySoundEx(Int32 world, Int32 sound, Float32 x, Float32 y, Float32 z) +{ + if (_Func->PlaySound(world, sound, x, y, z) == vcmpErrorArgumentOutOfBounds) + { + STHROWF("Argument value out of bounds"); + } +} + +// ------------------------------------------------------------------------------------------------ +void HideMapObject(Int32 model, const Vector3 & pos) +{ + _Func->HideMapObject(model, + static_cast< Int16 >(std::floor(pos.x * 10.0f) + 0.5f), + static_cast< Int16 >(std::floor(pos.y * 10.0f) + 0.5f), + static_cast< Int16 >(std::floor(pos.z * 10.0f) + 0.5f) + ); +} + +// ------------------------------------------------------------------------------------------------ +void HideMapObjectEx(Int32 model, Float32 x, Float32 y, Float32 z) +{ + _Func->HideMapObject(model, + static_cast< Int16 >(std::floor(x * 10.0f) + 0.5f), + static_cast< Int16 >(std::floor(y * 10.0f) + 0.5f), + static_cast< Int16 >(std::floor(z * 10.0f) + 0.5f) + ); +} + +// ------------------------------------------------------------------------------------------------ +void HideMapObjectRaw(Int32 model, Int16 x, Int16 y, Int16 z) +{ + _Func->HideMapObject(model, x, y, z); +} + +// ------------------------------------------------------------------------------------------------ +void ShowMapObject(Int32 model, const Vector3 & pos) +{ + _Func->ShowMapObject(model, + static_cast< Int16 >(std::floor(pos.x * 10.0f) + 0.5f), + static_cast< Int16 >(std::floor(pos.y * 10.0f) + 0.5f), + static_cast< Int16 >(std::floor(pos.z * 10.0f) + 0.5f) + ); +} + +// ------------------------------------------------------------------------------------------------ +void ShowMapObjectEx(Int32 model, Float32 x, Float32 y, Float32 z) +{ + _Func->ShowMapObject(model, + static_cast< Int16 >(std::floor(x * 10.0f) + 0.5f), + static_cast< Int16 >(std::floor(y * 10.0f) + 0.5f), + static_cast< Int16 >(std::floor(z * 10.0f) + 0.5f) + ); +} + +// ------------------------------------------------------------------------------------------------ +void ShowMapObjectRaw(Int32 model, Int16 x, Int16 y, Int16 z) +{ + _Func->ShowMapObject(model, x, y, z); +} + +// ------------------------------------------------------------------------------------------------ +void ShowAllMapObjects(void) +{ + _Func->ShowAllMapObjects(); +} + +// ------------------------------------------------------------------------------------------------ +SQFloat GetWeaponDataValue(Int32 weapon, Int32 field) +{ + return ConvTo< SQFloat >::From(_Func->GetWeaponDataValue(weapon, field)); +} + +// ------------------------------------------------------------------------------------------------ +bool SetWeaponDataValue(Int32 weapon, Int32 field, SQFloat value) +{ + return (_Func->SetWeaponDataValue(weapon, field, value) != vcmpErrorArgumentOutOfBounds); +} + +// ------------------------------------------------------------------------------------------------ +bool ResetWeaponDataValue(Int32 weapon, Int32 field) +{ + return (_Func->ResetWeaponDataValue(weapon, field) != vcmpErrorArgumentOutOfBounds); +} + +// ------------------------------------------------------------------------------------------------ +bool IsWeaponDataValueModified(Int32 weapon, Int32 field) +{ + return _Func->IsWeaponDataValueModified(weapon, field); +} + +// ------------------------------------------------------------------------------------------------ +bool ResetWeaponData(Int32 weapon) +{ + return (_Func->ResetWeaponData(weapon) != vcmpErrorArgumentOutOfBounds); +} + +// ------------------------------------------------------------------------------------------------ +void ResetAllWeaponData() +{ + _Func->ResetAllWeaponData(); +} + +// ------------------------------------------------------------------------------------------------ +Int32 AddPlayerClass(Int32 team, const Color3 & color, Int32 skin, const Vector3 & pos, Float32 angle, + Int32 wep1, Int32 ammo1, Int32 wep2, Int32 ammo2, Int32 wep3, Int32 ammo3) +{ + return _Func->AddPlayerClass(team, color.GetRGB(), skin, pos.x, pos.y, pos.z, angle, + wep1, ammo1, wep2, ammo2, wep3, ammo3); +} + +// ------------------------------------------------------------------------------------------------ +void SetSpawnPlayerPosition(const Vector3 & pos) +{ + _Func->SetSpawnPlayerPosition(pos.x, pos.y, pos.z); +} + +// ------------------------------------------------------------------------------------------------ +void SetSpawnCameraPosition(const Vector3 & pos) +{ + _Func->SetSpawnCameraPosition(pos.x, pos.y, pos.z); +} + +// ------------------------------------------------------------------------------------------------ +void SetSpawnCameraLookAt(const Vector3 & pos) +{ + _Func->SetSpawnCameraLookAt(pos.x, pos.y, pos.z); +} + +// ------------------------------------------------------------------------------------------------ +void SetSpawnPlayerPositionEx(Float32 x, Float32 y, Float32 z) +{ + _Func->SetSpawnPlayerPosition(x, y, z); +} + +// ------------------------------------------------------------------------------------------------ +void SetSpawnCameraPositionEx(Float32 x, Float32 y, Float32 z) +{ + _Func->SetSpawnCameraPosition(x, y, z); +} + +// ------------------------------------------------------------------------------------------------ +void SetSpawnCameraLookAtEx(Float32 x, Float32 y, Float32 z) +{ + _Func->SetSpawnPlayerPosition(x, y, z); +} + +// ------------------------------------------------------------------------------------------------ +void BanIP(CSStr addr) +{ + _Func->BanIP(const_cast< SStr >(addr)); +} + +// ------------------------------------------------------------------------------------------------ +bool UnbanIP(CSStr addr) +{ + return _Func->UnbanIP(const_cast< SStr >(addr)); +} + +// ------------------------------------------------------------------------------------------------ +bool IsIPBanned(CSStr addr) +{ + return _Func->IsIPBanned(const_cast< SStr >(addr)); +} + +// ------------------------------------------------------------------------------------------------ +Int32 GetPlayerIdFromName(CSStr name) +{ + return _Func->GetPlayerIdFromName(name); +} + +// ------------------------------------------------------------------------------------------------ +bool IsPlayerConnected(Int32 player_id) +{ + return _Func->IsPlayerConnected(player_id); +} + +// ------------------------------------------------------------------------------------------------ +void ForceAllSelect() +{ + _Func->ForceAllSelect(); +} + +// ------------------------------------------------------------------------------------------------ +bool CheckEntityExists(Int32 type, Int32 index) +{ + return _Func->CheckEntityExists(static_cast< vcmpEntityPool >(type), index); +} } // Namespace:: SqMod diff --git a/source/Misc/Functions.hpp b/source/Misc/Functions.hpp index a6f59e03..c63b9200 100644 --- a/source/Misc/Functions.hpp +++ b/source/Misc/Functions.hpp @@ -7,55 +7,452 @@ // ------------------------------------------------------------------------------------------------ namespace SqMod { -// ------------------------------------------------------------------------------------------------ -CCStr GetKeyCodeName(Uint8 keycode); -void SetKeyCodeName(Uint8 keycode, CCStr name); +/* ------------------------------------------------------------------------------------------------ + * Retrieve the name of a certain key-code. +*/ +CSStr GetKeyCodeName(Uint8 keycode); -// ------------------------------------------------------------------------------------------------ -Uint32 GetPluginVersion(); -CCStr GetPluginVersionStr(); -CCStr GetPluginName(); -CCStr GetPluginAuthor(); -Int32 GetPluginID(); -Uint32 GetNumberOfPlugins(); -Int32 FindPlugin(CCStr name); +/* ------------------------------------------------------------------------------------------------ + * Modify the name of a certain key-code. +*/ +void SetKeyCodeName(Uint8 keycode, CSStr name); -// ------------------------------------------------------------------------------------------------ +/* ------------------------------------------------------------------------------------------------ + * Retrieve the server version. +*/ Uint32 GetServerVersion(); -// ------------------------------------------------------------------------------------------------ +/* ------------------------------------------------------------------------------------------------ + * Retrieve the server settings. +*/ +Table GetServerSettings(); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the number of loaded plug-ins. +*/ +Uint32 GetNumberOfPlugins(); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve information about a certain plug-in. +*/ +Table GetPluginInfo(Int32 plugin_id); + +/* ------------------------------------------------------------------------------------------------ + * Attempt to find a plug-in identifier by it's name. +*/ +Int32 FindPlugin(CSStr name); + +/* ------------------------------------------------------------------------------------------------ + * Send a custom command to the loaded plug-ins. +*/ +void SendPluginCommand(Uint32 identifier, CSStr payload); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the server time. +*/ +const ULongInt & GetTime(); + +/* ------------------------------------------------------------------------------------------------ + * Send a log message to the server. +*/ +SQInteger SendLogMessage(HSQUIRRELVM vm); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the last error that occurred on the server. +*/ +Int32 GetLastError(); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the version of the host Squirrel plug-in as an integer. +*/ +Uint32 GetPluginVersion(); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the version of the host Squirrel plug-in as a string. +*/ +CSStr GetPluginVersionStr(); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the name of the host Squirrel plug-in. +*/ +CSStr GetPluginName(); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the author of the host Squirrel plug-in. +*/ +CSStr GetPluginAuthor(); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the id of the host Squirrel plug-in. +*/ +Int32 GetPluginID(); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the port onto which the server was binded. +*/ Uint32 GetServerPort(); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the server flags. +*/ Uint32 GetServerFlags(); -// ------------------------------------------------------------------------------------------------ -void SetServerName(CCStr name); -CCStr GetServerName(); - -// ------------------------------------------------------------------------------------------------ -ULongInt GetTime(); - -// ------------------------------------------------------------------------------------------------ -void SendCustomCommand(Uint32 type, CCStr cmd); - -// ------------------------------------------------------------------------------------------------ -void SetMaxPlayers(Int32 max); +/* ------------------------------------------------------------------------------------------------ + * Retrieve the maximum number of clients allowed on the server. +*/ Int32 GetMaxPlayers(void); -// ------------------------------------------------------------------------------------------------ -void SetServerPassword(CCStr passwd); -CCStr GetServerPassword(); +/* ------------------------------------------------------------------------------------------------ + * Modify the maximum number of clients allowed on the server. +*/ +void SetMaxPlayers(Int32 max); -// ------------------------------------------------------------------------------------------------ -void SetGameModeText(CCStr text); -CCStr GetGameModeText(); +/* ------------------------------------------------------------------------------------------------ + * Retrieve the server name. +*/ +CSStr GetServerName(); -// ------------------------------------------------------------------------------------------------ -Int32 PlaySound(Int32 world, Int32 sound, const Vector3 & pos); -Int32 PlaySoundEx(Int32 world, Int32 sound, Float32 x, Float32 y, Float32 z); +/* ------------------------------------------------------------------------------------------------ + * Modify the server name. +*/ +void SetServerName(CSStr name); -// ------------------------------------------------------------------------------------------------ -Int32 AddRadioStream(Int32 id, CCStr name, CCStr url, bool listed); -Int32 RemoveRadioStream(Int32 id); +/* ------------------------------------------------------------------------------------------------ + * Retrieve the server password. +*/ +CSStr GetServerPassword(); + +/* ------------------------------------------------------------------------------------------------ + * Modify the server password. +*/ +void SetServerPassword(CSStr passwd); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the game-mode text. +*/ +CSStr GetGameModeText(); + +/* ------------------------------------------------------------------------------------------------ + * Modify the game-mode text. +*/ +void SetGameModeText(CSStr text); + +/* ------------------------------------------------------------------------------------------------ + * Create a radio stream. +*/ +void CreateRadioStream(CSStr name, CSStr url, bool listed); + +/* ------------------------------------------------------------------------------------------------ + * Create a radio stream. +*/ +void CreateRadioStreamEx(Int32 id, CSStr name, CSStr url, bool listed); + +/* ------------------------------------------------------------------------------------------------ + * Remove a radio stream. +*/ +void RemoveRadioStream(Int32 id); + +/* ------------------------------------------------------------------------------------------------ + * Shutdown the server. +*/ +void ShutdownServer(); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve a server option. +*/ +bool GetServerOption(Int32 option_id); + +/* ------------------------------------------------------------------------------------------------ + * Modify a server option. +*/ +void SetServerOption(Int32 option_id, bool toggle); + +/* ------------------------------------------------------------------------------------------------ + * Modify a server option. +*/ +void SetServerOptionEx(Int32 option_id, bool toggle, Int32 header, Object & payload); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the world bounds. +*/ +Table GetWorldBounds(); + +/* ------------------------------------------------------------------------------------------------ + * Modify the world bounds. +*/ +void SetWorldBounds(const Vector2 & max, const Vector2 & min); + +/* ------------------------------------------------------------------------------------------------ + * Modify the world bounds. +*/ +void SetWorldBoundsEx(Float32 max_x, Float32 max_y, Float32 min_x, Float32 min_y); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the wasted settings. +*/ +Table GetWastedSettings(); + +/* ------------------------------------------------------------------------------------------------ + * Modify the wasted settings. +*/ +void SetWastedSettings(Uint32 dt, Uint32 ft, Float32 fis, Float32 fos, + const Color3 & fc, Uint32 cfs, Uint32 cft); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the current time-rate. +*/ +Uint32 GetTimeRate(void); + +/* ------------------------------------------------------------------------------------------------ + * Modify the current time-rate. +*/ +void SetTimeRate(Uint32 rate); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the game hour. +*/ +Int32 GetHour(void); + +/* ------------------------------------------------------------------------------------------------ + * Modify the game hour. +*/ +void SetHour(Int32 hour); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the game minute. +*/ +Int32 GetMinute(void); + +/* ------------------------------------------------------------------------------------------------ + * Modify the game minute. +*/ +void SetMinute(Int32 minute); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the weather effects. +*/ +Int32 GetWeather(void); + +/* ------------------------------------------------------------------------------------------------ + * Modify the weather effects. +*/ +void SetWeather(Int32 weather); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the game gravity. +*/ +Float32 GetGravity(void); + +/* ------------------------------------------------------------------------------------------------ + * Modify the game gravity. +*/ +void SetGravity(Float32 gravity); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the game speed. +*/ +Float32 GetGameSpeed(void); + +/* ------------------------------------------------------------------------------------------------ + * Modify the game speed. +*/ +void SetGameSpeed(Float32 speed); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the water level. +*/ +Float32 GetWaterLevel(void); + +/* ------------------------------------------------------------------------------------------------ + * Modify the water level. +*/ +void SetWaterLevel(Float32 level); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the maximum flight altitude. +*/ +Float32 GetMaximumFlightAltitude(void); + +/* ------------------------------------------------------------------------------------------------ + * Modify the maximum flight altitude. +*/ +void SetMaximumFlightAltitude(Float32 height); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the kill command delay. +*/ +Int32 GetKillCommandDelay(void); + +/* ------------------------------------------------------------------------------------------------ + * Modify the kill command delay. +*/ +void SetKillCommandDelay(Int32 delay); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the vehicles forced respawn height. +*/ +Float32 GetVehiclesForcedRespawnHeight(void); + +/* ------------------------------------------------------------------------------------------------ + * Modify the vehicles forced respawn height. +*/ +void SetVehiclesForcedRespawnHeight(Float32 height); + +/* ------------------------------------------------------------------------------------------------ + * Create a game explosion. +*/ +void CreateExplosion(Int32 world, Int32 type, const Vector3 & pos, CPlayer & source, bool grounded); + +/* ------------------------------------------------------------------------------------------------ + * Create a game explosion. +*/ +void CreateExplosionEx(Int32 world, Int32 type, Float32 x, Float32 y, Float32 z, CPlayer & source, bool grounded); + +/* ------------------------------------------------------------------------------------------------ + * Play a game sound. +*/ +void PlaySound(Int32 world, Int32 sound, const Vector3 & pos); + +/* ------------------------------------------------------------------------------------------------ + * Play a game sound. +*/ +void PlaySoundEx(Int32 world, Int32 sound, Float32 x, Float32 y, Float32 z); + +/* ------------------------------------------------------------------------------------------------ + * Make a map object invisible. +*/ +void HideMapObject(Int32 model, const Vector3 & pos); + +/* ------------------------------------------------------------------------------------------------ + * Make a map object invisible. +*/ +void HideMapObjectEx(Int32 model, Float32 x, Float32 y, Float32 z); + +/* ------------------------------------------------------------------------------------------------ + * Make a map object invisible. +*/ +void HideMapObjectRaw(Int32 model, Int16 x, Int16 y, Int16 z); + +/* ------------------------------------------------------------------------------------------------ + * Make a map object visible again. +*/ +void ShowMapObject(Int32 model, const Vector3 & pos); + +/* ------------------------------------------------------------------------------------------------ + * Make a map object visible again. +*/ +void ShowMapObjectEx(Int32 model, Float32 x, Float32 y, Float32 z); + +/* ------------------------------------------------------------------------------------------------ + * Make a map object visible again. +*/ +void ShowMapObjectRaw(Int32 model, Int16 x, Int16 y, Int16 z); + +/* ------------------------------------------------------------------------------------------------ + * Make all map objects visible again. +*/ +void ShowAllMapObjects(void); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve field data of a certain weapon. +*/ +SQFloat GetWeaponDataValue(Int32 weapon, Int32 field); + +/* ------------------------------------------------------------------------------------------------ + * Modify field data of a certain weapon. +*/ +bool SetWeaponDataValue(Int32 weapon, Int32 field, SQFloat value); + +/* ------------------------------------------------------------------------------------------------ + * Reset field data of a certain weapon. +*/ +bool ResetWeaponDataValue(Int32 weapon, Int32 field); + +/* ------------------------------------------------------------------------------------------------ + * See whether field data of a certain weapon was modified. +*/ +bool IsWeaponDataValueModified(Int32 weapon, Int32 field); + +/* ------------------------------------------------------------------------------------------------ + * Reset all fields data of a certain weapon. +*/ +bool ResetWeaponData(Int32 weapon); + +/* ------------------------------------------------------------------------------------------------ + * Reset all fields data of a all weapons. +*/ +void ResetAllWeaponData(); + +/* ------------------------------------------------------------------------------------------------ + * Create a new player class. +*/ +Int32 AddPlayerClass(Int32 team, const Color3 & color, Int32 skin, const Vector3 & pos, Float32 angle, + Int32 wep1, Int32 ammo1, Int32 wep2, Int32 ammo2, Int32 wep3, Int32 ammo3); + +/* ------------------------------------------------------------------------------------------------ + * Set the player position when spawning. +*/ +void SetSpawnPlayerPosition(const Vector3 & pos); + +/* ------------------------------------------------------------------------------------------------ + * Set the camera position when spawning. +*/ +void SetSpawnCameraPosition(const Vector3 & pos); + +/* ------------------------------------------------------------------------------------------------ + * Set the camera focus when spawning. +*/ +void SetSpawnCameraLookAt(const Vector3 & pos); + +/* ------------------------------------------------------------------------------------------------ + * Set the player position when spawning. +*/ +void SetSpawnPlayerPositionEx(Float32 x, Float32 y, Float32 z); + +/* ------------------------------------------------------------------------------------------------ + * Set the camera position when spawning. +*/ +void SetSpawnCameraPositionEx(Float32 x, Float32 y, Float32 z); + +/* ------------------------------------------------------------------------------------------------ + * Set the camera focus when spawning. +*/ +void SetSpawnCameraLookAtEx(Float32 x, Float32 y, Float32 z); + +/* ------------------------------------------------------------------------------------------------ + * Ban an IP address from the server. +*/ +void BanIP(CSStr addr); + +/* ------------------------------------------------------------------------------------------------ + * Unban an IP address from the server. +*/ +bool UnbanIP(CSStr addr); + +/* ------------------------------------------------------------------------------------------------ + * See if an IP address is banned from the server. +*/ +bool IsIPBanned(CSStr addr); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the identifier of the player with the specified name. +*/ +Int32 GetPlayerIdFromName(CSStr name); + +/* ------------------------------------------------------------------------------------------------ + * See if a player with the specified identifier is connected. +*/ +bool IsPlayerConnected(Int32 player_id); + +/* ------------------------------------------------------------------------------------------------ + * Force all players on the server to select a class. +*/ +void ForceAllSelect(); + +/* ------------------------------------------------------------------------------------------------ + * See if an entity exists on the server. +*/ +bool CheckEntityExists(Int32 type, Int32 index); } // Namespace:: SqMod diff --git a/source/Misc/Model.cpp b/source/Misc/Model.cpp index 5c726764..70503342 100644 --- a/source/Misc/Model.cpp +++ b/source/Misc/Model.cpp @@ -9,19 +9,16 @@ namespace SqMod { // ------------------------------------------------------------------------------------------------ -CCStr GetModelName(Int32 id) +CSStr GetModelName(Int32 /*id*/) { // @TODO Implement... - SQMOD_UNUSED_VAR(id); return _SC(""); } // ------------------------------------------------------------------------------------------------ -void SetModelName(Int32 id, CCStr name) +void SetModelName(Int32 /*id*/, CSStr /*name*/) { // @TODO Implement... - SQMOD_UNUSED_VAR(id); - SQMOD_UNUSED_VAR(name); } // ------------------------------------------------------------------------------------------------ @@ -71,6 +68,44 @@ bool IsModelWeapon(Int32 id) } // ------------------------------------------------------------------------------------------------ - +bool IsModelActuallyWeapon(Int32 id) +{ + switch (id) + { + case 259: + case 260: + case 261: + case 262: + case 263: + case 264: + case 265: + case 266: + case 267: + case 268: + case 269: + case 270: + case 271: + case 272: + case 274: + case 275: + case 276: + case 277: + case 278: + case 279: + case 280: + case 281: + case 282: + case 283: + case 284: + case 285: + case 286: + case 287: + case 288: + case 289: + case 290: + case 291: return true; + default: return false; + } +} } // Namespace:: SqMod diff --git a/source/Misc/Model.hpp b/source/Misc/Model.hpp index 8ecdb092..9a55c5b1 100644 --- a/source/Misc/Model.hpp +++ b/source/Misc/Model.hpp @@ -7,12 +7,25 @@ // ------------------------------------------------------------------------------------------------ namespace SqMod { -// ------------------------------------------------------------------------------------------------ -CCStr GetModelName(Int32 id); -void SetModelName(Int32 id, CCStr name); +/* ------------------------------------------------------------------------------------------------ + * Retrieve the name associated with a model identifier. +*/ +CSStr GetModelName(Int32 id); + +/* ------------------------------------------------------------------------------------------------ + * Modify the name associated with a model identifier. +*/ +void SetModelName(Int32 id, CSStr name); + +/* ------------------------------------------------------------------------------------------------ + * See whether the given model identifier is used a weapon model. +*/ bool IsModelWeapon(Int32 id); + +/* ------------------------------------------------------------------------------------------------ + * See whether the given model identifier is an actual weapon model. +*/ bool IsModelActuallyWeapon(Int32 id); -bool IsWeaponNatural(Int32 id); } // Namespace:: SqMod diff --git a/source/Misc/Player.cpp b/source/Misc/Player.cpp index 9711aa5f..a37b1ac5 100644 --- a/source/Misc/Player.cpp +++ b/source/Misc/Player.cpp @@ -47,42 +47,10 @@ static String CS_Skin_Names[] = { "" }; -// ------------------------------------------------------------------------------------------------ -void SetUseClasses(bool toggle) -{ _Func->SetUseClasses(toggle); } -bool GetUseClasses(void) -{ return _Func->GetUseClasses(); } - -// ------------------------------------------------------------------------------------------------ -Int32 AddPlayerClass(Int32 team, const Color3 & color, Int32 skin, const Vector3 & pos, Float32 angle, - Int32 w1, Int32 a1, Int32 w2, Int32 a2, Int32 w3, Int32 a3) -{ - return _Func->AddPlayerClass(team, color.GetRGB(), skin, pos.x, pos.y, pos.z, angle, - w1, a1, w2, a2, w3, a3); -} - -// ------------------------------------------------------------------------------------------------ -void SetSpawnPlayerPos(const Vector3 & pos) -{ _Func->SetSpawnPlayerPos(pos.x, pos.y, pos.z); } -void SetSpawnPlayerPosEx(Float32 x, Float32 y, Float32 z) -{ _Func->SetSpawnPlayerPos(x, y, z); } - -// ------------------------------------------------------------------------------------------------ -void SetSpawnCameraPos(const Vector3 & pos) -{ _Func->SetSpawnCameraPos(pos.x, pos.y, pos.z); } -void SetSpawnCameraPosEx(Float32 x, Float32 y, Float32 z) -{ _Func->SetSpawnCameraPos(x, y, z); } - -// ------------------------------------------------------------------------------------------------ -void SetSpawnCameraLookAt(const Vector3 & pos) -{ _Func->SetSpawnCameraLookAt(pos.x, pos.y, pos.z); } -void SetSpawnCameraLookAtEx(Float32 x, Float32 y, Float32 z) -{ _Func->SetSpawnCameraLookAt(x, y, z); } - // ------------------------------------------------------------------------------------------------ CCStr GetSkinName(Uint32 id) { - return (id > 159) ? g_EmptyStr : CS_Skin_Names[id].c_str(); + return (id > 159) ? _SC("") : CS_Skin_Names[id].c_str(); } // ------------------------------------------------------------------------------------------------ @@ -721,29 +689,8 @@ Int32 GetSkinID(CCStr name) // ------------------------------------------------------------------------------------------------ bool IsSkinValid(Int32 id) { - return (strlen(GetSkinName(id)) > 0); -} - -// ------------------------------------------------------------------------------------------------ -Object & FindPlayer(Object & by) -{ - switch (by.GetType()) - { - case OT_INTEGER: - return _Core->GetPlayer(by.Cast< Int32 >()).mObj; - case OT_FLOAT: - return _Core->GetPlayer(round(by.Cast< Float32 >())).mObj; - case OT_STRING: - { - String str(by.Cast< String >()); - Int32 id = _Func->GetPlayerIDFromName(&str[0]); - if (VALID_ENTITYEX(id, SQMOD_PLAYER_POOL)) - _Core->GetPlayer(id).mObj; - } break; - default: - STHROWF("Unsupported search identifier"); - } - return NullObject(); + CSStr name = GetSkinName(id); + return (name && *name != '\0'); } } // Namespace:: SqMod diff --git a/source/Misc/Player.hpp b/source/Misc/Player.hpp index b710ec23..46de19c9 100644 --- a/source/Misc/Player.hpp +++ b/source/Misc/Player.hpp @@ -7,34 +7,25 @@ // ------------------------------------------------------------------------------------------------ namespace SqMod { -// ------------------------------------------------------------------------------------------------ -void SetUseClasses(bool toggle); -bool GetUseClasses(void); - -// ------------------------------------------------------------------------------------------------ -Int32 AddPlayerClass(Int32 team, const Color3 & color, Int32 skin, const Vector3 & pos, Float32 angle, - Int32 w1, Int32 a1, Int32 w2, Int32 a2, Int32 w3, Int32 a3); - -// ------------------------------------------------------------------------------------------------ -void SetSpawnPlayerPos(const Vector3 & pos); -void SetSpawnPlayerPosEx(Float32 x, Float32 y, Float32 z); - -// ------------------------------------------------------------------------------------------------ -void SetSpawnCameraPos(const Vector3 & pos); -void SetSpawnCameraPosEx(Float32 x, Float32 y, Float32 z); - -// ------------------------------------------------------------------------------------------------ -void SetSpawnCameraLookAt(const Vector3 & pos); -void SetSpawnCameraLookAtEx(Float32 x, Float32 y, Float32 z); - -// ------------------------------------------------------------------------------------------------ +/* ------------------------------------------------------------------------------------------------ + * Retrieve the name associated with a skin model identifier. +*/ CCStr GetSkinName(Uint32 id); -void SetSkinName(Uint32 id, CCStr name); -Int32 GetSkinID(CCStr name); -bool IsSkinValid(Int32 id); -// ------------------------------------------------------------------------------------------------ -Object & FindPlayer(Object & by); +/* ------------------------------------------------------------------------------------------------ + * Modify the name associated with a skin model identifier. +*/ +void SetSkinName(Uint32 id, CCStr name); + +/* ------------------------------------------------------------------------------------------------ + * Convert a vehicle model name to a skin model identifier. +*/ +Int32 GetSkinID(CCStr name); + +/* ------------------------------------------------------------------------------------------------ + * See whether the specified skin model identifier is valid. +*/ +bool IsSkinValid(Int32 id); } // Namespace:: SqMod diff --git a/source/Misc/Register.cpp b/source/Misc/Register.cpp index a7d37b11..f39bc433 100644 --- a/source/Misc/Register.cpp +++ b/source/Misc/Register.cpp @@ -1,4 +1,6 @@ // ------------------------------------------------------------------------------------------------ +#include "Core.hpp" +#include "Base/Shared.hpp" #include "Base/Color3.hpp" #include "Base/Vector2.hpp" #include "Base/Vector3.hpp" @@ -11,126 +13,148 @@ #include "Misc/Player.hpp" #include "Misc/Vehicle.hpp" #include "Misc/Weapon.hpp" -#include "Misc/World.hpp" // ------------------------------------------------------------------------------------------------ namespace SqMod { +// ------------------------------------------------------------------------------------------------ +static const Object & FindPlayer(Object & by) +{ + switch (by.GetType()) + { + case OT_INTEGER: + { + return Core::Get().GetPlayer(by.Cast< Int32 >()).mObj; + } break; + case OT_FLOAT: + { + return Core::Get().GetPlayer(std::round(by.Cast< Float32 >())).mObj; + } break; + case OT_STRING: + { + // Obtain the argument as a string + String str(by.Cast< String >()); + // Attempt to locate the player with this name + Int32 id = _Func->GetPlayerIdFromName(&str[0]); + // Was there a player with this name? + if (VALID_ENTITYEX(id, SQMOD_PLAYER_POOL)) + { + Core::Get().GetPlayer(id).mObj; + } + } break; + default: STHROWF("Unsupported search identifier"); + } + // Default to a null object + return NullObject(); +} + // ================================================================================================ void Register_Misc(HSQUIRRELVM vm) { Table srvns(vm); - srvns.Func(_SC("SetTimeRate"), &SetTimeRate) - .Func(_SC("GetTimeRate"), &GetTimeRate) - .Func(_SC("SetHour"), &SetHour) - .Func(_SC("GetHour"), &GetHour) - .Func(_SC("SetMinute"), &SetMinute) - .Func(_SC("GetMinute"), &GetMinute) - .Func(_SC("SetWeather"), &SetWeather) - .Func(_SC("GetWeather"), &GetWeather) - .Func(_SC("SetGravity"), &SetGravity) - .Func(_SC("GetGravity"), &GetGravity) - .Func(_SC("SetGamespeed"), &SetGamespeed) - .Func(_SC("GetGamespeed"), &GetGamespeed) - .Func(_SC("SetWaterLevel"), &SetWaterLevel) - .Func(_SC("GetWaterLevel"), &GetWaterLevel) - .Func(_SC("SetMaxHeight"), &SetMaxHeight) - .Func(_SC("GetMaxHeight"), &GetMaxHeight) - .Func(_SC("SetKillCmdDelay"), &SetKillCmdDelay) - .Func(_SC("GetKillCmdDelay"), &GetKillCmdDelay) - .Func(_SC("SetVehiclesForcedRespawnHeight"), &SetVehiclesForcedRespawnHeight) - .Func(_SC("GetVehiclesForcedRespawnHeight"), &GetVehiclesForcedRespawnHeight) - .Func(_SC("ToggleSyncFrameLimiter"), &ToggleSyncFrameLimiter) - .Func(_SC("EnabledSyncFrameLimiter"), &EnabledSyncFrameLimiter) - .Func(_SC("ToggleFrameLimiter"), &ToggleFrameLimiter) - .Func(_SC("EnabledFrameLimiter"), &EnabledFrameLimiter) - .Func(_SC("ToggleTaxiBoostJump"), &ToggleTaxiBoostJump) - .Func(_SC("EnabledTaxiBoostJump"), &EnabledTaxiBoostJump) - .Func(_SC("ToggleDriveOnWater"), &ToggleDriveOnWater) - .Func(_SC("EnabledDriveOnWater"), &EnabledDriveOnWater) - .Func(_SC("ToggleFastSwitch"), &ToggleFastSwitch) - .Func(_SC("EnabledFastSwitch"), &EnabledFastSwitch) - .Func(_SC("ToggleFriendlyFire"), &ToggleFriendlyFire) - .Func(_SC("EnabledFriendlyFire"), &EnabledFriendlyFire) - .Func(_SC("ToggleDisableDriveby"), &ToggleDisableDriveby) - .Func(_SC("EnabledDisableDriveby"), &EnabledDisableDriveby) - .Func(_SC("TogglePerfectHandling"), &TogglePerfectHandling) - .Func(_SC("EnabledPerfectHandling"), &EnabledPerfectHandling) - .Func(_SC("ToggleFlyingCars"), &ToggleFlyingCars) - .Func(_SC("EnabledFlyingCars"), &EnabledFlyingCars) - .Func(_SC("ToggleJumpSwitch"), &ToggleJumpSwitch) - .Func(_SC("EnabledJumpSwitch"), &EnabledJumpSwitch) - .Func(_SC("ToggleShowMarkers"), &ToggleShowMarkers) - .Func(_SC("EnabledShowMarkers"), &EnabledShowMarkers) - .Func(_SC("ToggleStuntBike"), &ToggleStuntBike) - .Func(_SC("EnabledStuntBike"), &EnabledStuntBike) - .Func(_SC("ToggleShootInAir"), &ToggleShootInAir) - .Func(_SC("EnabledShootInAir"), &EnabledShootInAir) - .Func(_SC("ToggleShowNametags"), &ToggleShowNametags) - .Func(_SC("EnabledShowNametags"), &EnabledShowNametags) - .Func(_SC("ToggleJoinMessages"), &ToggleJoinMessages) - .Func(_SC("EnabledJoinMessages"), &EnabledJoinMessages) - .Func(_SC("ToggleDeathMessages"), &ToggleDeathMessages) - .Func(_SC("EnabledDeathMessages"), &EnabledDeathMessages) - .Func(_SC("ToggleChatTagsByDefaultEnabled"), &ToggleChatTagsByDefaultEnabled) - .Func(_SC("EnabledChatTagsByDefault"), &EnabledChatTagsByDefault) - .Func(_SC("CreateExplosion"), &CreateExplosion) - .Func(_SC("CreateExplosionEx"), &CreateExplosionEx) - .Func(_SC("HideMapObject"), &HideMapObject) - .Func(_SC("HideMapObjectEx"), &HideMapObjectEx) - .Func(_SC("HideMapObjectRaw"), &HideMapObjectRaw) - .Func(_SC("ShowMapObject"), &ShowMapObject) - .Func(_SC("ShowMapObjectEx"), &ShowMapObjectEx) - .Func(_SC("ShowAllMapObjects"), &ShowAllMapObjects) - .Func(_SC("SetWastedSettings"), &SetWastedSettings) - .Func(_SC("GetWastedSettings"), &GetWastedSettings) - .Func(_SC("SetWorldBounds"), &SetWorldBounds) - .Func(_SC("SetWorldBoundsEx"), &SetWorldBoundsEx) - .Func(_SC("GetWorldBounds"), &GetWorldBounds) + srvns.SquirrelFunc(_SC("SendLogMessage"), &SendLogMessage) + .Func(_SC("GetVersion"), &GetServerVersion) + .Func(_SC("GetSettings"), &GetServerSettings) + .Func(_SC("GetNumberOfPlugins"), &GetNumberOfPlugins) + .Func(_SC("GetPluginInfo"), &GetPluginInfo) + .Func(_SC("FindPlugin"), &FindPlugin) + .Func(_SC("SendPluginCommand"), &SendPluginCommand) + .Func(_SC("GetTime"), &GetTime) + .Func(_SC("GetLastError"), &GetLastError) .Func(_SC("GetPluginVersion"), &GetPluginVersion) .Func(_SC("GetPluginVersionStr"), &GetPluginVersionStr) .Func(_SC("GetPluginName"), &GetPluginName) .Func(_SC("GetPluginAuthor"), &GetPluginAuthor) .Func(_SC("GetPluginID"), &GetPluginID) - .Func(_SC("GetNumberOfPlugins"), &GetNumberOfPlugins) - .Func(_SC("FindPlugin"), &FindPlugin) - .Func(_SC("GetVersion"), &GetServerVersion) - .Func(_SC("GetPort"), &GetServerPort) - .Func(_SC("GetFlags"), &GetServerFlags) - .Func(_SC("SetName"), &SetServerName) - .Func(_SC("GetName"), &GetServerName) - .Func(_SC("GetTime"), &GetTime) - .Func(_SC("SendCustomCommand"), &SendCustomCommand) - .Func(_SC("SetMaxPlayers"), &SetMaxPlayers) + .Func(_SC("GetServerPort"), &GetServerPort) + .Func(_SC("GetServerFlags"), &GetServerFlags) .Func(_SC("GetMaxPlayers"), &GetMaxPlayers) - .Func(_SC("SetServerPassword"), &SetServerPassword) - .Func(_SC("GetServerPassword"), &GetServerPassword) - .Func(_SC("SetGameModeText"), &SetGameModeText) + .Func(_SC("SetMaxPlayers"), &SetMaxPlayers) + .Func(_SC("GetServerName"), &GetServerName) + .Func(_SC("SetServerName"), &SetServerName) + .Func(_SC("GetPassword"), &GetServerPassword) + .Func(_SC("SetPassword"), &SetServerPassword) .Func(_SC("GetGameModeText"), &GetGameModeText) - .Func(_SC("AddRadioStream"), &AddRadioStream) - .Func(_SC("RemoveRadioStream"), &RemoveRadioStream); + .Func(_SC("SetGameModeText"), &SetGameModeText) + .Func(_SC("CreateRadioStream"), &CreateRadioStream) + .Func(_SC("CreateRadioStreamEx"), &CreateRadioStreamEx) + .Func(_SC("RemoveRadioStream"), &RemoveRadioStream) + .Func(_SC("Shutdown"), &ShutdownServer) + .Func(_SC("GetOption"), &GetServerOption) + .Func(_SC("SetOption"), &SetServerOption) + .Func(_SC("SetOptionEx"), &SetServerOptionEx) + .Func(_SC("GetWorldBounds"), &GetWorldBounds) + .Func(_SC("SetWorldBounds"), &SetWorldBounds) + .Func(_SC("SetWorldBoundsEx"), &SetWorldBoundsEx) + .Func(_SC("GetWastedSettings"), &GetWastedSettings) + .Func(_SC("SetWastedSettings"), &SetWastedSettings) + .Func(_SC("GetTimeRate"), &GetTimeRate) + .Func(_SC("SetTimeRate"), &SetTimeRate) + .Func(_SC("GetHour"), &GetHour) + .Func(_SC("SetHour"), &SetHour) + .Func(_SC("GetMinute"), &GetMinute) + .Func(_SC("SetMinute"), &SetMinute) + .Func(_SC("GetWeather"), &GetWeather) + .Func(_SC("SetWeather"), &SetWeather) + .Func(_SC("GetGravity"), &GetGravity) + .Func(_SC("SetGravity"), &SetGravity) + .Func(_SC("GetGameSpeed"), &GetGameSpeed) + .Func(_SC("SetGameSpeed"), &SetGameSpeed) + .Func(_SC("GetWaterLevel"), &GetWaterLevel) + .Func(_SC("SetWaterLevel"), &SetWaterLevel) + .Func(_SC("GetMaximumFlightAltitude"), &GetMaximumFlightAltitude) + .Func(_SC("SetMaximumFlightAltitude"), &SetMaximumFlightAltitude) + .Func(_SC("GetKillCommandDelay"), &GetKillCommandDelay) + .Func(_SC("SetKillCommandDelay"), &SetKillCommandDelay) + .Func(_SC("GetVehiclesForcedRespawnHeight"), &GetVehiclesForcedRespawnHeight) + .Func(_SC("SetVehiclesForcedRespawnHeight"), &SetVehiclesForcedRespawnHeight) + .Func(_SC("CreateExplosion"), &CreateExplosion) + .Func(_SC("CreateExplosionEx"), &CreateExplosionEx) + .Func(_SC("PlaySound"), &PlaySound) + .Func(_SC("PlaySoundEx"), &PlaySoundEx) + .Func(_SC("HideMapObject"), &HideMapObject) + .Func(_SC("HideMapObjectEx"), &SetKeyCodeName) + .Func(_SC("HideMapObjectRaw"), &HideMapObjectRaw) + .Func(_SC("ShowMapObject"), &ShowMapObject) + .Func(_SC("ShowMapObjectEx"), &ShowMapObjectEx) + .Func(_SC("ShowMapObjectRaw"), &ShowMapObjectRaw) + .Func(_SC("ShowAllMapObjects"), &ShowAllMapObjects) + .Func(_SC("GetWeaponDataValue"), &GetWeaponDataValue) + .Func(_SC("SetWeaponDataValue"), &SetWeaponDataValue) + .Func(_SC("ResetWeaponDataValue"), &ResetWeaponDataValue) + .Func(_SC("IsWeaponDataValueModified"), &IsWeaponDataValueModified) + .Func(_SC("ResetWeaponData"), &ResetWeaponData) + .Func(_SC("ResetAllWeaponData"), &ResetAllWeaponData) + .Func(_SC("AddPlayerClass"), &AddPlayerClass) + .Func(_SC("SetSpawnPlayerPosition"), &SetSpawnPlayerPosition) + .Func(_SC("SetSpawnCameraPosition"), &SetSpawnCameraPosition) + .Func(_SC("SetSpawnCameraLookAt"), &SetSpawnCameraLookAt) + .Func(_SC("SetSpawnPlayerPositionEx"), &SetSpawnPlayerPositionEx) + .Func(_SC("SetSpawnCameraPositionEx"), &SetSpawnCameraPositionEx) + .Func(_SC("SetSpawnCameraLookAtEx"), &SetSpawnCameraLookAtEx) + .Func(_SC("BanIP"), &BanIP) + .Func(_SC("UnbanIP"), &UnbanIP) + .Func(_SC("IsIPBanned"), &IsIPBanned) + .Func(_SC("GetPlayerIdFromName"), &GetPlayerIdFromName) + .Func(_SC("IsPlayerConnected"), &IsPlayerConnected) + .Func(_SC("ForceAllSelect"), &ForceAllSelect) + .Func(_SC("CheckEntityExists"), &SetKeyCodeName); RootTable(vm).Bind(_SC("SqServer"), srvns); RootTable(vm) + .Func(_SC("FindPlayer"), &FindPlayer) + .Func(_SC("GetKeyCodeName"), &GetKeyCodeName) + .Func(_SC("SetKeyCodeName"), &SetKeyCodeName) .Func(_SC("GetModelName"), &GetModelName) .Func(_SC("SetModelName"), &SetModelName) .Func(_SC("IsModelWeapon"), &IsModelWeapon) .Func(_SC("IsModelActuallyWeapon"), &IsModelActuallyWeapon) - .Func(_SC("IsWeaponNatural"), &IsWeaponNatural) - .Func(_SC("SetUseClasses"), &SetUseClasses) - .Func(_SC("GetUseClasses"), &GetUseClasses) - .Func(_SC("AddPlayerClass"), &AddPlayerClass) - .Func(_SC("SetSpawnPlayerPos"), &SetSpawnPlayerPos) - .Func(_SC("SetSpawnPlayerPosEx"), &SetSpawnPlayerPosEx) - .Func(_SC("SetSpawnCameraPos"), &SetSpawnCameraPos) - .Func(_SC("SetSpawnCameraPosEx"), &SetSpawnCameraPosEx) .Func(_SC("GetSkinName"), &GetSkinName) .Func(_SC("SetSkinName"), &SetSkinName) .Func(_SC("GetSkinID"), &GetSkinID) .Func(_SC("IsSkinValid"), &IsSkinValid) - .Func(_SC("FindPlayer"), &FindPlayer) .Func(_SC("GetAutomobileName"), &GetAutomobileName) .Func(_SC("SetAutomobileName"), &SetAutomobileName) .Func(_SC("GetAutomobileID"), &GetAutomobileID) @@ -140,8 +164,11 @@ void Register_Misc(HSQUIRRELVM vm) .Func(_SC("GetWeaponID"), &GetWeaponID) .Func(_SC("IsWeaponValid"), &IsWeaponValid) .Func(_SC("WeaponToModel"), &WeaponToModel) + .Func(_SC("IsWeaponNatural"), &IsWeaponNatural) .Func(_SC("PlaySound"), &PlaySound) - .Func(_SC("PlaySoundEx"), &PlaySoundEx); + .Func(_SC("PlaySoundEx"), &PlaySoundEx) + .Func(_SC("CreateExplosion"), &CreateExplosion) + .Func(_SC("CreateExplosionEx"), &CreateExplosionEx); } } // Namespace:: SqMod diff --git a/source/Misc/Vehicle.cpp b/source/Misc/Vehicle.cpp index f4e44f3e..c7e1d6f9 100644 --- a/source/Misc/Vehicle.cpp +++ b/source/Misc/Vehicle.cpp @@ -35,20 +35,22 @@ static String CS_Vehicle_Names[] = { }; // ------------------------------------------------------------------------------------------------ -CCStr GetAutomobileName(Uint32 id) +CSStr GetAutomobileName(Uint32 id) { return (id < 130 || id > 236) ? _SC("") : CS_Vehicle_Names[id-130].c_str(); } // ------------------------------------------------------------------------------------------------ -void SetAutomobileName(Uint32 id, CCStr name) +void SetAutomobileName(Uint32 id, CSStr name) { if (id >= 130 || id <= 236) + { CS_Vehicle_Names[id-130].assign(name); + } } // ------------------------------------------------------------------------------------------------ -Int32 GetAutomobileID(CCStr name) +Int32 GetAutomobileID(CSStr name) { // Clone the string into an editable version String str(name); @@ -58,7 +60,9 @@ Int32 GetAutomobileID(CCStr name) std::transform(str.begin(), str.end(), str.begin(), ::tolower); // See if we still have a valid name after the cleanup if(str.empty()) + { return SQMOD_UNKNOWN; + } // Grab the actual length of the string Uint32 len = static_cast< Uint32 >(str.length()); // Get the most significant characters used to identify a vehicle @@ -70,7 +74,9 @@ Int32 GetAutomobileID(CCStr name) b = str[1]; } else if(str.length() >= 2) + { b = str[1]; + } // Search for a pattern in the name switch (a) { @@ -618,51 +624,8 @@ Int32 GetAutomobileID(CCStr name) // ------------------------------------------------------------------------------------------------ bool IsAutomobileValid(Int32 id) { - return (strlen(GetAutomobileName(id)) > 0); + CSStr name = GetAutomobileName(id); + return (name && *name != '\0'); } -// ------------------------------------------------------------------------------------------------ -bool IsModelActuallyWeapon(Int32 id) -{ - switch (id) - { - case 259: - case 260: - case 261: - case 262: - case 263: - case 264: - case 265: - case 266: - case 267: - case 268: - case 269: - case 270: - case 271: - case 272: - case 274: - case 275: - case 276: - case 277: - case 278: - case 279: - case 280: - case 281: - case 282: - case 283: - case 284: - case 285: - case 286: - case 287: - case 288: - case 289: - case 290: - case 291: return true; - default: return false; - } -} - -// ------------------------------------------------------------------------------------------------ - - } // Namespace:: SqMod diff --git a/source/Misc/Vehicle.hpp b/source/Misc/Vehicle.hpp index 6224bd6c..cdc8195c 100644 --- a/source/Misc/Vehicle.hpp +++ b/source/Misc/Vehicle.hpp @@ -7,10 +7,24 @@ // ------------------------------------------------------------------------------------------------ namespace SqMod { -// ------------------------------------------------------------------------------------------------ -CCStr GetAutomobileName(Uint32 id); -void SetAutomobileName(Uint32 id, CCStr name); -Int32 GetAutomobileID(CCStr name); +/* ------------------------------------------------------------------------------------------------ + * Retrieve the name associated with a vehicle model identifier. +*/ +CSStr GetAutomobileName(Uint32 id); + +/* ------------------------------------------------------------------------------------------------ + * Modify the name associated with a vehicle model identifier. +*/ +void SetAutomobileName(Uint32 id, CSStr name); + +/* ------------------------------------------------------------------------------------------------ + * Convert a vehicle model name to a vehicle model identifier. +*/ +Int32 GetAutomobileID(CSStr name); + +/* ------------------------------------------------------------------------------------------------ + * See whether the specified vehicle model identifier is valid. +*/ bool IsAutomobileValid(Int32 id); } // Namespace:: SqMod diff --git a/source/Misc/Weapon.cpp b/source/Misc/Weapon.cpp index 06b8ea82..3d4ff3a5 100644 --- a/source/Misc/Weapon.cpp +++ b/source/Misc/Weapon.cpp @@ -40,7 +40,9 @@ CCStr GetWeaponName(Uint32 id) void SetWeaponName(Uint32 id, CCStr name) { if (id <= 70) + { CS_Weapon_Names[id].assign(name); + } } // ------------------------------------------------------------------------------------------------ @@ -54,7 +56,9 @@ Int32 GetWeaponID(CCStr name) std::transform(str.begin(), str.end(), str.begin(), ::tolower); // See if we still have a valid name after the cleanup if(str.length() < 1) + { return SQMOD_UNKNOWN; + } // Grab the actual length of the string Uint32 len = static_cast< Uint32 >(str.length()); // Get the most significant characters used to identify a weapon @@ -66,7 +70,9 @@ Int32 GetWeaponID(CCStr name) b = str[1]; } else if(str.length() >= 2) + { b = str[1]; + } // Search for a pattern in the name switch(a) { @@ -242,22 +248,8 @@ Int32 GetWeaponID(CCStr name) // ------------------------------------------------------------------------------------------------ bool IsWeaponValid(Int32 id) { - return (strlen(GetWeaponName(id)) > 0); -} - -// ------------------------------------------------------------------------------------------------ -bool IsWeaponNatural(Int32 id) -{ - switch (id) - { - case SQMOD_WEAPON_VEHICLE: - case SQMOD_WEAPON_DRIVEBY: - case SQMOD_WEAPON_DROWNED: - case SQMOD_WEAPON_FALL: - case SQMOD_WEAPON_EXPLOSION2: - case SQMOD_WEAPON_SUICIDE: return true; - default: return false; - } + CSStr name = GetWeaponName(id); + return (name && *name != '\0'); } // ------------------------------------------------------------------------------------------------ @@ -299,21 +291,25 @@ Int32 WeaponToModel(Int32 id) case SQMOD_WEAPON_FLAMETHROWER: return 288; case SQMOD_WEAPON_M60: return 289; case SQMOD_WEAPON_MINIGUN: return 290; - case SQMOD_WEAPON_BOMB: return SQMOD_UNKNOWN; case SQMOD_WEAPON_HELICANNON: return 294; case SQMOD_WEAPON_CAMERA: return 292; - case SQMOD_WEAPON_VEHICLE: return SQMOD_UNKNOWN; - case SQMOD_WEAPON_EXPLOSION1: return SQMOD_UNKNOWN; - case SQMOD_WEAPON_DRIVEBY: return SQMOD_UNKNOWN; - case SQMOD_WEAPON_DROWNED: return SQMOD_UNKNOWN; - case SQMOD_WEAPON_FALL: return SQMOD_UNKNOWN; - case SQMOD_WEAPON_EXPLOSION2: return SQMOD_UNKNOWN; - case SQMOD_WEAPON_SUICIDE: return SQMOD_UNKNOWN; default: return SQMOD_UNKNOWN; } } // ------------------------------------------------------------------------------------------------ - +bool IsWeaponNatural(Int32 id) +{ + switch (id) + { + case SQMOD_WEAPON_VEHICLE: + case SQMOD_WEAPON_DRIVEBY: + case SQMOD_WEAPON_DROWNED: + case SQMOD_WEAPON_FALL: + case SQMOD_WEAPON_EXPLOSION2: + case SQMOD_WEAPON_SUICIDE: return true; + default: return false; + } +} } // Namespace:: SqMod diff --git a/source/Misc/Weapon.hpp b/source/Misc/Weapon.hpp index c58e6e36..a1241bc8 100644 --- a/source/Misc/Weapon.hpp +++ b/source/Misc/Weapon.hpp @@ -7,13 +7,36 @@ // ------------------------------------------------------------------------------------------------ namespace SqMod { -// ------------------------------------------------------------------------------------------------ -CCStr GetWeaponName(Uint32 id); -void SetWeaponName(Uint32 id, CCStr name); -Int32 GetWeaponID(CCStr name); +/* ------------------------------------------------------------------------------------------------ + * Retrieve the name associated with a weapon identifier. +*/ +CSStr GetWeaponName(Uint32 id); + +/* ------------------------------------------------------------------------------------------------ + * Modify the name associated with a weapon identifier. +*/ +void SetWeaponName(Uint32 id, CSStr name); + +/* ------------------------------------------------------------------------------------------------ + * Convert a weapon name to a weapon identifier. +*/ +Int32 GetWeaponID(CSStr name); + +/* ------------------------------------------------------------------------------------------------ + * See whether the specified weapon identifier is valid. +*/ bool IsWeaponValid(Int32 id); + +/* ------------------------------------------------------------------------------------------------ + * Convert the given weapon identifier to it's associated model identifier. +*/ Int32 WeaponToModel(Int32 id); +/* ------------------------------------------------------------------------------------------------ + * See whether the given weapon identifier cannot be used by another player to inflict damage. +*/ +bool IsWeaponNatural(Int32 id); + } // Namespace:: SqMod #endif // _MISC_WEAPON_HPP_ diff --git a/source/Misc/World.cpp b/source/Misc/World.cpp deleted file mode 100644 index 586675cb..00000000 --- a/source/Misc/World.cpp +++ /dev/null @@ -1,254 +0,0 @@ -// ------------------------------------------------------------------------------------------------ -#include "Misc/World.hpp" -#include "Base/Color3.hpp" -#include "Base/Vector2.hpp" -#include "Base/Vector3.hpp" -#include "Entity/Player.hpp" - -// ------------------------------------------------------------------------------------------------ -namespace SqMod { - -// ------------------------------------------------------------------------------------------------ -void SetTimeRate(Uint32 rate) { _Func->SetTimeRate(rate); } -Uint32 GetTimeRate(void) { return _Func->GetTimeRate(); } - -// ------------------------------------------------------------------------------------------------ -void SetHour(Int32 hour) { _Func->SetHour(hour); } -Int32 GetHour(void) { return _Func->GetHour(); } - -// ------------------------------------------------------------------------------------------------ -void SetMinute(Int32 minute) { _Func->SetMinute(minute); } -Int32 GetMinute(void) { return _Func->GetMinute(); } - -// ------------------------------------------------------------------------------------------------ -void SetWeather(Int32 weather) { _Func->SetWeather(weather); } -Int32 GetWeather(void) { return _Func->GetWeather(); } - -// ------------------------------------------------------------------------------------------------ -void SetGravity(Float32 gravity) { _Func->SetGamespeed(gravity); } -Float32 GetGravity(void) { return _Func->GetGamespeed(); } - -// ------------------------------------------------------------------------------------------------ -void SetGamespeed(Float32 speed) { _Func->SetGamespeed(speed); } -Float32 GetGamespeed(void) { return _Func->GetGamespeed(); } - -// ------------------------------------------------------------------------------------------------ -void SetWaterLevel(Float32 level) { _Func->SetWaterLevel(level); } -Float32 GetWaterLevel(void) { return _Func->GetWaterLevel(); } - -// ------------------------------------------------------------------------------------------------ -void SetMaxHeight(Float32 height) { _Func->SetMaxHeight(height); } -Float32 GetMaxHeight(void) { return _Func->GetMaxHeight(); } - -// ------------------------------------------------------------------------------------------------ -void SetKillCmdDelay(Int32 delay) { _Func->SetKillCmdDelay(delay); } -Int32 GetKillCmdDelay(void) { return _Func->GetKillCmdDelay(); } - -// ------------------------------------------------------------------------------------------------ -void SetVehiclesForcedRespawnHeight(Float32 height) -{ _Func->SetVehiclesForcedRespawnHeight(height); } -Float32 GetVehiclesForcedRespawnHeight(void) -{ return _Func->GetVehiclesForcedRespawnHeight(); } - -// ------------------------------------------------------------------------------------------------ -void ToggleSyncFrameLimiter(bool toggle) -{ _Func->ToggleSyncFrameLimiter(toggle); } -bool EnabledSyncFrameLimiter(void) -{ return _Func->EnabledSyncFrameLimiter(); } - -// ------------------------------------------------------------------------------------------------ -void ToggleFrameLimiter(bool toggle) -{ _Func->ToggleFrameLimiter(toggle); } -bool EnabledFrameLimiter(void) -{ return _Func->EnabledFrameLimiter(); } - -// ------------------------------------------------------------------------------------------------ -void ToggleTaxiBoostJump(bool toggle) -{ _Func->ToggleTaxiBoostJump(toggle); } -bool EnabledTaxiBoostJump(void) -{ return _Func->EnabledTaxiBoostJump(); } - -// ------------------------------------------------------------------------------------------------ -void ToggleDriveOnWater(bool toggle) -{ _Func->ToggleDriveOnWater(toggle); } -bool EnabledDriveOnWater(void) -{ return _Func->EnabledDriveOnWater(); } - -// ------------------------------------------------------------------------------------------------ -void ToggleFastSwitch(bool toggle) -{ _Func->ToggleFastSwitch(toggle); } -bool EnabledFastSwitch(void) -{ return _Func->EnabledFastSwitch(); } - -// ------------------------------------------------------------------------------------------------ -void ToggleFriendlyFire(bool toggle) -{ _Func->ToggleFriendlyFire(toggle); } -bool EnabledFriendlyFire(void) -{ return _Func->EnabledFriendlyFire(); } - -// ------------------------------------------------------------------------------------------------ -void ToggleDisableDriveby(bool toggle) -{ _Func->ToggleDisableDriveby(toggle); } -bool EnabledDisableDriveby(void) -{ return _Func->EnabledDisableDriveby(); } - -// ------------------------------------------------------------------------------------------------ -void TogglePerfectHandling(bool toggle) -{ _Func->TogglePerfectHandling(toggle); } -bool EnabledPerfectHandling(void) -{ return _Func->EnabledPerfectHandling(); } - -// ------------------------------------------------------------------------------------------------ -void ToggleFlyingCars(bool toggle) -{ _Func->ToggleFlyingCars(toggle); } -bool EnabledFlyingCars(void) -{ return _Func->EnabledFlyingCars(); } - -// ------------------------------------------------------------------------------------------------ -void ToggleJumpSwitch(bool toggle) -{ _Func->ToggleJumpSwitch(toggle); } -bool EnabledJumpSwitch(void) -{ return _Func->EnabledJumpSwitch(); } - -// ------------------------------------------------------------------------------------------------ -void ToggleShowMarkers(bool toggle) -{ _Func->ToggleShowMarkers(toggle); } -bool EnabledShowMarkers(void) -{ return _Func->EnabledShowMarkers(); } - -// ------------------------------------------------------------------------------------------------ -void ToggleStuntBike(bool toggle) -{ _Func->ToggleStuntBike(toggle); } -bool EnabledStuntBike(void) -{ return _Func->EnabledStuntBike(); } - -// ------------------------------------------------------------------------------------------------ -void ToggleShootInAir(bool toggle) -{ _Func->ToggleShootInAir(toggle); } -bool EnabledShootInAir(void) -{ return _Func->EnabledShootInAir(); } - -// ------------------------------------------------------------------------------------------------ -void ToggleShowNametags(bool toggle) -{ _Func->ToggleShowNametags(toggle); } -bool EnabledShowNametags(void) -{ return _Func->EnabledShowNametags(); } - -// ------------------------------------------------------------------------------------------------ -void ToggleJoinMessages(bool toggle) -{ _Func->ToggleJoinMessages(toggle); } -bool EnabledJoinMessages(void) -{ return _Func->EnabledJoinMessages(); } - -// ------------------------------------------------------------------------------------------------ -void ToggleDeathMessages(bool toggle) -{ _Func->ToggleDeathMessages(toggle); } -bool EnabledDeathMessages(void) -{ return _Func->EnabledDeathMessages(); } - -// ------------------------------------------------------------------------------------------------ -void ToggleChatTagsByDefaultEnabled(bool toggle) -{ _Func->ToggleChatTagsByDefaultEnabled(toggle); } -bool EnabledChatTagsByDefault(void) -{ return _Func->EnabledChatTagsByDefault(); } - -// ------------------------------------------------------------------------------------------------ -void CreateExplosion(Int32 world, Int32 type, const Vector3 & pos, CPlayer & source, Uint32 level) -{ - // Validate the specified player - source.Validate(); - // Perform the requested operation - _Func->CreateExplosion(world, type, pos.x, pos.y, pos.z, source.GetID(), level); -} - -void CreateExplosionEx(Int32 world, Int32 type, Float32 x, Float32 y, Float32 z, CPlayer & source, Uint32 level) -{ - // Validate the specified player - source.Validate(); - // Perform the requested operation - _Func->CreateExplosion(world, type, x, y, z, source.GetID(), level); -} - -// ------------------------------------------------------------------------------------------------ -void HideMapObject(Int32 model, const Vector3 & pos) -{ - _Func->HideMapObject(model, - static_cast< Int32 >(std::floor(pos.x * 10.0f) + 0.5f), - static_cast< Int32 >(std::floor(pos.y * 10.0f) + 0.5f), - static_cast< Int32 >(std::floor(pos.z * 10.0f) + 0.5f) - ); -} - -// ------------------------------------------------------------------------------------------------ -void HideMapObjectEx(Int32 model, Float32 x, Float32 y, Float32 z) -{ - _Func->HideMapObject(model, - static_cast< Int32 >(std::floor(x * 10.0f) + 0.5f), - static_cast< Int32 >(std::floor(y * 10.0f) + 0.5f), - static_cast< Int32 >(std::floor(z * 10.0f) + 0.5f) - ); -} - -// ------------------------------------------------------------------------------------------------ -void HideMapObjectRaw(Int32 model, Int32 x, Int32 y, Int32 z) -{ - _Func->HideMapObject(model, x, y, z); -} - -// ------------------------------------------------------------------------------------------------ -void ShowMapObject(Int32 model, const Vector3 & pos) -{ _Func->ShowMapObject(model, pos.x, pos.y, pos.z); } -void ShowMapObjectEx(Int32 model, Float32 x, Float32 y, Float32 z) -{ _Func->ShowMapObject(model, x, y, z); } - -// ------------------------------------------------------------------------------------------------ -void ShowAllMapObjects(void) -{ _Func->ShowAllMapObjects(); } - -// ------------------------------------------------------------------------------------------------ -void SetWastedSettings(Uint32 dt, Uint32 ft, Float32 fis, Float32 fos, - const Color3 & fc, Uint32 cfs, Uint32 cft) -{ - _Func->SetWastedSettings(dt, ft, fis, fos, fc.GetRGB(), cfs, cft); -} - -Table GetWastedSettings() -{ - Uint32 fc, dt, ft, cfs, cft; - Float32 fis, fos; - Color3 c; - _Func->GetWastedSettings(&dt, &ft, &fis, &fos, &fc, &cfs, &cft); - c.SetRGB(fc); - Table t(DefaultVM::Get()); - t.SetValue(_SC("dt"), dt); - t.SetValue(_SC("ft"), ft); - t.SetValue(_SC("fis"), fis); - t.SetValue(_SC("fos"), fos); - t.SetValue(_SC("fc"), c); - t.SetValue(_SC("cfs"), cfs); - t.SetValue(_SC("cft"), cft); - return t; -} - -// ------------------------------------------------------------------------------------------------ -void SetWorldBounds(const Vector2 & max, const Vector2 & min) -{ - _Func->SetWorldBounds(max.x, min.x, max.y, min.y); -} - -void SetWorldBoundsEx(Float32 max_x, Float32 max_y, Float32 min_x, Float32 min_y) -{ - _Func->SetWorldBounds(max_x, min_x, max_y, min_y); -} - -Table GetWorldBounds() -{ - Vector2 max, min; - _Func->GetWorldBounds(&max.x, &min.x, &max.y, &min.y); - Table t(DefaultVM::Get()); - t.SetValue(_SC("max"),max); - t.SetValue(_SC("min"), min); - return t; -} - -} // Namespace:: SqMod diff --git a/source/Misc/World.hpp b/source/Misc/World.hpp deleted file mode 100644 index 8a997673..00000000 --- a/source/Misc/World.hpp +++ /dev/null @@ -1,114 +0,0 @@ -#ifndef _MISC_WORLD_HPP_ -#define _MISC_WORLD_HPP_ - -// ------------------------------------------------------------------------------------------------ -#include "SqBase.hpp" - -// ------------------------------------------------------------------------------------------------ -namespace SqMod { - -// ------------------------------------------------------------------------------------------------ -void SetTimeRate(Uint32 rate); -Uint32 GetTimeRate(void); - -// ------------------------------------------------------------------------------------------------ -void SetHour(Int32 hour); -Int32 GetHour(void); - -// ------------------------------------------------------------------------------------------------ -void SetMinute(Int32 minute); -Int32 GetMinute(void); - -// ------------------------------------------------------------------------------------------------ -void SetWeather(Int32 weather); -Int32 GetWeather(void); - -// ------------------------------------------------------------------------------------------------ -void SetGravity(Float32 gravity); -Float32 GetGravity(void); - -// ------------------------------------------------------------------------------------------------ -void SetGamespeed(Float32 speed); -Float32 GetGamespeed(void); - -// ------------------------------------------------------------------------------------------------ -void SetWaterLevel(Float32 level); -Float32 GetWaterLevel(void); - -// ------------------------------------------------------------------------------------------------ -void SetMaxHeight(Float32 height); -Float32 GetMaxHeight(void); - -// ------------------------------------------------------------------------------------------------ -void SetKillCmdDelay(Int32 delay); -Int32 GetKillCmdDelay(void); - -// ------------------------------------------------------------------------------------------------ -void SetVehiclesForcedRespawnHeight(Float32 height); -Float32 GetVehiclesForcedRespawnHeight(void); - -// ------------------------------------------------------------------------------------------------ -void ToggleSyncFrameLimiter(bool toggle); -bool EnabledSyncFrameLimiter(void); -void ToggleFrameLimiter(bool toggle); -bool EnabledFrameLimiter(void); -void ToggleTaxiBoostJump(bool toggle); -bool EnabledTaxiBoostJump(void); -void ToggleDriveOnWater(bool toggle); -bool EnabledDriveOnWater(void); -void ToggleFastSwitch(bool toggle); -bool EnabledFastSwitch(void); -void ToggleFriendlyFire(bool toggle); -bool EnabledFriendlyFire(void); -void ToggleDisableDriveby(bool toggle); -bool EnabledDisableDriveby(void); -void TogglePerfectHandling(bool toggle); -bool EnabledPerfectHandling(void); -void ToggleFlyingCars(bool toggle); -bool EnabledFlyingCars(void); -void ToggleJumpSwitch(bool toggle); -bool EnabledJumpSwitch(void); -void ToggleShowMarkers(bool toggle); -bool EnabledShowMarkers(void); -void ToggleStuntBike(bool toggle); -bool EnabledStuntBike(void); -void ToggleShootInAir(bool toggle); -bool EnabledShootInAir(void); -void ToggleShowNametags(bool toggle); -bool EnabledShowNametags(void); -void ToggleJoinMessages(bool toggle); -bool EnabledJoinMessages(void); -void ToggleDeathMessages(bool toggle); -bool EnabledDeathMessages(void); -void ToggleChatTagsByDefaultEnabled(bool toggle); -bool EnabledChatTagsByDefault(void); - -// ------------------------------------------------------------------------------------------------ -void CreateExplosion(Int32 world, Int32 type, const Vector3 & pos, CPlayer & source, Uint32 level); -void CreateExplosionEx(Int32 world, Int32 type, Float32 x, Float32 y, Float32 z, CPlayer & source, Uint32 level); - -// ------------------------------------------------------------------------------------------------ -void HideMapObject(Int32 model, const Vector3 & pos); -void HideMapObjectEx(Int32 model, Float32 x, Float32 y, Float32 z); -void HideMapObjectRaw(Int32 model, Int32 x, Int32 y, Int32 z); - -// ------------------------------------------------------------------------------------------------ -void ShowMapObject(Int32 model, const Vector3 & pos); -void ShowMapObjectEx(Int32 model, Float32 x, Float32 y, Float32 z); - -// ------------------------------------------------------------------------------------------------ -void ShowAllMapObjects(void); - -// ------------------------------------------------------------------------------------------------ -void SetWastedSettings(Uint32 dt, Uint32 ft, Float32 fis, Float32 fos, - const Color3 & fc, Uint32 cfs, Uint32 cft); -Table GetWastedSettings(); - -// ------------------------------------------------------------------------------------------------ -void SetWorldBounds(const Vector2 & max, const Vector2 & min); -void SetWorldBoundsEx(Float32 max_x, Float32 max_y, Float32 min_x, Float32 min_y); -Table GetWorldBounds(); - -} // Namespace:: SqMod - -#endif // _MISC_WORLD_HPP_ diff --git a/source/Register.cpp b/source/Register.cpp index 0dffc171..b8f5939b 100644 --- a/source/Register.cpp +++ b/source/Register.cpp @@ -40,8 +40,7 @@ extern void Register_Numeric(HSQUIRRELVM vm); extern void Register_Math(HSQUIRRELVM vm); extern void Register_Random(HSQUIRRELVM vm); extern void Register_String(HSQUIRRELVM vm); -extern void Register_SysEnv(HSQUIRRELVM vm); -extern void Register_SysPath(HSQUIRRELVM vm); +extern void Register_System(HSQUIRRELVM vm); // ------------------------------------------------------------------------------------------------ extern void Register_Constants(HSQUIRRELVM vm); @@ -70,13 +69,10 @@ bool RegisterAPI(HSQUIRRELVM vm) Register_CBlip(vm); Register_CCheckpoint(vm); - Register_CForcefield(vm); Register_CKeybind(vm); Register_CObject(vm); Register_CPickup(vm); Register_CPlayer(vm); - Register_CSprite(vm); - Register_CTextdraw(vm); Register_CVehicle(vm); Register_Chrono(vm); @@ -85,8 +81,7 @@ bool RegisterAPI(HSQUIRRELVM vm) Register_Numeric(vm); Register_Math(vm); Register_String(vm); - Register_SysEnv(vm); - Register_SysPath(vm); + Register_System(vm); Register_Constants(vm); Register_Log(vm); diff --git a/source/Routine.cpp b/source/Routine.cpp index 46059451..757c69d9 100644 --- a/source/Routine.cpp +++ b/source/Routine.cpp @@ -10,11 +10,9 @@ namespace SqMod { // ------------------------------------------------------------------------------------------------ -bool Routine::s_Lock = false; Routine::Time Routine::s_Last = 0; Routine::Time Routine::s_Prev = 0; -Routine::Queue Routine::s_Queue; -Routine::Buckets Routine::s_Buckets; +Routine::Routines Routine::s_Routines; Routine::Objects Routine::s_Objects; // ------------------------------------------------------------------------------------------------ @@ -26,57 +24,66 @@ SQInteger Routine::Typename(HSQUIRRELVM vm) } // ------------------------------------------------------------------------------------------------ -void Routine::Attach(Routine * routine, Interval interval) +void Routine::Process() { - // Do we have a valid routine and interval bucket to attach? - if (!routine || !interval) + // Is this the first call? + if (s_Last == 0) { + s_Last = GetCurrentSysTime(); + // We'll do it text time return; } - // Attempt to locate the bucket with the specified interval - Buckets::iterator itr = std::find_if(s_Buckets.begin(), s_Buckets.end(), IntrvFunc(interval)); - // Does this bucket exist? - if (itr == s_Buckets.end()) + // Backup the last known time-stamp + s_Prev = s_Last; + // Get the current time-stamp + s_Last = GetCurrentSysTime(); + // Calculate the elapsed time + const Int32 delta = Int32((s_Last - s_Prev) / 1000L); + // Process all active routines + for (auto & r : s_Routines) { - // Then create it - s_Buckets.emplace_back(interval); - // And attach this routine - s_Buckets.back().mRoutines.push_back(routine); - } - // Is this routine already attached to this bucket? - else if (std::find(itr->mRoutines.begin(), itr->mRoutines.end(), routine) == itr->mRoutines.end()) - { - itr->mRoutines.push_back(routine); // Then let's attach it now + // Is this routine valid? + if (!r.second) + { + continue; + } + // Decrease the elapsed time + r.first -= delta; + // Have we completed the routine interval? + if (r.first <= 0) + { + // Reset the elapsed time + r.first = r.second->m_Interval; + // Execute the routine + r.second->Execute(); + } } } // ------------------------------------------------------------------------------------------------ -void Routine::Detach(Routine * routine, Interval interval) +void Routine::Initialize() { - // Do we have a valid routine and interval to detach? - if (!routine || !interval) + // Clear all slots + s_Routines.fill(Element(0, nullptr)); +} + +// ------------------------------------------------------------------------------------------------ +void Routine::Deinitialize() +{ + // Process all routine instances + for (auto & r : s_Objects) { - return; - } - // Attempt to locate the bucket with this interval - Buckets::iterator bitr = std::find_if(s_Buckets.begin(), s_Buckets.end(), IntrvFunc(interval)); - // Was there a bucket with this interval? - if (bitr == s_Buckets.end()) - { - return; // Nothing to detach from! - } - // Attempt to find this routine in the associated bucket - Routines::iterator ritr = std::find(bitr->mRoutines.begin(), bitr->mRoutines.end(), routine); - // Was this routine even attached? - if (ritr != bitr->mRoutines.end()) - { - bitr->mRoutines.erase(ritr); // Then erase it and move on - } - // Any reason to keep this bucket? (don't immediate routines with interval of 1) - if (interval != 1 && bitr->mRoutines.empty()) - { - s_Buckets.erase(bitr); // Remove the bucket as well + // Release all resources + r.first->Release(); + // Mark it as terminated + r.first->m_Terminated = true; } + // Release all references + s_Objects.clear(); + // Clear all slots + s_Routines.fill(Element(0, nullptr)); + // Clear the last time-stamp in case of a reload + s_Last = 0; } // ------------------------------------------------------------------------------------------------ @@ -142,474 +149,71 @@ void Routine::Forget(Routine * routine) } // ------------------------------------------------------------------------------------------------ -void Routine::ProcQueue() +void Routine::Insert(Routine * routine, bool associate) { - // Do we have any queued commands that must be performed when unlocked? - if (s_Queue.empty() || s_Lock) + // Do we even have what to insert? + if (!routine) { - return; // We're done here! - } - // Process all commands in the queue - for (const auto & cmd : s_Queue) - { - // Are we supposed to detach the associated routine? - if (cmd.mCommand == CMD_DETACH) - { - // Detach the routine from it's associated bucket first - Detach(cmd.mRoutine, cmd.mInterval); - // Break association to allow the instance to be destroyed - Dissociate(cmd.mRoutine); - } - // Are we supposed to attach the associated routine? - else if (cmd.mCommand == CMD_ATTACH) - { - // Attach the routine to it's associated bucket first - Attach(cmd.mRoutine, cmd.mInterval); - // Prevent destruction of this routine while buckets are locked - Associate(cmd.mRoutine); - } - } - // Clear processed commands - s_Queue.clear(); -} - -// ------------------------------------------------------------------------------------------------ -void Routine::Process() -{ - // In case an exception prevented the unlock last time - s_Lock = false; - // Normally there shouldn't be any but just in case the above happened - ProcQueue(); - // Is this the first call? - if (s_Last == 0) - { - s_Last = GetCurrentSysTime(); - // We'll do it text time return; } - // Lock the buckets - s_Lock = true; - // Backup the last known time-stamp - s_Prev = s_Last; - // Get the current time-stamp - s_Last = GetCurrentSysTime(); - // Calculate the elapsed time - Int32 delta = Int32((s_Last - s_Prev) / 1000L); - // Process all available buckets - for (auto & bucket : s_Buckets) + // See if this routine is already inserted + Routines::iterator itr = std::find_if(s_Routines.begin(), s_Routines.end(), + [routine](Element & e) -> bool { return (e.second == routine); }); + // Is this instance already inserted? + if (itr != s_Routines.end()) { - // Update the bucket elapsed time - bucket.mElapsed += delta; - // Have we completed the bucket interval? - if (bucket.mElapsed < bucket.mInterval) + return; // We have what we came here for! + } + // Attempt to locate an unused routine slot + itr = std::find_if(s_Routines.begin(), s_Routines.end(), + [](Element & e) -> bool { return (e.second == nullptr); }); + // Are there any slots available? + if (itr == s_Routines.end()) + { + STHROWF("Maximum number of active routines was reached: %d", SQMOD_MAX_ROUTINES); + } + // Insert the routine at the obtained slot + itr->first = routine->m_Interval; + itr->second = routine; + // Associate this slot with the routine instance + routine->m_Slot = std::distance(s_Routines.begin(), itr); + // Keep a string reference to this routine instance, if requested + if (associate) + { + Associate(routine); + } +} + +// ------------------------------------------------------------------------------------------------ +void Routine::Remove(Routine * routine) +{ + // Do we even have what to remove? + if (!routine) + { + return; + } + Routines::iterator itr; + // Make sure the routine wasn't activated multiple time (paranoia) + do { + // Search for the slot with the specified routine instance + itr = std::find_if(s_Routines.begin(), s_Routines.end(), + [routine](Element & e) -> bool { return (e.second == routine); }); + // Was this routine instance activated? + if (itr != s_Routines.end()) { - continue; // Move to the next one + itr->first = 0; + itr->second = nullptr; } - // Attempt to execute bucket routines, if any - for (auto & routine : bucket.mRoutines) - { - routine->Execute(); - } - // Reset the bucket elapsed time - bucket.mElapsed = 0; - } - // Unlock the buckets - s_Lock = false; - // Process operations that couldn't be performed while buckets were locked - ProcQueue(); -} - -// ------------------------------------------------------------------------------------------------ -void Routine::TerminateAll() -{ - // Let's make sure no pending commands are left - ProcQueue(); - // Process all buckets - for (auto & bucket : s_Buckets) - { - // Process all routines in this bucket - for (auto & routine : bucket.mRoutines) - { - // Release all resources - routine->Release(); - // Mark it as terminated - routine->m_Terminated = true; - } - } - // Clear all references to routines - s_Buckets.clear(); - // Clear all routine instance associations - s_Objects.clear(); - // Clear the last time-stamp in case of a reload - s_Last = 0; -} - -// ------------------------------------------------------------------------------------------------ -Routine::Routine(Object & env, Function & func, Interval interval) - : m_Iterations(0) - , m_Interval(interval) - , m_Arguments(0) - , m_Suspended(false) - , m_Terminated(false) - , m_Callback(env.GetVM(), env, func.GetFunc()) - , m_Tag(_SC("")) - , m_Data() -{ - Create(); -} - -Routine::Routine(Object & env, Function & func, Interval interval, Iterate iterations) - : m_Iterations(iterations) - , m_Interval(interval) - , m_Arguments(0) - , m_Suspended(false) - , m_Terminated(false) - , m_Callback(env.GetVM(), env, func.GetFunc()) - , m_Tag(_SC("")) - , m_Data() -{ - Create(); -} - -// ------------------------------------------------------------------------------------------------ -Routine::Routine(Object & env, Function & func, Interval interval, Iterate iterations - , Object & a1) - : m_Iterations(iterations) - , m_Interval(interval) - , m_Arguments(1) - , m_Suspended(false) - , m_Terminated(false) - , m_Callback(env.GetVM(), env, func.GetFunc()) - , m_Tag(_SC("")) - , m_Data() - , m_Arg1(a1) -{ - Create(); -} - -// ------------------------------------------------------------------------------------------------ -Routine::Routine(Object & env, Function & func, Interval interval, Iterate iterations - , Object & a1, Object & a2) - : m_Iterations(iterations) - , m_Interval(interval) - , m_Arguments(2) - , m_Suspended(false) - , m_Terminated(false) - , m_Callback(env.GetVM(), env, func.GetFunc()) - , m_Tag(_SC("")) - , m_Data() - , m_Arg1(a1), m_Arg2(a2) -{ - Create(); -} - -// ------------------------------------------------------------------------------------------------ -Routine::Routine(Object & env, Function & func, Interval interval, Iterate iterations - , Object & a1, Object & a2, Object & a3) - : m_Iterations(iterations) - , m_Interval(interval) - , m_Arguments(3) - , m_Suspended(false) - , m_Terminated(false) - , m_Callback(env.GetVM(), env, func.GetFunc()) - , m_Tag(_SC("")) - , m_Data() - , m_Arg1(a1), m_Arg2(a2), m_Arg3(a3) -{ - Create(); -} - -// ------------------------------------------------------------------------------------------------ -Routine::Routine(Object & env, Function & func, Interval interval, Iterate iterations - , Object & a1, Object & a2, Object & a3, Object & a4) - : m_Iterations(iterations) - , m_Interval(interval) - , m_Arguments(4) - , m_Suspended(false) - , m_Terminated(false) - , m_Callback(env.GetVM(), env, func.GetFunc()) - , m_Tag(_SC("")) - , m_Data() - , m_Arg1(a1), m_Arg2(a2), m_Arg3(a3), m_Arg4(a4) -{ - Create(); -} - -// ------------------------------------------------------------------------------------------------ -Routine::Routine(Object & env, Function & func, Interval interval, Iterate iterations - , Object & a1, Object & a2, Object & a3, Object & a4, Object & a5) - : m_Iterations(iterations) - , m_Interval(interval) - , m_Arguments(5) - , m_Suspended(false) - , m_Terminated(false) - , m_Callback(env.GetVM(), env, func.GetFunc()) - , m_Tag(_SC("")) - , m_Data() - , m_Arg1(a1), m_Arg2(a2), m_Arg3(a3), m_Arg4(a4), m_Arg5(a5) -{ - Create(); -} - -// ------------------------------------------------------------------------------------------------ -Routine::~Routine() -{ - // Remove this instance from the pool - Forget(this); - // Was the routine already terminated? - if (m_Terminated) - { - return; // Nothing to release! - } - // Detach from the associated bucket - Detach(); - // Release script resources - Release(); -} - -// ------------------------------------------------------------------------------------------------ -Int32 Routine::Cmp(const Routine & o) const -{ - if (m_Interval == o.m_Interval) - return 0; - else if (m_Interval > o.m_Interval) - return 1; - else - return -1; -} - -// ------------------------------------------------------------------------------------------------ -CSStr Routine::ToString() const -{ - return ToStrF(_PRINT_INT_FMT, m_Interval); -} - -// ------------------------------------------------------------------------------------------------ -const String & Routine::GetTag() const -{ - return m_Tag; -} - -// ------------------------------------------------------------------------------------------------ -void Routine::SetTag(CSStr tag) -{ - m_Tag.assign(tag ? tag : _SC("")); -} - -// ------------------------------------------------------------------------------------------------ -Object & Routine::GetData() -{ - // Validate the routine lifetime - Validate(); - // Return the requested information - return m_Data; -} - -// ------------------------------------------------------------------------------------------------ -void Routine::SetData(Object & data) -{ - // Validate the routine lifetime - Validate(); - // Apply the specified value - m_Data = data; -} - -// ------------------------------------------------------------------------------------------------ -Routine & Routine::ApplyTag(CSStr tag) -{ - m_Tag.assign(tag ? tag : _SC("")); - // Allow chaining - return *this; -} - -// ------------------------------------------------------------------------------------------------ -Routine & Routine::ApplyData(Object & data) -{ - // Validate the routine lifetime - Validate(); - // Apply the specified value - m_Data = data; - // Allow chaining - return *this; -} - -// ------------------------------------------------------------------------------------------------ -void Routine::Terminate() -{ - // Was the routine already terminated? - if (m_Terminated) - { - STHROWF("Routine was already terminated"); - } - // Detach from the associated bucket - Detach(); - // Release script resources and mark it as terminated - Release(); -} - -// ------------------------------------------------------------------------------------------------ -Routine & Routine::SetArg(Uint8 num, Object & val) -{ - // Validate the routine lifetime - Validate(); - // Identify which argument was requested - switch (num) - { - case 1: m_Arg1 = val; break; - case 2: m_Arg2 = val; break; - case 3: m_Arg3 = val; break; - case 4: m_Arg4 = val; break; - case 5: m_Arg5 = val; break; - case 6: m_Arg6 = val; break; - case 7: m_Arg7 = val; break; - case 8: m_Arg8 = val; break; - case 9: m_Arg9 = val; break; - case 10: m_Arg10 = val; break; - case 11: m_Arg11 = val; break; - case 12: m_Arg12 = val; break; - case 13: m_Arg13 = val; break; - case 14: m_Arg14 = val; break; - default: STHROWF("Argument is out of range: %d", num); - } - // Allow chaining - return *this; -} - -// ------------------------------------------------------------------------------------------------ -Object & Routine::GetArg(Uint8 num) -{ - // Validate the routine lifetime - Validate(); - // Identify which argument was requested - switch (num) - { - case 1: return m_Arg1; - case 2: return m_Arg2; - case 3: return m_Arg3; - case 4: return m_Arg4; - case 5: return m_Arg5; - case 6: return m_Arg6; - case 7: return m_Arg7; - case 8: return m_Arg8; - case 9: return m_Arg9; - case 10: return m_Arg10; - case 11: return m_Arg11; - case 12: return m_Arg12; - case 13: return m_Arg13; - case 14: return m_Arg14; - default: STHROWF("Argument is out of range: %d", num); - } - // Shouldn't really reach this point - return NullObject(); -} - -// ------------------------------------------------------------------------------------------------ -Routine::Interval Routine::GetInterval() const -{ - return m_Interval; -} - -// ------------------------------------------------------------------------------------------------ -void Routine::SetInterval(Interval interval) -{ - // Validate the routine lifetime - Validate(); - // Is the specified interval valid? - if (!interval) - { - STHROWF("Invalid routine interval"); - } - // Detach from the current bucket - Detach(); - // Update the interval - m_Interval = interval; - // Attach to the new bucket - Attach(); -} - -// ------------------------------------------------------------------------------------------------ -Routine::Iterate Routine::GetIterations() const -{ - return m_Iterations; -} - -// ------------------------------------------------------------------------------------------------ -void Routine::SetIterations(Iterate iterations) -{ - // Validate the routine lifetime - Validate(); - // Perform the requested operation - m_Iterations = iterations; -} - -// ------------------------------------------------------------------------------------------------ -Uint8 Routine::GetArguments() const -{ - return m_Arguments; -} - -void Routine::SetArguments(Uint8 num) -{ - // Validate the routine lifetime - Validate(); - // Is the specified argument count valid? - if (num > 14) - { - STHROWF("Argument is out of range: %d", num); - } - // Perform the requested operation - m_Arguments = num; -} - -// ------------------------------------------------------------------------------------------------ -bool Routine::GetSuspended() const -{ - return m_Suspended; -} - -// ------------------------------------------------------------------------------------------------ -void Routine::SetSuspended(bool toggle) -{ - // Validate the routine lifetime - Validate(); - // Perform the requested operation - m_Suspended = toggle; -} - -// ------------------------------------------------------------------------------------------------ -bool Routine::GetTerminated() const -{ - return m_Terminated; -} - -// ------------------------------------------------------------------------------------------------ -Function & Routine::GetCallback() -{ - // Validate the routine lifetime - Validate(); - // Return the requested information - return m_Callback; -} - -// ------------------------------------------------------------------------------------------------ -void Routine::SetCallback(Object & env, Function & func) -{ - // Validate the routine lifetime - Validate(); - // Perform the requested operation - m_Callback = Function(env.GetVM(), env, func.GetFunc()); + } while (itr != s_Routines.end()); + // Reset the routine instance slot + routine->m_Slot = 0xFFFF; + // Release any strong reference to this routine instance + Dissociate(routine); } // ------------------------------------------------------------------------------------------------ void Routine::Release() { - // Was the routine already terminated? - if (m_Terminated) - { - return; // Nothing to release! - } - // Mark it as terminated - m_Terminated = true; // Release the callback m_Callback.ReleaseGently(); // Release the arguments @@ -629,71 +233,6 @@ void Routine::Release() m_Arg14.Release(); } -// ------------------------------------------------------------------------------------------------ -void Routine::Create() -{ - // Do we even have a valid interval? - if (!m_Interval) - { - STHROWF("Invalid routine interval"); - } - // Is the specified callback even valid? - else if (m_Callback.IsNull()) - { - STHROWF("Invalid routine callback"); - } - // Always use the command queue to attach the routine when created - s_Queue.emplace_back(this, m_Interval, CMD_ATTACH); -} - -// ------------------------------------------------------------------------------------------------ -void Routine::Attach() -{ - // Do we have a valid interval? - if (!m_Interval) - { - return; // Nothing to attach to! - } - // Are the buckets locked? - else if (s_Lock) - { - // Queue a command to attach this routine when the bucket is unlocked - s_Queue.emplace_back(this, m_Interval, CMD_ATTACH); - } - // Attempt to attach the the routine now - else - { - // Attach to the associated bucket - Attach(this, m_Interval); - // Associate the instance with it's script object to prevent unexpected release - Associate(this); - } -} - -// ------------------------------------------------------------------------------------------------ -void Routine::Detach() -{ - // Do we have a valid interval? - if (!m_Interval) - { - return; // Nothing to detach from! - } - // Are the buckets locked? - else if (s_Lock) - { - // Queue a command to detach this routine when the bucket is unlocked - s_Queue.emplace_back(this, m_Interval, CMD_DETACH); - } - // Attempt to detach the the routine now - else - { - // Detach from the associated bucket - Detach(this, m_Interval); - // Break association to allow the instance to be released - Dissociate(this); - } -} - // ------------------------------------------------------------------------------------------------ void Routine::Execute() { @@ -785,21 +324,485 @@ void Routine::Execute() Terminate(); // This routine reached the end of it's life } } - -/* ------------------------------------------------------------------------------------------------ - * Forward the call to process routines. -*/ -void ProcessRoutine() +// ------------------------------------------------------------------------------------------------ +Routine::Routine(Object & env, Function & func, Interval interval) + : m_Iterations(0) + , m_Interval(interval) + , m_Slot(0xFFFF) + , m_Arguments(0) + , m_Suspended(false) + , m_Terminated(false) + , m_Callback(env.GetVM(), env, func.GetFunc()) + , m_Tag(_SC("")) + , m_Data() { - Routine::Process(); + // Make sure the interval is good + if (m_Interval < 0) + { + STHROWF("Invalid routine interval"); + } + else + { + Insert(this, false); + } } -/* ------------------------------------------------------------------------------------------------ - * Forward the call to terminate routines. -*/ -void TerminateRoutine() +Routine::Routine(Object & env, Function & func, Interval interval, Iterator iterations) + : m_Iterations(iterations) + , m_Interval(interval) + , m_Slot(0xFFFF) + , m_Arguments(0) + , m_Suspended(false) + , m_Terminated(false) + , m_Callback(env.GetVM(), env, func.GetFunc()) + , m_Tag(_SC("")) + , m_Data() { - Routine::TerminateAll(); + // Make sure the interval is good + if (m_Interval < 0) + { + STHROWF("Invalid routine interval"); + } + else + { + Insert(this, false); + } +} + +// ------------------------------------------------------------------------------------------------ +Routine::Routine(Object & env, Function & func, Interval interval, Iterator iterations + , Object & a1) + : m_Iterations(iterations) + , m_Interval(interval) + , m_Slot(0xFFFF) + , m_Arguments(1) + , m_Suspended(false) + , m_Terminated(false) + , m_Callback(env.GetVM(), env, func.GetFunc()) + , m_Tag(_SC("")) + , m_Data() + , m_Arg1(a1) +{ + // Make sure the interval is good + if (m_Interval < 0) + { + STHROWF("Invalid routine interval"); + } + else + { + Insert(this, false); + } +} + +// ------------------------------------------------------------------------------------------------ +Routine::Routine(Object & env, Function & func, Interval interval, Iterator iterations + , Object & a1, Object & a2) + : m_Iterations(iterations) + , m_Interval(interval) + , m_Slot(0xFFFF) + , m_Arguments(2) + , m_Suspended(false) + , m_Terminated(false) + , m_Callback(env.GetVM(), env, func.GetFunc()) + , m_Tag(_SC("")) + , m_Data() + , m_Arg1(a1), m_Arg2(a2) +{ + // Make sure the interval is good + if (m_Interval < 0) + { + STHROWF("Invalid routine interval"); + } + else + { + Insert(this, false); + } +} + +// ------------------------------------------------------------------------------------------------ +Routine::Routine(Object & env, Function & func, Interval interval, Iterator iterations + , Object & a1, Object & a2, Object & a3) + : m_Iterations(iterations) + , m_Interval(interval) + , m_Slot(0xFFFF) + , m_Arguments(3) + , m_Suspended(false) + , m_Terminated(false) + , m_Callback(env.GetVM(), env, func.GetFunc()) + , m_Tag(_SC("")) + , m_Data() + , m_Arg1(a1), m_Arg2(a2), m_Arg3(a3) +{ + // Make sure the interval is good + if (m_Interval < 0) + { + STHROWF("Invalid routine interval"); + } + else + { + Insert(this, false); + } +} + +// ------------------------------------------------------------------------------------------------ +Routine::Routine(Object & env, Function & func, Interval interval, Iterator iterations + , Object & a1, Object & a2, Object & a3, Object & a4) + : m_Iterations(iterations) + , m_Interval(interval) + , m_Slot(0xFFFF) + , m_Arguments(4) + , m_Suspended(false) + , m_Terminated(false) + , m_Callback(env.GetVM(), env, func.GetFunc()) + , m_Tag(_SC("")) + , m_Data() + , m_Arg1(a1), m_Arg2(a2), m_Arg3(a3), m_Arg4(a4) +{ + // Make sure the interval is good + if (m_Interval < 0) + { + STHROWF("Invalid routine interval"); + } + else + { + Insert(this, false); + } +} + +// ------------------------------------------------------------------------------------------------ +Routine::Routine(Object & env, Function & func, Interval interval, Iterator iterations + , Object & a1, Object & a2, Object & a3, Object & a4, Object & a5) + : m_Iterations(iterations) + , m_Interval(interval) + , m_Slot(0xFFFF) + , m_Arguments(5) + , m_Suspended(false) + , m_Terminated(false) + , m_Callback(env.GetVM(), env, func.GetFunc()) + , m_Tag(_SC("")) + , m_Data() + , m_Arg1(a1), m_Arg2(a2), m_Arg3(a3), m_Arg4(a4), m_Arg5(a5) +{ + // Make sure the interval is good + if (m_Interval < 0) + { + STHROWF("Invalid routine interval"); + } + else + { + Insert(this, false); + } +} + +// ------------------------------------------------------------------------------------------------ +Routine::~Routine() +{ + // Remove this instance from the pool + Forget(this); + // Was the routine already terminated? + if (!m_Terminated) + { + return; // Nothing to release! + } + // Remove it from the pool + Remove(this); + // Release script resources + Release(); +} + +// ------------------------------------------------------------------------------------------------ +Int32 Routine::Cmp(const Routine & o) const +{ + if (m_Interval == o.m_Interval) + { + return 0; + } + else if (m_Interval > o.m_Interval) + { + return 1; + } + else + { + return -1; + } +} + +// ------------------------------------------------------------------------------------------------ +CSStr Routine::ToString() const +{ + return ToStrF(_PRINT_INT_FMT, m_Interval); +} + +// ------------------------------------------------------------------------------------------------ +const String & Routine::GetTag() const +{ + return m_Tag; +} + +// ------------------------------------------------------------------------------------------------ +void Routine::SetTag(CSStr tag) +{ + m_Tag.assign(tag ? tag : _SC("")); +} + +// ------------------------------------------------------------------------------------------------ +Object & Routine::GetData() +{ + // Validate the routine lifetime + Validate(); + // Return the requested information + return m_Data; +} + +// ------------------------------------------------------------------------------------------------ +void Routine::SetData(Object & data) +{ + // Validate the routine lifetime + Validate(); + // Apply the specified value + m_Data = data; +} + +// ------------------------------------------------------------------------------------------------ +Routine & Routine::ApplyTag(CSStr tag) +{ + m_Tag.assign(tag ? tag : _SC("")); + // Allow chaining + return *this; +} + +// ------------------------------------------------------------------------------------------------ +Routine & Routine::ApplyData(Object & data) +{ + // Validate the routine lifetime + Validate(); + // Apply the specified value + m_Data = data; + // Allow chaining + return *this; +} + +// ------------------------------------------------------------------------------------------------ +Routine & Routine::Activate() +{ + // Validate the routine lifetime + Validate(); + // Make sure the interval is good + if (m_Interval < 0) + { + STHROWF("Invalid routine interval"); + } + // Make sure no slot is associated + else if (m_Slot >= s_Routines.size()) + { + Insert(this); + } + // Allow chaining + return *this; +} + +// ------------------------------------------------------------------------------------------------ +Routine & Routine::Deactivate() +{ + // Validate the routine lifetime + Validate(); + // Remove it from the pool + Remove(this); + // Allow chaining + return *this; +} + +// ------------------------------------------------------------------------------------------------ +Routine & Routine::Terminate() +{ + // Was the routine already terminated? + if (m_Terminated) + { + STHROWF("Routine was already terminated"); + } + // Remove it from the pool + Remove(this); + // Release script resources + Release(); + // Mark it as terminated + m_Terminated = true; + // Allow chaining + return *this; +} + +// ------------------------------------------------------------------------------------------------ +Routine & Routine::Reanimate() +{ + // Allow the instance to be used + m_Terminated = false; + // Allow chaining + return *this; +} + +// ------------------------------------------------------------------------------------------------ +Routine & Routine::SetArg(Uint16 num, Object & val) +{ + // Validate the routine lifetime + Validate(); + // Identify which argument was requested + switch (num) + { + case 1: m_Arg1 = val; break; + case 2: m_Arg2 = val; break; + case 3: m_Arg3 = val; break; + case 4: m_Arg4 = val; break; + case 5: m_Arg5 = val; break; + case 6: m_Arg6 = val; break; + case 7: m_Arg7 = val; break; + case 8: m_Arg8 = val; break; + case 9: m_Arg9 = val; break; + case 10: m_Arg10 = val; break; + case 11: m_Arg11 = val; break; + case 12: m_Arg12 = val; break; + case 13: m_Arg13 = val; break; + case 14: m_Arg14 = val; break; + default: STHROWF("Argument is out of range: %d", num); + } + // Allow chaining + return *this; +} + +// ------------------------------------------------------------------------------------------------ +Object & Routine::GetArg(Uint16 num) +{ + // Validate the routine lifetime + Validate(); + // Identify which argument was requested + switch (num) + { + case 1: return m_Arg1; + case 2: return m_Arg2; + case 3: return m_Arg3; + case 4: return m_Arg4; + case 5: return m_Arg5; + case 6: return m_Arg6; + case 7: return m_Arg7; + case 8: return m_Arg8; + case 9: return m_Arg9; + case 10: return m_Arg10; + case 11: return m_Arg11; + case 12: return m_Arg12; + case 13: return m_Arg13; + case 14: return m_Arg14; + default: STHROWF("Argument is out of range: %d", num); + } + // Shouldn't really reach this point + return NullObject(); +} + +// ------------------------------------------------------------------------------------------------ +Routine::Interval Routine::GetInterval() const +{ + return m_Interval; +} + +// ------------------------------------------------------------------------------------------------ +void Routine::SetInterval(Interval interval) +{ + // Validate the routine lifetime + Validate(); + // Is the specified interval valid? + if (interval < 0) + { + STHROWF("Invalid routine interval"); + } + // Do we have any slot to update? + if (m_Slot >= s_Routines.size()) + { + // Update the interval + m_Interval = interval; + // We're done here! + return; + } + // Make changes visible immediately + if (interval > m_Interval) + { + s_Routines[m_Slot].first += (interval - m_Interval); + } + else + { + s_Routines[m_Slot].first -= (m_Interval - interval); + } + // Update the interval + m_Interval = interval; +} + +// ------------------------------------------------------------------------------------------------ +Routine::Iterator Routine::GetIterations() const +{ + return m_Iterations; +} + +// ------------------------------------------------------------------------------------------------ +void Routine::SetIterations(Iterator iterations) +{ + // Validate the routine lifetime + Validate(); + // Perform the requested operation + m_Iterations = iterations; +} + +// ------------------------------------------------------------------------------------------------ +Uint16 Routine::GetArguments() const +{ + return m_Arguments; +} + +void Routine::SetArguments(Uint16 num) +{ + // Validate the routine lifetime + Validate(); + // Is the specified argument count valid? + if (num > 14) + { + STHROWF("Argument is out of range: %d", num); + } + // Perform the requested operation + m_Arguments = num; +} + +// ------------------------------------------------------------------------------------------------ +bool Routine::GetSuspended() const +{ + return m_Suspended; +} + +// ------------------------------------------------------------------------------------------------ +void Routine::SetSuspended(bool toggle) +{ + // Validate the routine lifetime + Validate(); + // Perform the requested operation + m_Suspended = toggle; +} + +// ------------------------------------------------------------------------------------------------ +bool Routine::GetTerminated() const +{ + return m_Terminated; +} + +// ------------------------------------------------------------------------------------------------ +Function & Routine::GetCallback() +{ + // Validate the routine lifetime + Validate(); + // Return the requested information + return m_Callback; +} + +// ------------------------------------------------------------------------------------------------ +void Routine::SetCallback(Object & env, Function & func) +{ + // Validate the routine lifetime + Validate(); + // Perform the requested operation + m_Callback = Function(env.GetVM(), env, func.GetFunc()); } // ------------------------------------------------------------------------------------------------ @@ -809,120 +812,46 @@ Object Routine::Create(Object & env, Function & func, Interval interval) } // ------------------------------------------------------------------------------------------------ -Object Routine::Create(Object & env, Function & func, Interval interval, Iterate iterations) +Object Routine::Create(Object & env, Function & func, Interval interval, Iterator iterations) { return Associate(new Routine(env, func, interval, iterations)); } // ------------------------------------------------------------------------------------------------ -Object Routine::Create(Object & env, Function & func, Interval interval, Iterate iterations +Object Routine::Create(Object & env, Function & func, Interval interval, Iterator iterations , Object & a1) { return Associate(new Routine(env, func, interval, iterations, a1)); } // ------------------------------------------------------------------------------------------------ -Object Routine::Create(Object & env, Function & func, Interval interval, Iterate iterations +Object Routine::Create(Object & env, Function & func, Interval interval, Iterator iterations , Object & a1, Object & a2) { return Associate(new Routine(env, func, interval, iterations, a1, a2)); } // ------------------------------------------------------------------------------------------------ -Object Routine::Create(Object & env, Function & func, Interval interval, Iterate iterations +Object Routine::Create(Object & env, Function & func, Interval interval, Iterator iterations , Object & a1, Object & a2, Object & a3) { return Associate(new Routine(env, func, interval, iterations, a1, a2, a3)); } // ------------------------------------------------------------------------------------------------ -Object Routine::Create(Object & env, Function & func, Interval interval, Iterate iterations +Object Routine::Create(Object & env, Function & func, Interval interval, Iterator iterations , Object & a1, Object & a2, Object & a3, Object & a4) { return Associate(new Routine(env, func, interval, iterations, a1, a2, a3, a4)); } // ------------------------------------------------------------------------------------------------ -Object Routine::Create(Object & env, Function & func, Interval interval, Iterate iterations +Object Routine::Create(Object & env, Function & func, Interval interval, Iterator iterations , Object & a1, Object & a2, Object & a3, Object & a4, Object & a5) { return Associate(new Routine(env, func, interval, iterations, a1, a2, a3, a4, a5)); } -// ------------------------------------------------------------------------------------------------ -void Routine::Flush() -{ - // Make sure the buckets are not locked - if (s_Lock) - { - STHROWF("Buckets are under active lock"); - } - // Process commands in queue - ProcQueue(); -} - -// ------------------------------------------------------------------------------------------------ -Uint32 Routine::QueueSize() -{ - return static_cast< Uint32 >(s_Queue.size()); -} - -// ------------------------------------------------------------------------------------------------ -Uint32 Routine::GetCount() -{ - return static_cast< Uint32 >(s_Objects.size()); -} - -// ------------------------------------------------------------------------------------------------ -Uint32 Routine::GetBuckets() -{ - return static_cast< Uint32 >(s_Buckets.size()); -} - -// ------------------------------------------------------------------------------------------------ -Uint32 Routine::GetInBucket(Interval interval) -{ - // Attempt to locate the bucket with the specified interval - Buckets::iterator itr = std::find_if(s_Buckets.begin(), s_Buckets.end(), IntrvFunc(interval)); - // Does this bucket exist? - if (itr == s_Buckets.end()) - { - return 0; // This bucket doesn't exist! - } - // Return the number of elements in this bucket - return static_cast< Uint32 >(itr->mRoutines.size()); -} - -// ------------------------------------------------------------------------------------------------ -Array Routine::GetBucketsList() -{ - // Allocate an array large enough to hold the number of active buckets - Array arr(DefaultVM::Get(), s_Buckets.size()); - // The index where the bucket interval should be inserted - SQInteger idx = 0; - // Insert the interval and size of each active bucket - for (const auto & bucket : s_Buckets) - { - arr.SetValue(idx++, bucket.mInterval); - } - // Return the resulted array - return arr; -} - -// ------------------------------------------------------------------------------------------------ -Table Routine::GetBucketsTable() -{ - // Create a table to hold the number of active buckets - Table tbl(DefaultVM::Get()); - // Insert the interval of each active bucket - for (const auto & bucket : s_Buckets) - { - tbl.SetValue(bucket.mInterval, bucket.mRoutines.size()); - } - // Return the resulted table - return tbl; -} - // ------------------------------------------------------------------------------------------------ Object Routine::FindByTag(CSStr tag) { @@ -955,16 +884,40 @@ Object Routine::FindByTag(CSStr tag) return NullObject(); } +/* ------------------------------------------------------------------------------------------------ + * Forward the call to process routines. +*/ +void ProcessRoutines() +{ + Routine::Process(); +} + +/* ------------------------------------------------------------------------------------------------ + * Forward the call to initialize routines. +*/ +void InitializeRoutines() +{ + Routine::Initialize(); +} + +/* ------------------------------------------------------------------------------------------------ + * Forward the call to terminate routines. +*/ +void TerminateRoutines() +{ + Routine::Deinitialize(); +} + // ================================================================================================ void Register_Routine(HSQUIRRELVM vm) { RootTable(vm).Bind(_SC("SqRoutine"), Class< Routine, NoConstructor< Routine > >(vm, _SC("SqRoutine")) - /* Metamethods */ + // Metamethods .Func(_SC("_cmp"), &Routine::Cmp) .SquirrelFunc(_SC("_typename"), &Routine::Typename) .Func(_SC("_tostring"), &Routine::ToString) - /* Properties */ + // Properties .Prop(_SC("Tag"), &Routine::GetTag, &Routine::SetTag) .Prop(_SC("Data"), &Routine::GetData, &Routine::SetData) .Prop(_SC("Interval"), &Routine::GetInterval, &Routine::SetInterval) @@ -973,7 +926,7 @@ void Register_Routine(HSQUIRRELVM vm) .Prop(_SC("Suspended"), &Routine::GetSuspended, &Routine::SetSuspended) .Prop(_SC("Terminated"), &Routine::GetTerminated) .Prop(_SC("Callback"), &Routine::GetCallback) - /* Functions */ + // Functions .Func(_SC("SetTag"), &Routine::ApplyTag) .Func(_SC("SetData"), &Routine::ApplyData) .Func(_SC("Terminate"), &Routine::Terminate) @@ -981,32 +934,25 @@ void Register_Routine(HSQUIRRELVM vm) .Func(_SC("GetArg"), &Routine::GetArg) .Func(_SC("SetArg"), &Routine::SetArg) // Static Functions - .StaticFunc(_SC("Flush"), &Routine::Flush) - .StaticFunc(_SC("QueueSize"), &Routine::QueueSize) - .StaticFunc(_SC("Count"), &Routine::GetCount) - .StaticFunc(_SC("Buckets"), &Routine::GetBuckets) - .StaticFunc(_SC("InBucket"), &Routine::GetInBucket) - .StaticFunc(_SC("BucketsList"), &Routine::GetBucketsList) - .StaticFunc(_SC("BucketsTable"), &Routine::GetBucketsTable) .StaticFunc(_SC("FindByTag"), &Routine::FindByTag) // Static Overloads .StaticOverload< Object (*)(Object &, Function &, Routine::Interval) > (_SC("Create"), &Routine::Create) - .StaticOverload< Object (*)(Object &, Function &, Routine::Interval, Routine::Iterate) > + .StaticOverload< Object (*)(Object &, Function &, Routine::Interval, Routine::Iterator) > (_SC("Create"), &Routine::Create) - .StaticOverload< Object (*)(Object &, Function &, Routine::Interval, Routine::Iterate, + .StaticOverload< Object (*)(Object &, Function &, Routine::Interval, Routine::Iterator, Object &) > (_SC("Create"), &Routine::Create) - .StaticOverload< Object (*)(Object &, Function &, Routine::Interval, Routine::Iterate, + .StaticOverload< Object (*)(Object &, Function &, Routine::Interval, Routine::Iterator, Object &, Object &) > (_SC("Create"), &Routine::Create) - .StaticOverload< Object (*)(Object &, Function &, Routine::Interval, Routine::Iterate, + .StaticOverload< Object (*)(Object &, Function &, Routine::Interval, Routine::Iterator, Object &, Object &, Object &) > (_SC("Create"), &Routine::Create) - .StaticOverload< Object (*)(Object &, Function &, Routine::Interval, Routine::Iterate, + .StaticOverload< Object (*)(Object &, Function &, Routine::Interval, Routine::Iterator, Object &, Object &, Object &, Object &) > (_SC("Create"), &Routine::Create) - .StaticOverload< Object (*)(Object &, Function &, Routine::Interval, Routine::Iterate, + .StaticOverload< Object (*)(Object &, Function &, Routine::Interval, Routine::Iterator, Object &, Object &, Object &, Object &, Object &) > (_SC("Create"), &Routine::Create) ); diff --git a/source/Routine.hpp b/source/Routine.hpp index 6782fe4d..7ad39bf4 100644 --- a/source/Routine.hpp +++ b/source/Routine.hpp @@ -5,8 +5,9 @@ #include "Base/Shared.hpp" // ------------------------------------------------------------------------------------------------ -#include -#include +#include +#include +#include // ------------------------------------------------------------------------------------------------ namespace SqMod { @@ -21,183 +22,37 @@ public: /* -------------------------------------------------------------------------------------------- * Simplify future changes to a single point of change. */ - typedef SQInteger Interval; - typedef Uint32 Iterate; - typedef std::vector< Routine * > Routines; + typedef Int64 Time; + typedef SQInteger Interval; + typedef Uint32 Iterator; + typedef std::pair< Interval, Routine * > Element; + typedef std::array< Element, SQMOD_MAX_ROUTINES > Routines; + typedef std::unordered_map< Routine *, Object > Objects; /* -------------------------------------------------------------------------------------------- * Process all active routines and update elapsed time. */ static void Process(); + /* -------------------------------------------------------------------------------------------- + * Initialize all resources and prepare for startup. + */ + static void Initialize(); + /* -------------------------------------------------------------------------------------------- * Release all resources and prepare for shutdown. */ - static void TerminateAll(); + static void Deinitialize(); protected: - /* -------------------------------------------------------------------------------------------- - * Commands that can be performed when the buckets are unlocked. - */ - enum - { - CMD_REMOVE = 1, - CMD_DETACH = 2, - CMD_ATTACH = 3 - }; - - /* -------------------------------------------------------------------------------------------- - * Group of routines that have the same interval. - */ - struct Bucket - { - // ---------------------------------------------------------------------------------------- - Interval mInterval; /* The interval of time between calls. */ - Interval mElapsed; /* Time elapsed since the last pulse. */ - Routines mRoutines; /* Routines to trigger on completion. */ - - /* ---------------------------------------------------------------------------------------- - * Default constructor. - */ - Bucket(Interval interval) - : mInterval(interval), mElapsed(0), mRoutines() - { - /* ... */ - } - - /* ---------------------------------------------------------------------------------------- - * Copy constructor. - */ - Bucket(const Bucket & o) = default; - - /* ---------------------------------------------------------------------------------------- - * Move constructor. - */ - Bucket(Bucket && o) = default; - - /* ---------------------------------------------------------------------------------------- - * Destructor. - */ - ~Bucket() = default; - - /* ---------------------------------------------------------------------------------------- - * Copy assignment operator. - */ - Bucket & operator = (const Bucket & o) = default; - - /* ---------------------------------------------------------------------------------------- - * Move assignment operator. - */ - Bucket & operator = (Bucket && o) = default; - }; - - /* -------------------------------------------------------------------------------------------- - * A command to perform certain actions when the buckets are unlocked. - */ - struct Cmd - { - // ---------------------------------------------------------------------------------------- - Routine* mRoutine; /* The routine to which this command applies */ - Interval mInterval; /* The bucket where this routine is stored. */ - Uint16 mCommand; /* The command that must be performed. */ - - /* ---------------------------------------------------------------------------------------- - * Base constructor. - */ - Cmd(Routine * routine, Interval interval, Uint16 command) - : mRoutine(routine), mInterval(interval), mCommand(command) - { - /* ... */ - } - - /* ---------------------------------------------------------------------------------------- - * Copy constructor. - */ - Cmd(const Cmd & o) = default; - - /* ---------------------------------------------------------------------------------------- - * Move constructor. - */ - Cmd(Cmd && o) = default; - - /* ---------------------------------------------------------------------------------------- - * Destructor. - */ - ~Cmd() = default; - - /* ---------------------------------------------------------------------------------------- - * Copy assignment operator. - */ - Cmd & operator = (const Cmd & o) = default; - - /* ---------------------------------------------------------------------------------------- - * Move assignment operator. - */ - Cmd & operator = (Cmd && o) = default; - }; - // -------------------------------------------------------------------------------------------- - typedef Int64 Time; - typedef std::vector< Cmd > Queue; - typedef std::vector< Bucket > Buckets; - typedef std::unordered_map< Routine *, Object > Objects; + static Time s_Last; // Last time point. + static Time s_Prev; // Previous time point. + static Routines s_Routines; // Buckets of routines grouped by similar intervals. + static Objects s_Objects; // List of existing routines and their associated object. - /* -------------------------------------------------------------------------------------------- - * Functor used to search for buckets with a certain interval. - */ - struct IntrvFunc - { - private: - - // ---------------------------------------------------------------------------------------- - const Interval m_Interval; /* The interval to be matched. */ - - public: - - /* ---------------------------------------------------------------------------------------- - * Base constructor. - */ - IntrvFunc(Interval interval) - : m_Interval(interval) - { - /* ... */ - } - - /* ---------------------------------------------------------------------------------------- - * Function call operator. - */ - bool operator () (Buckets::reference elem) const - { - return (elem.mInterval == m_Interval); - } - - /* ---------------------------------------------------------------------------------------- - * Function call operator. - */ - bool operator () (Buckets::const_reference elem) const - { - return (elem.mInterval == m_Interval); - } - }; - - // -------------------------------------------------------------------------------------------- - static bool s_Lock; /* Avoid further changes to the bucket pool. */ - static Time s_Last; /* Last time point. */ - static Time s_Prev; /* Previous time point. */ - static Queue s_Queue; /* Actions to be performed when the buckets aren't locked */ - static Buckets s_Buckets; /* Buckets of routines grouped by similar intervals. */ - static Objects s_Objects; /* List of existing routines and their associated object. */ - - /* -------------------------------------------------------------------------------------------- - * Attach a routine to a certain bucket. - */ - static void Attach(Routine * routine, Interval interval); - - /* -------------------------------------------------------------------------------------------- - * Detach a routine from a certain bucket. - */ - static void Detach(Routine * routine, Interval interval); +protected: /* -------------------------------------------------------------------------------------------- * Create or locate the object for the specified routine and keep a strong reference to it. @@ -220,9 +75,24 @@ protected: static void Forget(Routine * routine); /* -------------------------------------------------------------------------------------------- - * Process queue commands. + * Insert a routine instance into the pool to be processed. */ - static void ProcQueue(); + static void Insert(Routine * routine, bool associate = true); + + /* -------------------------------------------------------------------------------------------- + * Insert a routine instance from the pool to not be processed. + */ + static void Remove(Routine * routine); + + /* -------------------------------------------------------------------------------------------- + * Release routine resources. + */ + void Release(); + + /* -------------------------------------------------------------------------------------------- + * Execute the binded callback. + */ + void Execute(); /* -------------------------------------------------------------------------------------------- * See whether this routine is valid otherwise throw an exception. @@ -245,73 +115,88 @@ private: /* -------------------------------------------------------------------------------------------- * Constructor with just an interval and explicit iterations. */ - Routine(Object & env, Function & func, Interval interval, Iterate iterations); + Routine(Object & env, Function & func, Interval interval, Iterator iterations); /* -------------------------------------------------------------------------------------------- * Constructor with just an interval, explicit iterations and arguments. */ - Routine(Object & env, Function & func, Interval interval, Iterate iterations + Routine(Object & env, Function & func, Interval interval, Iterator iterations , Object & a1); /* -------------------------------------------------------------------------------------------- * Constructor with just an interval, explicit iterations and arguments. */ - Routine(Object & env, Function & func, Interval interval, Iterate iterations + Routine(Object & env, Function & func, Interval interval, Iterator iterations , Object & a1, Object & a2); /* -------------------------------------------------------------------------------------------- * Constructor with just an interval, explicit iterations and arguments. */ - Routine(Object & env, Function & func, Interval interval, Iterate iterations + Routine(Object & env, Function & func, Interval interval, Iterator iterations , Object & a1, Object & a2, Object & a3); /* -------------------------------------------------------------------------------------------- * Constructor with just an interval, explicit iterations and arguments. */ - Routine(Object & env, Function & func, Interval interval, Iterate iterations + Routine(Object & env, Function & func, Interval interval, Iterator iterations , Object & a1, Object & a2, Object & a3, Object & a4); /* -------------------------------------------------------------------------------------------- * Constructor with just an interval, explicit iterations and arguments. */ - Routine(Object & env, Function & func, Interval interval, Iterate iterations + Routine(Object & env, Function & func, Interval interval, Iterator iterations , Object & a1, Object & a2, Object & a3, Object & a4, Object & a5); /* -------------------------------------------------------------------------------------------- * Copy constructor. (disabled) */ - Routine(const Routine &); + Routine(const Routine & o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Move constructor. (disabled) + */ + Routine(Routine && o) = delete; /* -------------------------------------------------------------------------------------------- * Copy assignment operator. (disabled) */ - Routine & operator = (const Routine &); + Routine & operator = (const Routine & o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Move assignment operator. (disabled) + */ + Routine & operator = (Routine && o) = delete; private: /* -------------------------------------------------------------------------------------------- * Number of iterations before self destruct. - */ - Iterate m_Iterations; + */ + Iterator m_Iterations; /* -------------------------------------------------------------------------------------------- * Interval between calls. - */ + */ Interval m_Interval; + /* -------------------------------------------------------------------------------------------- + * The index of the slot in the pool. + */ + Uint16 m_Slot; + /* -------------------------------------------------------------------------------------------- * Number of arguments to forward. - */ - Uint8 m_Arguments; + */ + Uint16 m_Arguments; /* -------------------------------------------------------------------------------------------- * Whether calls should be ignored. - */ + */ bool m_Suspended; /* -------------------------------------------------------------------------------------------- * Whether the routine was terminated. - */ + */ bool m_Terminated; /* -------------------------------------------------------------------------------------------- @@ -388,19 +273,34 @@ public: Routine & ApplyData(Object & data); /* -------------------------------------------------------------------------------------------- - * Terminate this routine by releasing all resources and scheduling it for detachment. + * Activate the routine instance. */ - void Terminate(); + Routine & Activate(); + + /* -------------------------------------------------------------------------------------------- + * Deactivate the routine instance. + */ + Routine & Deactivate(); + + /* -------------------------------------------------------------------------------------------- + * Terminate this routine by deactivating and releasing all resources. + */ + Routine & Terminate(); + + /* -------------------------------------------------------------------------------------------- + * Unmark this routine as terminated and allow to be activated. + */ + Routine & Reanimate(); /* -------------------------------------------------------------------------------------------- * Modify an explicit value to be passed as the specified argument. */ - Routine & SetArg(Uint8 num, Object & val); + Routine & SetArg(Uint16 num, Object & val); /* -------------------------------------------------------------------------------------------- * Retrieve the value that is passed as the specified argument. */ - Object & GetArg(Uint8 num); + Object & GetArg(Uint16 num); /* -------------------------------------------------------------------------------------------- * Retrieve the amount of time required to wait between calls to the routine. @@ -415,22 +315,22 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the number of times that the routine can be called before terminating itself. */ - Iterate GetIterations() const; + Iterator GetIterations() const; /* -------------------------------------------------------------------------------------------- * Modify the number of times that the routine can be called before terminating itself. */ - void SetIterations(Iterate iterations); + void SetIterations(Iterator iterations); /* -------------------------------------------------------------------------------------------- * Retrieve the number of arguments that are forwarded when executing the callback. */ - Uint8 GetArguments() const; + Uint16 GetArguments() const; /* -------------------------------------------------------------------------------------------- * Modify the number of arguments that are forwarded when executing the callback. */ - void SetArguments(Uint8 num); + void SetArguments(Uint16 num); /* -------------------------------------------------------------------------------------------- * See whether the routine is suspended from further calls. @@ -457,33 +357,6 @@ public: */ void SetCallback(Object & env, Function & func); -protected: - - /* -------------------------------------------------------------------------------------------- - * Release routine resources. - */ - void Release(); - - /* -------------------------------------------------------------------------------------------- - * Create the routine for the first time. - */ - void Create(); - - /* -------------------------------------------------------------------------------------------- - * Attach the routine to the associated bucket. - */ - void Attach(); - - /* -------------------------------------------------------------------------------------------- - * Attach the routine from the associated bucket. - */ - void Detach(); - - /* -------------------------------------------------------------------------------------------- - * Execute the binded callback. - */ - void Execute(); - public: /* -------------------------------------------------------------------------------------------- @@ -494,78 +367,42 @@ public: /* -------------------------------------------------------------------------------------------- * Create a routine with just an interval and explicit iterations. */ - static Object Create(Object & env, Function & func, Interval interval, Iterate iterations); + static Object Create(Object & env, Function & func, Interval interval, Iterator iterations); /* -------------------------------------------------------------------------------------------- * Create a routine with just an interval, explicit iterations and arguments. */ - static Object Create(Object & env, Function & func, Interval interval, Iterate iterations + static Object Create(Object & env, Function & func, Interval interval, Iterator iterations , Object & a1); /* -------------------------------------------------------------------------------------------- * Create a routine with just an interval, explicit iterations and arguments. */ - static Object Create(Object & env, Function & func, Interval interval, Iterate iterations + static Object Create(Object & env, Function & func, Interval interval, Iterator iterations , Object & a1, Object & a2); /* -------------------------------------------------------------------------------------------- * Create a routine with just an interval, explicit iterations and arguments. */ - static Object Create(Object & env, Function & func, Interval interval, Iterate iterations + static Object Create(Object & env, Function & func, Interval interval, Iterator iterations , Object & a1, Object & a2, Object & a3); /* -------------------------------------------------------------------------------------------- * Create a routine with just an interval, explicit iterations and arguments. */ - static Object Create(Object & env, Function & func, Interval interval, Iterate iterations + static Object Create(Object & env, Function & func, Interval interval, Iterator iterations , Object & a1, Object & a2, Object & a3, Object & a4); /* -------------------------------------------------------------------------------------------- * Create a routine with just an interval, explicit iterations and arguments. */ - static Object Create(Object & env, Function & func, Interval interval, Iterate iterations + static Object Create(Object & env, Function & func, Interval interval, Iterator iterations , Object & a1, Object & a2, Object & a3, Object & a4, Object & a5); - /* -------------------------------------------------------------------------------------------- - * Flush queued commands manually. - */ - static void Flush(); - - /* -------------------------------------------------------------------------------------------- - * Return the number of queued commands. - */ - static Uint32 QueueSize(); - - /* -------------------------------------------------------------------------------------------- - * Return the number of known routines. - */ - static Uint32 GetCount(); - - /* -------------------------------------------------------------------------------------------- - * Return the number of known buckets. - */ - static Uint32 GetBuckets(); - - /* -------------------------------------------------------------------------------------------- - * Return the number of known routines in bucket. - */ - static Uint32 GetInBucket(Interval interval); - - /* -------------------------------------------------------------------------------------------- - * Return the number of known buckets. - */ - static Array GetBucketsList(); - - /* -------------------------------------------------------------------------------------------- - * Return the number of known buckets. - */ - static Table GetBucketsTable(); - /* -------------------------------------------------------------------------------------------- * Attempt to find a certain routine by its associated tag. */ static Object FindByTag(CSStr tag); - }; } // Namespace:: SqMod diff --git a/source/SqBase.hpp b/source/SqBase.hpp index c050d2c0..2bb31ba5 100644 --- a/source/SqBase.hpp +++ b/source/SqBase.hpp @@ -111,8 +111,8 @@ */ #define SQMOD_NAME "Squirrel Module" -#define SQMOD_AUTHOR "Sandu Liviu Catalin" -#define SQMOD_COPYRIGHT "Copyright (C) 2015 Sandu Liviu Catalin" +#define SQMOD_AUTHOR "Sandu Liviu Catalin (S.L.C)" +#define SQMOD_COPYRIGHT "Copyright (C) 2016 Sandu Liviu Catalin" #define SQMOD_HOST_NAME "SqModHost" #define SQMOD_VERSION 001 #define SQMOD_VERSION_STR "0.0.1" @@ -123,6 +123,7 @@ /* ------------------------------------------------------------------------------------------------ * SQUIRREL FORWARD DECLARATIONS */ + extern "C" { typedef struct tagSQObject SQObject; struct SQVM; @@ -133,6 +134,7 @@ extern "C" { /* ------------------------------------------------------------------------------------------------ * SQRAT FORWARD DECLARATIONS */ + namespace Sqrat { class Array; class Object; @@ -204,6 +206,7 @@ typedef Uint32 SizeT; /* ------------------------------------------------------------------------------------------------ * STRING TYPE */ + typedef std::basic_string String; typedef char * CStr; @@ -215,6 +218,7 @@ typedef const SQChar * CSStr; /* ------------------------------------------------------------------------------------------------ * SHORT SQUIRREL TYPENAMES */ + typedef SQUnsignedInteger32 SQUint32; typedef SQUnsignedInteger SQUint; typedef SQInteger SQInt; @@ -222,6 +226,12 @@ typedef SQInteger SQInt; // ------------------------------------------------------------------------------------------------ using namespace Sqrat; +/* ------------------------------------------------------------------------------------------------ + * Squirrel compatible stl string. +*/ + +typedef std::basic_string< SQChar > String; + /* ------------------------------------------------------------------------------------------------ * FORWARD DECLARATIONS */ @@ -265,217 +275,62 @@ template < typename T > class LongInt; typedef LongInt< Int64 > SLongInt; typedef LongInt< Uint64 > ULongInt; -/* ------------------------------------------------------------------------------------------------ - * ... -*/ -typedef std::basic_string< SQChar > String; - -#ifdef _DEBUG - -/* ------------------------------------------------------------------------------------------------ - * A simple managed pointer used to identify if components are still used after shutdown. -*/ -template < typename T > class ManagedPtr -{ -private: - - T * m_Ptr; - -public: - - /* -------------------------------------------------------------------------------------------- - * Base constructor. - */ - ManagedPtr(T * ptr) - : m_Ptr(ptr) - { - /* ... */ - } - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. (disabled) - */ - ManagedPtr(const ManagedPtr & o) = delete; - - /* -------------------------------------------------------------------------------------------- - * Move constructor. (disabled) - */ - ManagedPtr(ManagedPtr && o) - : m_Ptr(o.m_Ptr) - { - o.m_Ptr = nullptr; - } - - /* -------------------------------------------------------------------------------------------- - * Destructor. - */ - ~ManagedPtr() - { - if (m_Ptr) - { - delete m_Ptr; - } - } - - /* -------------------------------------------------------------------------------------------- - * Copy assignment operator. (disabled) - */ - ManagedPtr & operator = (const ManagedPtr & o) = delete; - - /* -------------------------------------------------------------------------------------------- - * Move assignment operator. (disabled) - */ - ManagedPtr & operator = (ManagedPtr && o) - { - if (m_Ptr != o.m_Ptr) - { - if (m_Ptr) - { - delete m_Ptr; - } - m_Ptr = o.m_Ptr; - o.m_Ptr = nullptr; - } - return *this; - } - - /* -------------------------------------------------------------------------------------------- - * Implicit conversion to boolean for use in boolean operations. - */ - operator bool () const - { - return m_Ptr; - } - - /* -------------------------------------------------------------------------------------------- - * Implicit conversion to the managed pointer type. - */ - operator T * () const - { - return m_Ptr; - } - - /* -------------------------------------------------------------------------------------------- - * Implicit conversion to the managed pointer type. - */ - operator const T * () const - { - return m_Ptr; - } - - /* -------------------------------------------------------------------------------------------- - * Member operator for dereferencing the managed pointer. - */ - T * operator -> () const - { - assert(m_Ptr != nullptr); - return m_Ptr; - } - - /* -------------------------------------------------------------------------------------------- - * Indirection operator for obtaining a reference of the managed pointer. - */ - T & operator * () const - { - assert(m_Ptr != nullptr); - return *m_Ptr; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the managed pointer in it's raw form. - */ - T * Get() const - { - return m_Ptr; - } - -}; - -#define SQMOD_MANAGEDPTR_TYPE(t) ManagedPtr< t > -#define SQMOD_MANAGEDPTR_REF(t) ManagedPtr< t > & -#define SQMOD_MANAGEDPTR_MAKE(t, p) ManagedPtr< t >(p) -#define SQMOD_MANAGEDPTR_DEL(t, p) p = ManagedPtr< t >(nullptr) -#define SQMOD_MANAGEDPTR_GET(p) p.Get(); - -#else - -#define SQMOD_MANAGEDPTR_TYPE(t) t * -#define SQMOD_MANAGEDPTR_REF(t) t * -#define SQMOD_MANAGEDPTR_MAKE(t, p) p -#define SQMOD_MANAGEDPTR_DEL(t, p) delete p -#define SQMOD_MANAGEDPTR_GET(p) p - -#endif // _DEBUG +// ------------------------------------------------------------------------------------------------ +class BufferWrapper; /* ------------------------------------------------------------------------------------------------ * FORWARD DECLARATIONS */ + enum EventType { EVT_UNKNOWN = 0, + EVT_CUSTOMEVENT, EVT_BLIPCREATED, EVT_CHECKPOINTCREATED, - EVT_FORCEFIELDCREATED, EVT_KEYBINDCREATED, EVT_OBJECTCREATED, EVT_PICKUPCREATED, EVT_PLAYERCREATED, - EVT_SPRITECREATED, - EVT_TEXTDRAWCREATED, EVT_VEHICLECREATED, EVT_BLIPDESTROYED, EVT_CHECKPOINTDESTROYED, - EVT_FORCEFIELDDESTROYED, EVT_KEYBINDDESTROYED, EVT_OBJECTDESTROYED, EVT_PICKUPDESTROYED, EVT_PLAYERDESTROYED, - EVT_SPRITEDESTROYED, - EVT_TEXTDRAWDESTROYED, EVT_VEHICLEDESTROYED, EVT_BLIPCUSTOM, EVT_CHECKPOINTCUSTOM, - EVT_FORCEFIELDCUSTOM, EVT_KEYBINDCUSTOM, EVT_OBJECTCUSTOM, EVT_PICKUPCUSTOM, EVT_PLAYERCUSTOM, - EVT_SPRITECUSTOM, - EVT_TEXTDRAWCUSTOM, EVT_VEHICLECUSTOM, - EVT_PLAYERAWAY, - EVT_PLAYERGAMEKEYS, - EVT_PLAYERRENAME, + EVT_SERVERSTARTUP, + EVT_SERVERSHUTDOWN, + EVT_SERVERFRAME, + EVT_INCOMINGCONNECTION, EVT_PLAYERREQUESTCLASS, EVT_PLAYERREQUESTSPAWN, EVT_PLAYERSPAWN, - EVT_PLAYERSTARTTYPING, - EVT_PLAYERSTOPTYPING, - EVT_PLAYERCHAT, - EVT_PLAYERCOMMAND, - EVT_PLAYERMESSAGE, - EVT_PLAYERHEALTH, - EVT_PLAYERARMOUR, - EVT_PLAYERWEAPON, - EVT_PLAYERMOVE, EVT_PLAYERWASTED, EVT_PLAYERKILLED, - EVT_PLAYERTEAMKILL, - EVT_PLAYERSPECTATE, - EVT_PLAYERCRASHREPORT, - EVT_PLAYERBURNING, - EVT_PLAYERCROUCHING, + EVT_PLAYEREMBARKING, + EVT_PLAYEREMBARKED, + EVT_PLAYERDISEMBARK, + EVT_PLAYERRENAME, EVT_PLAYERSTATE, - EVT_PLAYERACTION, EVT_STATENONE, EVT_STATENORMAL, - EVT_STATESHOOTING, + EVT_STATEAIM, EVT_STATEDRIVER, EVT_STATEPASSENGER, EVT_STATEENTERDRIVER, EVT_STATEENTERPASSENGER, - EVT_STATEEXITVEHICLE, + EVT_STATEEXIT, EVT_STATEUNSPAWNED, + EVT_PLAYERACTION, EVT_ACTIONNONE, EVT_ACTIONNORMAL, EVT_ACTIONAIMING, @@ -489,32 +344,44 @@ enum EventType EVT_ACTIONWASTED, EVT_ACTIONEMBARKING, EVT_ACTIONDISEMBARKING, - EVT_VEHICLERESPAWN, + EVT_PLAYERBURNING, + EVT_PLAYERCROUCHING, + EVT_PLAYERGAMEKEYS, + EVT_PLAYERSTARTTYPING, + EVT_PLAYERSTOPTYPING, + EVT_PLAYERAWAY, + EVT_PLAYERMESSAGE, + EVT_PLAYERCOMMAND, + EVT_PLAYERPRIVATEMESSAGE, + EVT_PLAYERKEYPRESS, + EVT_PLAYERKEYRELEASE, + EVT_PLAYERSPECTATE, + EVT_PLAYERCRASHREPORT, EVT_VEHICLEEXPLODE, - EVT_VEHICLEHEALTH, - EVT_VEHICLEMOVE, - EVT_PICKUPRESPAWN, - EVT_KEYBINDKEYPRESS, - EVT_KEYBINDKEYRELEASE, - EVT_VEHICLEEMBARKING, - EVT_VEHICLEEMBARKED, - EVT_VEHICLEDISEMBARK, + EVT_VEHICLERESPAWN, + EVT_OBJECTSHOT, + EVT_OBJECTTOUCHED, EVT_PICKUPCLAIMED, EVT_PICKUPCOLLECTED, - EVT_OBJECTSHOT, - EVT_OBJECTBUMP, + EVT_PICKUPRESPAWN, EVT_CHECKPOINTENTERED, EVT_CHECKPOINTEXITED, - EVT_FORCEFIELDENTERED, - EVT_FORCEFIELDEXITED, - EVT_SERVERFRAME, - EVT_SERVERSTARTUP, - EVT_SERVERSHUTDOWN, - EVT_INTERNALCOMMAND, - EVT_LOGINATTEMPT, - EVT_CUSTOMEVENT, - EVT_WORLDOPTION, - EVT_WORLDTOGGLE, + EVT_ENTITYPOOL, + EVT_CLIENTSCRIPTDATA, + EVT_PLAYERUPDATE, + EVT_VEHICLEUPDATE, + EVT_PLAYERHEALTH, + EVT_PLAYERARMOUR, + EVT_PLAYERWEAPON, + EVT_PLAYERHEADING, + EVT_PLAYERPOSITION, + EVT_PLAYEROPTION, + EVT_VEHICLECOLOUR, + EVT_VEHICLEHEALTH, + EVT_VEHICLEPOSITION, + EVT_VEHICLEROTATION, + EVT_VEHICLEOPTION, + EVT_SERVEROPTION, EVT_SCRIPTRELOAD, EVT_SCRIPTLOADED, EVT_MAX @@ -730,13 +597,10 @@ enum CmdError #define SQMOD_BLIP_POOL 128 #define SQMOD_CHECKPOINT_POOL 2000 -#define SQMOD_FORCEFIELD_POOL 2000 #define SQMOD_KEYBIND_POOL 256 #define SQMOD_OBJECT_POOL 3000 #define SQMOD_PICKUP_POOL 2000 #define SQMOD_PLAYER_POOL 100 -#define SQMOD_SPRITE_POOL 128 -#define SQMOD_TEXTDRAW_POOL 256 #define SQMOD_VEHICLE_POOL 1000 /* ------------------------------------------------------------------------------------------------ @@ -779,36 +643,11 @@ enum CmdError */ #define SQMOD_STACK_SIZE 2048 +#define SQMOD_MAX_ROUTINES 1024 #define SQMOD_MAX_CMD_ARGS 12 #define SQMOD_PLAYER_MSG_PREFIXES 16 #define SQMOD_PLAYER_TMP_BUFFER 128 -/* ------------------------------------------------------------------------------------------------ - * ENTITY POOL UPDATE IDENTIFIERS -*/ -#define SQMOD_ENTITY_POOL_VEHICLE 1 -#define SQMOD_ENTITY_POOL_OBJECT 2 -#define SQMOD_ENTITY_POOL_PICKUP 3 -#define SQMOD_ENTITY_POOL_RADIO 4 -#define SQMOD_ENTITY_POOL_SPRITE 5 -#define SQMOD_ENTITY_POOL_TEXTDRAW 6 -#define SQMOD_ENTITY_POOL_BLIP 7 -#define SQMOD_ENTITY_POOL_MAX 8 - -/* ------------------------------------------------------------------------------------------------ - * PLAYER STATE IDENTIFIERS -*/ -#define SQMOD_PLAYER_STATE_NONE 0 -#define SQMOD_PLAYER_STATE_NORMAL 1 -#define SQMOD_PLAYER_STATE_SHOOTING 2 -#define SQMOD_PLAYER_STATE_DRIVER 3 -#define SQMOD_PLAYER_STATE_PASSENGER 4 -#define SQMOD_PLAYER_STATE_ENTERING_AS_DRIVER 5 -#define SQMOD_PLAYER_STATE_ENTERING_AS_PASSENGER 6 -#define SQMOD_PLAYER_STATE_EXITING_VEHICLE 7 -#define SQMOD_PLAYER_STATE_UNSPAWNED 8 -#define SQMOD_PLAYER_STATE_MAX 9 - /* ------------------------------------------------------------------------------------------------ * PLAYER ACTION IDENTIFIERS */ @@ -827,43 +666,6 @@ enum CmdError #define SQMOD_PLAYER_ACTION_EXITING_VEHICLE 60 #define SQMOD_PLAYER_ACTION_MAX 61 -/* ------------------------------------------------------------------------------------------------ - * VEHICLE UPDATE IDENTIFIERS -*/ -#define SQMOD_VEHICLEUPD_DRIVER 0 -#define SQMOD_VEHICLEUPD_OTHER 1 -#define SQMOD_VEHICLEUPD_MAX 2 - -/* ------------------------------------------------------------------------------------------------ - * PLAYER UPDATE IDENTIFIERS -*/ -#define SQMOD_PLAYERUPD_ONFOOT 0 -#define SQMOD_PLAYERUPD_AIM 1 -#define SQMOD_PLAYERUPD_DRIVER 2 -#define SQMOD_PLAYERUPD_PASSENGER 3 -#define SQMOD_PLAYERUPD_MAX 4 - -/* ------------------------------------------------------------------------------------------------ - * PART REASON IDENTIFIERS -*/ -#define SQMOD_PARTREASON_TIMEOUT 0 -#define SQMOD_PARTREASON_DISCONNECTED 1 -#define SQMOD_PARTREASON_KICKEDBANNED 2 -#define SQMOD_PARTREASON_CRASHED 3 -#define SQMOD_PARTREASON_MAX 4 - -/* ------------------------------------------------------------------------------------------------ - * BODY PART IDENTIFIERS -*/ -#define SQMOD_BODYPART_BODY 0 -#define SQMOD_BODYPART_TORSO 1 -#define SQMOD_BODYPART_LEFTARM 2 -#define SQMOD_BODYPART_RIGHTARM 3 -#define SQMOD_BODYPART_LEFTLEG 4 -#define SQMOD_BODYPART_RIGHTLEG 5 -#define SQMOD_BODYPART_HEAD 6 -#define SQMOD_BODYPART_MAX 7 - /* ------------------------------------------------------------------------------------------------ * WEATHER IDENTIFIERS */