strlib_old.inc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. /*
  2. strlib library for string manipulation.
  3. Created by David Weston
  4. Version: 1.3
  5. Licence: http://www.typefish.co.uk/licences/
  6. */
  7. /* Stuff that needs to be included. */
  8. #include <a_samp>
  9. /* Pretty key definitions */
  10. #if defined _strlib_included
  11. #endinput
  12. #endif
  13. #define _strlib_included
  14. #define _strlib_sma_string 128
  15. #define _strlib_med_string 256
  16. #define _strlib_big_string 512
  17. /* Natives for tricking PAWNO. */
  18. /*
  19. native str_replace(sSearch[], sReplace[], const sSubject[], &iCount = 0)
  20. native str_ireplace(sSearch[], sReplace[], const sSubject[], &iCount = 0)
  21. native str_pad(const sSource[], iPadLength, cPadChar = ' ')
  22. native str_repeat(const sSource[], iMultiplier)
  23. native str_rot13(const sSource[])
  24. native strtr(const sSource[], sRemove[], sReplace[])
  25. native substr(const sSource[], iStart, iLength = sizeof(sSource))
  26. native trim(const sSource[])
  27. native rtrim(const sSource[])
  28. native ltrim(const sSource[])
  29. native implode(const aPieces[][], const sGlue[] = " ")
  30. native explode(aExplode[][], sSource[], sDelimiter[] = " ")
  31. native explodea(aExplode[][], sSource[], sDelimiter[] = " ")
  32. native str_in_array(sNeedle[], aHaystack[][])
  33. */
  34. /*
  35. str_replace:
  36. Case sensitive string replace
  37. Arguments:
  38. sSearch[] String to search for
  39. sReplace[] String to replace with
  40. sSubject[] Original string
  41. (op) &iCount How many times 'sSearch' has been replaced.
  42. Returns:
  43. Replaced string.
  44. */
  45. stock str_replace(sSearch[], sReplace[], const sSubject[], &iCount = 0)
  46. {
  47. new
  48. iLengthTarget = strlen(sSearch),
  49. iLengthReplace = strlen(sReplace),
  50. iLengthSource = strlen(sSubject),
  51. iItterations = (iLengthSource - iLengthTarget) + 1;
  52. new
  53. sTemp[128],
  54. sReturn[_strlib_med_string];
  55. strcat(sReturn, sSubject, _strlib_med_string);
  56. iCount = 0;
  57. for(new iIndex; iIndex < iItterations; ++iIndex)
  58. {
  59. strmid(sTemp, sReturn, iIndex, (iIndex + iLengthTarget), (iLengthTarget + 1));
  60. if(!strcmp(sTemp, sSearch, false))
  61. {
  62. strdel(sReturn, iIndex, (iIndex + iLengthTarget));
  63. strins(sReturn, sReplace, iIndex, iLengthReplace);
  64. iIndex += iLengthTarget;
  65. iCount++;
  66. }
  67. }
  68. return sReturn;
  69. }
  70. /*
  71. str_ireplace:
  72. Case insensitive string replace
  73. Arguments:
  74. sSearch[] String to search for
  75. sReplace[] String to replace with
  76. sSubject[] Original string
  77. (op) &iCount How many times 'sSearch' has been replaced.
  78. Returns:
  79. Replaced string.
  80. */
  81. stock str_ireplace(sSearch[], sReplace[], const sSubject[], &iCount = 0)
  82. {
  83. new
  84. iLengthTarget = strlen(sSearch),
  85. iLengthReplace = strlen(sReplace),
  86. iLengthSource = strlen(sSubject),
  87. iItterations = (iLengthSource - iLengthTarget) + 1;
  88. new
  89. sTemp[128],
  90. sReturn[_strlib_med_string];
  91. strcat(sReturn, sSubject, _strlib_med_string);
  92. iCount = 0;
  93. for(new iIndex; iIndex < iItterations; ++iIndex)
  94. {
  95. strmid(sTemp, sReturn, iIndex, (iIndex + iLengthTarget), (iLengthTarget + 1));
  96. if(!strcmp(sTemp, sSearch, true))
  97. {
  98. strdel(sReturn, iIndex, (iIndex + iLengthTarget));
  99. strins(sReturn, sReplace, iIndex, iLengthReplace);
  100. iIndex += iLengthTarget;
  101. iCount++;
  102. }
  103. }
  104. return sReturn;
  105. }
  106. /*
  107. str_pad:
  108. Pad a string with characters until the defined amount.
  109. Arguments:
  110. sSource[] String input to pad.
  111. iPadLength Pad to amount. If less than sSource, sSource is returned.
  112. (op) cPadChar Character to use as padding.
  113. Returns:
  114. Padded string.
  115. */
  116. stock str_pad(const sSource[], iPadLength, cPadChar = ' ')
  117. {
  118. new
  119. iInputLength = strlen(sSource),
  120. sReturn[_strlib_med_string];
  121. strcat(sReturn, sSource, _strlib_med_string);
  122. if((iInputLength >= iPadLength) && (iPadLength > 255))
  123. {
  124. return sReturn;
  125. }
  126. while(iInputLength < iPadLength)
  127. {
  128. sReturn[iInputLength] = cPadChar;
  129. ++iInputLength;
  130. }
  131. return sReturn;
  132. }
  133. /*
  134. str_repeat:
  135. Repeats a string 'iMultiplier' times.
  136. Arguments:
  137. sSource[] String to be repeated
  138. iMultiplier Amount of times to be repeated
  139. Returns:
  140. Repeated string.
  141. */
  142. stock str_repeat(const sSource[], iMultiplier)
  143. {
  144. new
  145. iInputLength = strlen(sSource),
  146. iItteration = (iInputLength * iMultiplier),
  147. iIndex,
  148. sReturn[_strlib_med_string];
  149. while(iIndex < iItteration)
  150. {
  151. strins(sReturn, sSource, iIndex);
  152. iIndex += iInputLength;
  153. }
  154. return sReturn;
  155. }
  156. /*
  157. str_rot13:
  158. Rotates alphabetical characters 13 characters along.
  159. Arguments:
  160. sSource[] String to be rotated
  161. Returns:
  162. Rotated string.
  163. */
  164. stock str_rot13(const sSource[])
  165. {
  166. new
  167. iInputLength = strlen(sSource),
  168. sReturn[_strlib_med_string];
  169. for(new iIndex; iIndex < iInputLength; ++iIndex)
  170. {
  171. switch(sSource[iIndex])
  172. {
  173. case 65..77:
  174. {
  175. sReturn[iIndex] = sSource[iIndex] + 13;
  176. }
  177. case 78..90:
  178. {
  179. sReturn[iIndex] = sSource[iIndex] - 13;
  180. }
  181. case 97..109:
  182. {
  183. sReturn[iIndex] = sSource[iIndex] + 13;
  184. }
  185. case 110..122:
  186. {
  187. sReturn[iIndex] = sSource[iIndex] - 13;
  188. }
  189. default:
  190. {
  191. sReturn[iIndex] = sSource[iIndex];
  192. }
  193. }
  194. }
  195. return sReturn;
  196. }
  197. /*
  198. strtr:
  199. Removes 'sRemove' from the string and replaces
  200. that character from 'sReplace'.
  201. Arguments:
  202. sSource[] String to be transformed
  203. sRemove[] Characters to be removed (must be in same order as below!)
  204. sReplace[] Characters to be replaced (must be in same order as above!)
  205. Returns:
  206. Trimmed string.
  207. */
  208. stock strtr(const sSource[], sRemove[], sReplace[])
  209. {
  210. new
  211. iCurrentChar = 0,
  212. iInputLength = strlen(sSource),
  213. iRemoveLength = strlen(sRemove);
  214. new
  215. iDeleteChar = -1,
  216. sReturn[_strlib_med_string];
  217. for(new iIndex; iIndex < iInputLength; ++iIndex)
  218. {
  219. for(new iChar; iChar < iRemoveLength; ++iChar)
  220. {
  221. if(sSource[iIndex] == sRemove[iChar])
  222. {
  223. iDeleteChar = iChar;
  224. break;
  225. }
  226. }
  227. switch(iDeleteChar)
  228. {
  229. case -1:
  230. {
  231. sReturn[iCurrentChar] = sSource[iIndex];
  232. iCurrentChar++;
  233. }
  234. default:
  235. {
  236. if(strlen(sReplace) > iDeleteChar)
  237. {
  238. sReturn[iCurrentChar] = sReplace[iDeleteChar];
  239. iCurrentChar++;
  240. }
  241. iDeleteChar = -1;
  242. }
  243. }
  244. }
  245. return sReturn;
  246. }
  247. /*
  248. trim:
  249. Removes whitespace, tabs, and new lines
  250. from the beginning and end of 'sSource'.
  251. Arguments:
  252. sSource[] String to be trimmed
  253. Returns:
  254. Trimmed string.
  255. */
  256. stock trim(const sSource[])
  257. {
  258. new
  259. iBegin,
  260. iEnd,
  261. iInputLength = strlen(sSource),
  262. sReturn[_strlib_med_string];
  263. strcat(sReturn, sSource, _strlib_med_string);
  264. for(iBegin = 0; iBegin < iInputLength; ++iBegin)
  265. {
  266. switch(sReturn[iBegin])
  267. {
  268. case ' ', '\t', '\r', '\n':
  269. {
  270. continue;
  271. }
  272. default:
  273. {
  274. break;
  275. }
  276. }
  277. }
  278. for(iEnd = (iInputLength - 1); iEnd > iBegin; --iEnd)
  279. {
  280. switch(sReturn[iEnd])
  281. {
  282. case ' ', '\t', '\r', '\n':
  283. {
  284. continue;
  285. }
  286. default:
  287. {
  288. break;
  289. }
  290. }
  291. }
  292. strdel(sReturn, (iEnd + 1), iInputLength);
  293. strdel(sReturn, 0, iBegin);
  294. return sReturn;
  295. }
  296. /*
  297. ltrim:
  298. Removes whitespace, tabs, and new lines
  299. from the beginning of 'sSource'.
  300. Arguments:
  301. sSource[] String to be trimmed
  302. Returns:
  303. Trimmed string.
  304. */
  305. stock ltrim(const sSource[])
  306. {
  307. new
  308. iBegin,
  309. iInputLength = strlen(sSource),
  310. sReturn[_strlib_med_string];
  311. strcat(sReturn, sSource, _strlib_med_string);
  312. for(iBegin = 0; iBegin < iInputLength; ++iBegin)
  313. {
  314. switch(sReturn[iBegin])
  315. {
  316. case ' ', '\t', '\r', '\n':
  317. {
  318. continue;
  319. }
  320. default:
  321. {
  322. break;
  323. }
  324. }
  325. }
  326. strdel(sReturn, 0, iBegin);
  327. return sReturn;
  328. }
  329. /*
  330. rtrim:
  331. Removes whitespace, tabs, and new lines
  332. from the end of 'sSource'.
  333. Arguments:
  334. sSource[] String to be trimmed
  335. Returns:
  336. Trimmed string.
  337. */
  338. stock rtrim(const sSource[])
  339. {
  340. new
  341. iEnd,
  342. iInputLength = strlen(sSource),
  343. sReturn[_strlib_med_string];
  344. strcat(sReturn, sSource, _strlib_med_string);
  345. for(iEnd = (iInputLength - 1); iEnd > 0; --iEnd)
  346. {
  347. switch(sReturn[iEnd])
  348. {
  349. case ' ', '\t', '\r', '\n':
  350. {
  351. continue;
  352. }
  353. default:
  354. {
  355. break;
  356. }
  357. }
  358. }
  359. strdel(sReturn, (iEnd + 1), iInputLength);
  360. return sReturn;
  361. }
  362. /*
  363. substr:
  364. Gets a substring from a string.
  365. Arguments:
  366. sSource[] String to be substring'd.
  367. iStart Position for the start of substring.
  368. iLength Position for the end of substring.
  369. (if negative, cells away from end)
  370. Returns:
  371. Substring.
  372. */
  373. stock substr(const sSource[], iStart, iLength = sizeof sSource)
  374. {
  375. new
  376. sReturn[_strlib_med_string];
  377. if(iLength < 0)
  378. {
  379. strmid(sReturn, sSource, iStart, strlen(sSource) + iLength);
  380. return sReturn;
  381. }
  382. else
  383. {
  384. strmid(sReturn, sSource, iStart, (iStart + iLength));
  385. return sReturn;
  386. }
  387. }
  388. /*
  389. implode:
  390. Returns a string where the array has been stuck back together
  391. again.
  392. Arguments:
  393. aPieces[][] The array to glue back together.
  394. sGlue The string to use as the glue.
  395. Returns:
  396. The imploded string.
  397. */
  398. stock implode(const aPieces[][], const sGlue[] = " ", iVertices = sizeof aPieces)
  399. {
  400. new
  401. sReturn[_strlib_med_string];
  402. while(iVertices != -1)
  403. {
  404. strins(sReturn, aPieces[iVertices], 0);
  405. if(iVertices != 0)
  406. {
  407. strins(sReturn, sGlue, 0);
  408. }
  409. --iVertices;
  410. }
  411. return sReturn;
  412. }
  413. /*
  414. explode:
  415. Creates an array of values from 'sSource', where only the exact amount of
  416. values matching sizeof(aExplode) are returned.
  417. Arguments:
  418. aExplode[][] The exploded array
  419. sSource[] Source string.
  420. sDelimiter The string to use as the delimiter.
  421. Returns:
  422. Returns -1 on failure, otherwise success.
  423. */
  424. stock explode(aExplode[][], const sSource[], const sDelimiter[] = " ", iVertices = sizeof aExplode, iLength = sizeof aExplode[])
  425. {
  426. new
  427. iNode,
  428. iPointer,
  429. iPrevious = -1,
  430. iDelimiter = strlen(sDelimiter);
  431. while(iNode < iVertices)
  432. {
  433. iPointer = strfind(sSource, sDelimiter, false, iPointer);
  434. if(iPointer == -1)
  435. {
  436. strmid(aExplode[iNode], sSource, iPrevious, strlen(sSource), iLength);
  437. break;
  438. }
  439. else
  440. {
  441. strmid(aExplode[iNode], sSource, iPrevious, iPointer, iLength);
  442. }
  443. iPrevious = (iPointer += iDelimiter);
  444. ++iNode;
  445. }
  446. return iPrevious;
  447. }
  448. /*
  449. explodea:
  450. Creates an array of values from 'sSource', where any overrun is stored in
  451. the final node.
  452. Arguments:
  453. aExplode[][] The exploded array
  454. sSource[] Source string.
  455. sDelimiter The string to use as the delimiter.
  456. Returns:
  457. Returns -1 on failure, otherwise success.
  458. */
  459. stock explodea(aExplode[][], const sSource[], const sDelimiter[] = " ", iVertices = sizeof aExplode, iLength = sizeof aExplode[])
  460. {
  461. new
  462. iNode,
  463. iPointer,
  464. iPrevious = -1,
  465. iSource = strlen(sSource),
  466. iDelimiter = strlen(sDelimiter);
  467. while(iNode < iVertices)
  468. {
  469. iPointer = strfind(sSource, sDelimiter, false, iPointer);
  470. strmid(aExplode[iNode], sSource, iPrevious, (iNode == (iVertices - 1) ? iSource : iPointer), iLength);
  471. iPrevious = (iPointer += iDelimiter);
  472. ++iNode;
  473. }
  474. return iPrevious;
  475. }
  476. /*
  477. str_in_array:
  478. Checks if a string matches any of the strings in the array.
  479. Arguments:
  480. sNeedle[] String that is being matched.
  481. aHaystack[][] Array with strings to be searched,
  482. Returns:
  483. Returns true on a match.
  484. */
  485. stock bool:str_in_array(const sNeedle[], const aHaystack[][], const iHaystack = sizeof aHaystack)
  486. {
  487. new iNode = 0;
  488. while(iNode < iHaystack)
  489. {
  490. if(!strcmp(sNeedle, aHaystack[iNode], true))
  491. {
  492. return true;
  493. }
  494. ++iNode;
  495. }
  496. return false;
  497. }