y_compilerdata.inc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. #if defined _INC_y_compilerdata
  2. #endinput
  3. #endif
  4. #define _INC_y_compilerdata
  5. /**
  6. <!--
  7. <transition target[^/]+/>
  8. :::::::: README ::::::::
  9. To read the generated XML output, copy `pawndoc.xsl` to `pawno/xml/`.
  10. This information goes very close to the top of the generated XML documentation
  11. (because of include dependency orders), but doesn't appear in the visual output.
  12. There is a bug in the compiler related to outputting documentation on state
  13. transitions (<a href="https://github.com/Zeex/pawn/issues/184" />). So after
  14. generation of the XML file, you should clean it up with the following RegEx
  15. replacement:
  16. Search: <transition target[^/]+/>
  17. Replace: (nothing)
  18. This works 99% of the time, though you may get one where the corrupted target
  19. includes the character `/`, in which case you should manually delete them. Note
  20. that YSI now includes manual documentation for transitions, but these all
  21. include the parameter `keep="true"`, which exists simply to not match that
  22. RegEx. I also put the search at the top of this block so it is easier to find
  23. in the output code.
  24. -->
  25. *//*+
  26. * <library name="y_compilerdata">
  27. * <section>
  28. * Description
  29. * </section>
  30. * Detect various information about the compiler, including which pass it is
  31. * currently executing, what flags it was compiled with, and which version it
  32. * is. Provide that information to the rest of the script through a series of
  33. * consistent macros. Used by y_groups to include code that might be needed
  34. * before it is known if it is needed (it can be dumped later).
  35. * <section>
  36. * Version
  37. * </section>
  38. * 0.1
  39. * <section>
  40. * Functions
  41. * </section>
  42. * <subsection>
  43. * Static
  44. * </subsection><ul>
  45. * <symbol name="__CompilerStringReturn">
  46. * Assembly for returning a string to its callers' caller. Used to
  47. * bypass a known bug.</symbol>
  48. * <symbol name="__CompilerSecondPass">Tested to determine the current compiler pass.</symbol>
  49. * </ul><subsection>
  50. * Inline
  51. * </subsection><ul>
  52. * <symbol name="__COMPILER_STRING_RETURN">Correctly return a string from a varargs function.</symbol>
  53. * </ul><section>
  54. * Macros
  55. * </section><ul>
  56. * <symbol name="__COMPILER_PASS">Which pass the compiler is currently running.</li><to_ul></symbol>
  57. * <symbol name="__COMPILER_DOCUMENTING">Is the compiler collecting documentation
  58. * information right now (i.e. is this the first pass)?</symbol>
  59. * <symbol name="__COMPILER_1ST_PASS">Is this the first compiler pass?</symbol>
  60. * <symbol name="__COMPILER_2ND_PASS">Is this the second compiler pass?</symbol>
  61. * <symbol name="__COMPILER_FIRST_PASS">Is this the first compiler pass?</symbol>
  62. * <symbol name="__COMPILER_SECOND_PASS">Is this the second compiler pass?</symbol>
  63. * <symbol name="__COMPILER_MODIFIED">Is the compiler an updated/unofficial/modified one?</symbol>
  64. * <symbol name="__COMPILER_OFFICIAL">Is the compiler an official one?</symbol>
  65. * <symbol name="__COMPILER_COMPAT">Was the compiler built with `-Z`?</symbol>
  66. * <symbol name="__COMPILER_INCLUDE_GUARDS">Does the compiler generate auto-include guards?</symbol>
  67. * <symbol name="__COMPILER_NESTED_ELLIPSIS">Does the compiler support nested ellipses?</symbol>
  68. * <symbol name="__COMPILER_BUGGED_STRING_RETURN">
  69. * Are vararg function string returns bugged? Not needed for using
  70. * <symbolref name="__COMPILER_STRING_RETURN" />, as that will do the best
  71. * thing in both cases already.</symbol>
  72. * <symbol name="P:D">Wrap a fake function declaration, so macros can be documented.</symbol>
  73. * </ul>
  74. * </library>
  75. *//** *//*
  76. Legal:
  77. Version: MPL 1.1
  78. The contents of this file are subject to the Mozilla Public License Version
  79. 1.1 the "License"; you may not use this file except in compliance with
  80. the License. You may obtain a copy of the License at
  81. http://www.mozilla.org/MPL/
  82. Software distributed under the License is distributed on an "AS IS" basis,
  83. WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  84. for the specific language governing rights and limitations under the
  85. License.
  86. The Original Code is the YSI framework.
  87. The Initial Developer of the Original Code is Alex "Y_Less" Cole.
  88. Portions created by the Initial Developer are Copyright C 2011
  89. the Initial Developer. All Rights Reserved.
  90. Contributors:
  91. Y_Less
  92. koolk
  93. JoeBullet/Google63
  94. g_aSlice/Slice
  95. Misiur
  96. samphunter
  97. tianmeta
  98. maddinat0r
  99. spacemud
  100. Crayder
  101. Dayvison
  102. Ahmad45123
  103. Zeex
  104. irinel1996
  105. Yiin-
  106. Chaprnks
  107. Konstantinos
  108. Masterchen09
  109. Southclaws
  110. PatchwerkQWER
  111. m0k1
  112. paulommu
  113. udan111
  114. Thanks:
  115. JoeBullet/Google63 - Handy arbitrary ASM jump code using SCTRL.
  116. ZeeX - Very productive conversations.
  117. koolk - IsPlayerinAreaEx code.
  118. TheAlpha - Danish translation.
  119. breadfish - German translation.
  120. Fireburn - Dutch translation.
  121. yom - French translation.
  122. 50p - Polish translation.
  123. Zamaroht - Spanish translation.
  124. Los - Portuguese translation.
  125. Dracoblue, sintax, mabako, Xtreme, other coders - Producing other modes for
  126. me to strive to better.
  127. Pixels^ - Running XScripters where the idea was born.
  128. Matite - Pestering me to release it and using it.
  129. Very special thanks to:
  130. Thiadmer - PAWN, whose limits continue to amaze me!
  131. Kye/Kalcor - SA:MP.
  132. SA:MP Team past, present and future - SA:MP.
  133. Optional plugins:
  134. Gamer_Z - GPS.
  135. Incognito - Streamer.
  136. Me - sscanf2, fixes2, Whirlpool.
  137. */
  138. // The macros `P:C` and `P:#` don't work without this.
  139. #pragma semicolon 1
  140. // Die tabsize 0!
  141. #pragma tabsize 4
  142. #define tabsize%00%0\10;%0 _DUMMY_do_not_use_tabsize_0
  143. // Enable `P:D(func())` for forcing function-like macros in to documentation.
  144. // For example:
  145. //
  146. // /**
  147. // * <param name="playerid">An example named macro parameter (`%0`).</param>
  148. // * <remarks>
  149. // * This is a function-like macro. By default, compiling with `-r` does
  150. // * not put macros in the XML, which is a shame if we are using a macro to
  151. // * fake a function, because then a function will be apparently missing
  152. // * from the documentation. Instead, we make a function, THEN make the
  153. // * macro. But, importantly, we only make the function on the first pass,
  154. // * not the second pass (documentation is apparently generated in the first
  155. // * pass).
  156. // * </remarks>
  157. // * <example>
  158. // *
  159. // * for (new i = 0; MyFunc(i); ++i)
  160. // * {
  161. // * printf("%d", i);
  162. // * }
  163. // *
  164. // * </example>
  165. // */
  166. // P:D(bool:MyFunc(playerid));
  167. // #define MyFunc(%0) ((%0) < MAX_PLAYERS)
  168. //
  169. #define P:%1(%2); Debug_Print%1(%2);
  170. #define C:%1(%2); Debug_Code%1(%2);
  171. #if defined __CompilerSecondPass
  172. #define __COMPILER_PASS (1)
  173. #define __COMPILER_DOCUMENTING (0)
  174. #else
  175. #define __COMPILER_PASS (0)
  176. #define __COMPILER_DOCUMENTING (1)
  177. #endif
  178. #define __COMPILER_1ST_PASS (__COMPILER_PASS == (0))
  179. #define __COMPILER_2ND_PASS (__COMPILER_PASS == (1))
  180. #define __COMPILER_FIRST_PASS __COMPILER_1ST_PASS
  181. #define __COMPILER_SECOND_PASS __COMPILER_2ND_PASS
  182. /*-------------------------------------------------------------------------*//*+
  183. * <remarks>
  184. * Exists purely to be detected before it is used. If that check succeedes,
  185. * the compiler is on its second pass and already has a list of all functions.
  186. * </remarks>
  187. *//*------------------------------------------------------------------------**/
  188. static stock __CompilerSecondPass() {}
  189. #if __Pawn >= 0x0400
  190. #error YSI does not yet support PAWN 4.0
  191. #elseif __Pawn < 0x0300
  192. #error YSI does not yet support PAWN 2.0/1.0
  193. #endif
  194. #if ((__Pawn & 0x0F) >= 0x0A) || ((__Pawn & 0xF0) >= 0xA0)
  195. #define __COMPILER_MODIFIED (1)
  196. #define __COMPILER_OFFICIAL (0)
  197. #else
  198. #define __COMPILER_MODIFIED (0)
  199. #define __COMPILER_OFFICIAL (1)
  200. #endif
  201. #if __COMPILER_MODIFIED
  202. #if defined __compat
  203. #define __COMPILER_COMPAT (1)
  204. #else
  205. #define __COMPILER_COMPAT (0)
  206. #endif
  207. #else
  208. #define __COMPILER_COMPAT (0)
  209. #endif
  210. #if __COMPILER_OFFICIAL || __COMPILER_COMPAT
  211. #define __COMPILER_INCLUDE_GUARDS (1)
  212. #else
  213. #define __COMPILER_INCLUDE_GUARDS (0)
  214. #endif
  215. #if __COMPILER_1ST_PASS && __COMPILER_MODIFIED
  216. // Disable matching the resulting function against (most) macros that are
  217. // defined with the same name (since the whole point of this is to provide a
  218. // concrete implementation for documentation to see).
  219. #define Debug_PrintD(%1(%2)); %1 Debug_PrintD_OPEN %2 Debug_PrintD_CLOSE { return 0; }
  220. #else
  221. #define Debug_PrintD(%1);
  222. #endif
  223. #define Debug_PrintD_OPEN (
  224. #define Debug_PrintD_CLOSE )
  225. #if __COMPILER_MODIFIED
  226. #define __COMPILER_NESTED_ELLIPSIS (1)
  227. #define __compiler_one_string_parameter:%8(%0,%1) (%0)
  228. #define __COMPILER_STRING_RETURN(%0) return __compiler_one_string_parameter:(%0)
  229. #define __COMPILER_BUGGED_STRING_RETURN (0)
  230. // Disable the recursion warning in the Russian compiler (and the unknown
  231. // pragma warning in other compilers temporarily).
  232. #pragma warning push
  233. #pragma warning disable 207
  234. #pragma disablerecursion
  235. #pragma warning pop
  236. #else
  237. #define __COMPILER_NESTED_ELLIPSIS (0)
  238. #define __compiler_one_string_parameter:%8(%0,%1) (%0)
  239. #define __COMPILER_STRING_RETURN(%0) __CompilerStringReturn(%0);return (__compiler_one_string_parameter:(%0))
  240. #define __CompilerStringReturn("%0"%1);return%8(%8:(%3)) return $
  241. #define __COMPILER_BUGGED_STRING_RETURN (1)
  242. #include "y_funcinc"
  243. /*---------------------------------------------------------------------*//*+
  244. * <param name="str">String to return.</param>
  245. * <param name="size">Size of the string.</param>
  246. * <param name="dummy">Ignored parameter for raw string given sizes.</param>
  247. * <returns>
  248. * string
  249. * </returns>
  250. * <remarks>
  251. * The old compiler has a very annoying bug where returning a string from a
  252. * function that takes variable parameters will not work correctly. This
  253. * is because string returns are done with a secret extra parameter but it
  254. * is not correctly selected when the count is unknown or variable.
  255. * </remarks>
  256. *//*--------------------------------------------------------------------**/
  257. stock __CompilerStringReturn(const str[], size = sizeof (str), dummy = 0)
  258. {
  259. #pragma unused dummy
  260. #emit PUSH.S size // Push the first parameter.
  261. #emit PUSH.S str // Push the second parameter.
  262. #emit LOAD.S.alt 0 // Load the previous frame pointer.
  263. #emit MOVE.pri // Copy the pointer.
  264. #emit ADD.C 8 // Get the pointer to the parameter count.
  265. #emit LOAD.I // Load the parameter count.
  266. #emit ADD.C 12 // Adjust for the function header size.
  267. #emit ADD // Get the pointer to after the parameters.
  268. #emit LOAD.I // Load the pointer in the (secret) parameter.
  269. #emit PUSH.pri // Push the destination.
  270. #emit MOVE.alt // Make a copy of the pointer.
  271. #emit ZERO.pri // `pri = 0`.
  272. #emit STOR.I // Set the first cell of the target to NULL.
  273. #emit PUSH.C 12 // Push the parameters for `strcpy`.
  274. #emit SYSREQ.C strcat // Call `strcat`.
  275. #emit LOAD.S.pri 0 // Reload the previous frame pointer.
  276. #emit SCTRL 4 // Wipe out the stack.
  277. #emit SCTRL 5 // Wipe out the frame (go to parent context).
  278. #emit RETN // Return (now within the parent context).
  279. return 0;
  280. }
  281. #endif
  282. // Consistent naming of compiler defined values.
  283. #define __Line __line
  284. #define __File __file
  285. #define __Date __date
  286. #define __Time __time
  287. #define __Compat __compat
  288. #define __Emit __emit
  289. #define __CellBytes cellbytes
  290. #define __CellBits cellbits
  291. // And the other way
  292. #define __cellbytes cellbytes
  293. #define __cellbits cellbits
  294. #define __cell_bytes cellbytes
  295. #define __cell_bits cellbits
  296. #define __pawn __Pawn
  297. // Don't define `__PawnBuild` if it doesn't exist, but do create an alternate
  298. // symbol (with a consistent naming scheme) that always exists.
  299. #if defined __PawnBuild
  300. #define __pawn_build __PawnBuild
  301. #else
  302. #define __pawn_build 0
  303. #endif
  304. // Should be an inbuilt constant!
  305. #define cellbytes (cellbits / 8)