strlib.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
  2. // For more information, see LICENCE in the main folder
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7. #include "strlib.h"
  8. #include "../common/cbasetypes.h"
  9. #include "../common/utils.h"
  10. #include "../common/malloc.h"
  11. #define J_MAX_MALLOC_SIZE 65535
  12. // escapes a string in-place (' -> \' , \ -> \\ , % -> _)
  13. char* jstrescape (char* pt)
  14. {
  15. //copy from here
  16. char *ptr;
  17. int i = 0, j = 0;
  18. //copy string to temporary
  19. CREATE(ptr, char, J_MAX_MALLOC_SIZE);
  20. strcpy(ptr,pt);
  21. while (ptr[i] != '\0') {
  22. switch (ptr[i]) {
  23. case '\'':
  24. pt[j++] = '\\';
  25. pt[j++] = ptr[i++];
  26. break;
  27. case '\\':
  28. pt[j++] = '\\';
  29. pt[j++] = ptr[i++];
  30. break;
  31. case '%':
  32. pt[j++] = '_'; i++;
  33. break;
  34. default:
  35. pt[j++] = ptr[i++];
  36. }
  37. }
  38. pt[j++] = '\0';
  39. aFree(ptr);
  40. return pt;
  41. }
  42. // escapes a string into a provided buffer
  43. char* jstrescapecpy (char* pt, const char* spt)
  44. {
  45. //copy from here
  46. //WARNING: Target string pt should be able to hold strlen(spt)*2, as each time
  47. //a escape character is found, the target's final length increases! [Skotlex]
  48. int i =0, j=0;
  49. if (!spt) { //Return an empty string [Skotlex]
  50. pt[0] = '\0';
  51. return &pt[0];
  52. }
  53. while (spt[i] != '\0') {
  54. switch (spt[i]) {
  55. case '\'':
  56. pt[j++] = '\\';
  57. pt[j++] = spt[i++];
  58. break;
  59. case '\\':
  60. pt[j++] = '\\';
  61. pt[j++] = spt[i++];
  62. break;
  63. case '%':
  64. pt[j++] = '_'; i++;
  65. break;
  66. default:
  67. pt[j++] = spt[i++];
  68. }
  69. }
  70. pt[j++] = '\0';
  71. return &pt[0];
  72. }
  73. // escapes exactly 'size' bytes of a string into a provided buffer
  74. int jmemescapecpy (char* pt, const char* spt, int size)
  75. {
  76. //copy from here
  77. int i =0, j=0;
  78. while (i < size) {
  79. switch (spt[i]) {
  80. case '\'':
  81. pt[j++] = '\\';
  82. pt[j++] = spt[i++];
  83. break;
  84. case '\\':
  85. pt[j++] = '\\';
  86. pt[j++] = spt[i++];
  87. break;
  88. case '%':
  89. pt[j++] = '_'; i++;
  90. break;
  91. default:
  92. pt[j++] = spt[i++];
  93. }
  94. }
  95. // copy size is 0 ~ (j-1)
  96. return j;
  97. }
  98. // Function to suppress control characters in a string.
  99. int remove_control_chars(char* str)
  100. {
  101. int i;
  102. int change = 0;
  103. for(i = 0; str[i]; i++) {
  104. if (str[i] < 32) {
  105. str[i] = '_';
  106. change = 1;
  107. }
  108. }
  109. return change;
  110. }
  111. //Trims a string, also removes illegal characters such as \t and reduces continous spaces to a single one. by [Foruken]
  112. char* trim(char* str, const char* delim)
  113. {
  114. char* strp = strtok(str,delim);
  115. char buf[1024];
  116. char* bufp = buf;
  117. memset(buf,0,sizeof buf);
  118. while(strp) {
  119. strcpy(bufp, strp);
  120. bufp = bufp + strlen(strp);
  121. strp = strtok(NULL, delim);
  122. if (strp) {
  123. strcpy(bufp," ");
  124. bufp++;
  125. }
  126. }
  127. strcpy(str,buf);
  128. return str;
  129. }
  130. //stristr: Case insensitive version of strstr, code taken from
  131. //http://www.daniweb.com/code/snippet313.html, Dave Sinkula
  132. //
  133. const char* stristr(const char* haystack, const char* needle)
  134. {
  135. if ( !*needle )
  136. {
  137. return haystack;
  138. }
  139. for ( ; *haystack; ++haystack )
  140. {
  141. if ( TOUPPER(*haystack) == TOUPPER(*needle) )
  142. {
  143. // matched starting char -- loop through remaining chars
  144. const char *h, *n;
  145. for ( h = haystack, n = needle; *h && *n; ++h, ++n )
  146. {
  147. if ( TOUPPER(*h) != TOUPPER(*n) )
  148. {
  149. break;
  150. }
  151. }
  152. if ( !*n ) // matched all of 'needle' to null termination
  153. {
  154. return haystack; // return the start of the match
  155. }
  156. }
  157. }
  158. return 0;
  159. }
  160. #ifdef __WIN32
  161. char* _strtok_r(char *s1, const char *s2, char **lasts)
  162. {
  163. char *ret;
  164. if (s1 == NULL)
  165. s1 = *lasts;
  166. while(*s1 && strchr(s2, *s1))
  167. ++s1;
  168. if(*s1 == '\0')
  169. return NULL;
  170. ret = s1;
  171. while(*s1 && !strchr(s2, *s1))
  172. ++s1;
  173. if(*s1)
  174. *s1++ = '\0';
  175. *lasts = s1;
  176. return ret;
  177. }
  178. #endif
  179. #if !defined(WIN32) || (defined(_MSC_VER) && _MSC_VER < 1400)
  180. /* Find the length of STRING, but scan at most MAXLEN characters.
  181. If no '\0' terminator is found in that many characters, return MAXLEN. */
  182. size_t strnlen (const char* string, size_t maxlen)
  183. {
  184. const char* end = memchr (string, '\0', maxlen);
  185. return end ? (size_t) (end - string) : maxlen;
  186. }
  187. #endif