utils.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. /*
  2. * Version: MPL 1.1
  3. *
  4. * The contents of this file are subject to the Mozilla Public License Version
  5. * 1.1 (the "License"); you may not use this file except in compliance with
  6. * the License. You may obtain a copy of the License at
  7. * http://www.mozilla.org/MPL/
  8. *
  9. * Software distributed under the License is distributed on an "AS IS" basis,
  10. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11. * for the specific language governing rights and limitations under the
  12. * License.
  13. *
  14. * The Original Code is the sscanf 2.0 SA:MP plugin.
  15. *
  16. * The Initial Developer of the Original Code is Alex "Y_Less" Cole.
  17. * Portions created by the Initial Developer are Copyright (C) 2010
  18. * the Initial Developer. All Rights Reserved.
  19. *
  20. * Contributor(s):
  21. *
  22. * Special Thanks to:
  23. *
  24. * SA:MP Team past, present and future
  25. */
  26. #include "utils.h"
  27. #include "sscanf.h"
  28. #include <ctype.h>
  29. //int
  30. // g_iServerVersion = 0;
  31. unsigned int
  32. g_iTrueMax = 0,
  33. g_iInvalid = 0,
  34. g_iMaxPlayerName = 0;
  35. int *
  36. g_iConnected = 0;
  37. int *
  38. g_iNPC = 0;
  39. char *
  40. g_szPlayerNames = 0;
  41. //char **
  42. // g_pServer = NULL;
  43. static char
  44. * g_cDelim = " ",
  45. * g_cTemp = 0;
  46. extern logprintf_t
  47. logprintf;
  48. // Server information
  49. int
  50. strincmp(const char * st1, const char * st2, unsigned int n)
  51. {
  52. int
  53. ret;
  54. while (n--)
  55. {
  56. if (*st1 == '\0' || *st2 == '\0')
  57. {
  58. return 0;
  59. }
  60. ret = tolower(*st1++) - tolower(*st2++);
  61. if (ret)
  62. {
  63. return ret;
  64. }
  65. }
  66. return 0;
  67. }
  68. bool
  69. strstrin(const char * st1, const char * st2, unsigned int n)
  70. {
  71. char
  72. f = tolower(*st2);
  73. while (*st1)
  74. {
  75. if (tolower(*st1) == f)
  76. {
  77. if (!strincmp(st1, st2, n))
  78. {
  79. return true;
  80. }
  81. }
  82. ++st1;
  83. }
  84. return false;
  85. }
  86. int *
  87. GetConnected()
  88. {
  89. //return (int *)(*g_pServer + 500 * 120 + 8); // g_iTrueMax
  90. return g_iConnected;
  91. }
  92. int *
  93. GetNPCs()
  94. {
  95. //return (int *)(*g_pServer + 500 * 157 + 8); // g_iTrueMax
  96. return g_iNPC;
  97. }
  98. char *
  99. GetNames()
  100. {
  101. //return *g_pServer + 500 * 128 + 8; // g_iTrueMax
  102. return g_szPlayerNames;
  103. }
  104. bool
  105. IsPlayerConnected(int playerid)
  106. {
  107. // Check the IsPlayerConnected variable in memory.
  108. return GetConnected()[playerid] != 0;
  109. }
  110. bool
  111. IsPlayerNPC(int playerid)
  112. {
  113. // Check the IsPlayerNPC variable in memory.
  114. return GetNPCs()[playerid] != 0;
  115. }
  116. char *
  117. GetPlayerName(int playerid)
  118. {
  119. // Get the player name pointer from memory.
  120. return GetNames() + (playerid * g_iMaxPlayerName);
  121. }
  122. // Spacer information
  123. // These are the delimiter functions. The code is arranged in this way to
  124. // allow for planned extensions to allow multiple custom delimiters without
  125. // modifying any other code.
  126. bool
  127. IsDelimiter(char ch)
  128. {
  129. // Can easily modify this function when we want to add the ability to have
  130. // multiple delimiters. This should be the only place that this check is
  131. // done now - use functions, not code!
  132. //return ch == g_cDelim;
  133. char *
  134. nu = g_cDelim;
  135. while (*nu)
  136. {
  137. if (*nu++ == ch) return true;
  138. }
  139. return false;
  140. }
  141. bool
  142. IsDefaultDelimiter()
  143. {
  144. return g_cDelim[0] == ' ' && g_cDelim[1] == '\0';
  145. }
  146. void
  147. TempDelimiter(char * ch)
  148. {
  149. g_cTemp = g_cDelim;
  150. g_cDelim = ch;
  151. }
  152. void
  153. RestoreDelimiter()
  154. {
  155. g_cDelim = g_cTemp;
  156. g_cTemp = 0;
  157. }
  158. bool
  159. InitialiseDelimiter()
  160. {
  161. return AddDelimiter(' ');
  162. }
  163. bool
  164. ResetDelimiter()
  165. {
  166. return InitialiseDelimiter();
  167. }
  168. bool
  169. AddDelimiter(char ch)
  170. {
  171. static char
  172. sStr[2] = {0, 0};
  173. // Only add new delimiters if we are not in a temporary delimiter area.
  174. // The only place this applies is when you do something like:
  175. // E<ip<;>ii>(1, 2, 3)
  176. sStr[0] = ch;
  177. sStr[1] = '\0';
  178. if (g_cTemp)
  179. {
  180. g_cTemp = sStr;
  181. }
  182. else
  183. {
  184. g_cDelim = sStr;
  185. }
  186. return true;
  187. }
  188. bool
  189. AddDelimiters(char * ch)
  190. {
  191. // Only add new delimiters if we are not in a temporary delimiter area.
  192. // The only place this applies is when you do something like:
  193. // E<ip<;>ii>(1, 2, 3)
  194. if (g_cTemp)
  195. {
  196. g_cTemp = ch;
  197. }
  198. else
  199. {
  200. g_cDelim = ch;
  201. }
  202. return true;
  203. }
  204. // Generic spacer code - delimiters and whitespace.
  205. bool
  206. IsWhitespace(char ch)
  207. {
  208. return (unsigned char)ch <= (unsigned char)' ';
  209. }
  210. bool
  211. IsSpacer(char ch)
  212. {
  213. return IsWhitespace(ch) || IsDelimiter(ch);
  214. }
  215. bool
  216. IsStringEnd(char ch)
  217. {
  218. if (IsDefaultDelimiter())
  219. {
  220. return IsWhitespace(ch);
  221. }
  222. else
  223. {
  224. return IsEnd(ch) || IsDelimiter(ch);
  225. }
  226. }
  227. bool
  228. IsEnd(char ch)
  229. {
  230. return ch == '\0';
  231. }
  232. void
  233. SkipSpacer(char ** input)
  234. {
  235. char *
  236. str = *input;
  237. while (*str && IsSpacer(*str))
  238. {
  239. ++str;
  240. }
  241. *input = str;
  242. }
  243. void
  244. FindSpacer(char ** input)
  245. {
  246. char *
  247. str = *input;
  248. // Don't need a valid character check here as NULL is a spacer.
  249. while (!IsSpacer(*str))
  250. {
  251. ++str;
  252. }
  253. *input = str;
  254. }
  255. void
  256. SkipDelimiter(char ** input)
  257. {
  258. char *
  259. str = *input;
  260. while (*str && IsDelimiter(*str))
  261. {
  262. ++str;
  263. }
  264. *input = str;
  265. }
  266. void
  267. FindDelimiter(char ** input)
  268. {
  269. char *
  270. str = *input;
  271. while (!IsDelimiter(*str))
  272. {
  273. ++str;
  274. }
  275. *input = str;
  276. }
  277. void
  278. SkipWhitespace(char ** input)
  279. {
  280. char *
  281. str = *input;
  282. while (*str && IsWhitespace(*str))
  283. {
  284. ++str;
  285. }
  286. *input = str;
  287. }
  288. void
  289. SkipOneSpacer(char ** input)
  290. {
  291. char *
  292. str = *input;
  293. // Skip all whitespace before the explicit delimiter.
  294. while (*str && IsWhitespace(*str))
  295. {
  296. ++str;
  297. }
  298. // We have found a delimiter - skip just one of them.
  299. if (IsDelimiter(*str))
  300. {
  301. ++str;
  302. // Now skip any space after it too.
  303. while (*str && IsWhitespace(*str))
  304. {
  305. ++str;
  306. }
  307. }
  308. *input = str;
  309. }
  310. void
  311. FindWhitespace(char ** input)
  312. {
  313. char *
  314. str = *input;
  315. while (!IsWhitespace(*str))
  316. {
  317. ++str;
  318. }
  319. *input = str;
  320. }
  321. bool
  322. GetReturn(char ** input)
  323. {
  324. // Check the end is a valid end.
  325. if (IsSpacer(**input))
  326. {
  327. return true;
  328. }
  329. return false;
  330. }
  331. bool
  332. GetReturnDefault(char ** input)
  333. {
  334. // Check the end is a valid end.
  335. SkipWhitespace(input);
  336. if (IsDelimiter(**input))
  337. {
  338. ++(*input);
  339. }
  340. else
  341. {
  342. logprintf("sscanf warning: Unclosed default value.");
  343. }
  344. return true;
  345. }
  346. bool
  347. strichecks(char * st1, const char * st2)
  348. {
  349. // Highly specialised strcmp function. We don't need the lexical
  350. // difference, only to know if they're the same, so we only compare then
  351. // like that and return true/false. Because the string we're comparing to
  352. // is constant we can use that for the length, we also know it's always
  353. // upper case. Note that this is not a generic function, it only works on
  354. // capital letters and underlines.
  355. while (*st2 && (*st2 == (*st1 & ~0x20)))
  356. {
  357. ++st1;
  358. ++st2;
  359. }
  360. // Check if *st2 is null.
  361. return IsEnd(*st2);
  362. }