utils.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. #include <assert.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "utils.h"
  6. // http://c-faq.com/lib/randrange.html
  7. int randint(int N) { return rand() / (RAND_MAX / N + 1); }
  8. // http://c-faq.com/lib/randrange.html
  9. // numbers in the range [M, N] could be generated with something like
  10. int randrange(int M, int N) {
  11. return M + rand() / (RAND_MAX / (N - M + 1) + 1);
  12. }
  13. /**
  14. * random_activate()
  15. *
  16. * Is a weight (1-10),
  17. * tests if random number is < weight * 10.
  18. *
  19. * So random_activate(9) happens more frequently
  20. * then random_activate(8) or lower.
  21. *
  22. * This probably needs to be fixed.
  23. * We need a better randint(RANGE) code.
  24. */
  25. int random_activate(int w) {
  26. int r = randint(100);
  27. if (r <= (w * 10)) {
  28. return 1;
  29. };
  30. return 0;
  31. }
  32. /**
  33. * Display a repr of the given string.
  34. *
  35. * This converts most \n\r\v\f\t codes,
  36. * defaults to \xHH (hex value).
  37. */
  38. char *repr(const char *data) {
  39. static char buffer[40960];
  40. char *cp;
  41. strcpy(buffer, data);
  42. cp = buffer;
  43. while (*cp != 0) {
  44. char c = *cp;
  45. if (c == ' ') {
  46. cp++;
  47. continue;
  48. };
  49. /* Ok, it's form-feed ('\f'), newline ('\n'), carriage return ('\r'),
  50. * horizontal tab ('\t'), and vertical tab ('\v') */
  51. if (strchr("\f\n\r\t\v\?", c) != NULL) {
  52. memmove(cp + 1, cp, strlen(cp) + 1);
  53. *cp = '\\';
  54. cp++;
  55. switch (c) {
  56. case '\f':
  57. *cp = 'f';
  58. cp++;
  59. break;
  60. case '\n':
  61. *cp = 'n';
  62. cp++;
  63. break;
  64. case '\r':
  65. *cp = 'r';
  66. cp++;
  67. break;
  68. case '\t':
  69. *cp = 't';
  70. cp++;
  71. break;
  72. case '\v':
  73. *cp = 'v';
  74. cp++;
  75. break;
  76. default:
  77. *cp = '?';
  78. cp++;
  79. break;
  80. }
  81. continue;
  82. }
  83. if (c == '\\') {
  84. memmove(cp + 1, cp, strlen(cp) + 1);
  85. *cp = '\\';
  86. cp += 2;
  87. continue;
  88. }
  89. if (c == '"') {
  90. memmove(cp + 1, cp, strlen(cp) + 1);
  91. *cp = '\\';
  92. cp += 2;
  93. continue;
  94. }
  95. if (strchr("[()]{}:;,.<>?!@#$%^&*", c) != NULL) {
  96. cp++;
  97. continue;
  98. }
  99. if (strchr("0123456789", c) != NULL) {
  100. cp++;
  101. continue;
  102. }
  103. if (strchr("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", c) !=
  104. NULL) {
  105. cp++;
  106. continue;
  107. }
  108. // Ok, default to \xHH output.
  109. memmove(cp + 3, cp, strlen(cp) + 1);
  110. char buffer[10];
  111. int slen;
  112. slen = snprintf(buffer, sizeof(buffer), "\\x%02x", (int)c & 0xff);
  113. /*
  114. if (slen >= sizeof(buffer)) {
  115. ZF_LOGE("snprintf %d > size %d", slen, (int)sizeof(buffer));
  116. }
  117. */
  118. strncpy(cp, buffer, 4);
  119. cp += 4;
  120. continue;
  121. }
  122. return buffer;
  123. }
  124. /*
  125. * strnstr()
  126. *
  127. * buffer safe version that looks for a string.
  128. */
  129. const char *strnstr(const char *source, int len, const char *needle) {
  130. int pos;
  131. for (pos = 0; pos < len; pos++) {
  132. if (source[pos] == needle[0]) {
  133. if (strncmp(source + pos, needle, strlen(needle)) == 0) {
  134. return source + pos;
  135. }
  136. }
  137. }
  138. return NULL;
  139. }
  140. /*
  141. * rstrnstr() Reverse string find in a string
  142. *
  143. * This obeys the len, and handles nulls in buffer.
  144. * find is a c-string (null terminated)
  145. */
  146. int rstrnstr(const char *buffer, int len, const char *find) {
  147. int flen = strlen(find);
  148. if (len < flen) {
  149. // I can't find a string in a buffer smaller then it is!
  150. return -1;
  151. }
  152. int pos = len - flen;
  153. while (pos > 0) {
  154. if (buffer[pos] == find[0]) {
  155. // First chars match, check them all.
  156. if (strncmp(buffer + pos, find, flen) == 0) {
  157. return pos;
  158. }
  159. }
  160. pos--;
  161. }
  162. return -1;
  163. }
  164. /*
  165. * string_insert()
  166. * Inserts a string into a given position.
  167. * This safely checks to make sure the buffer isn't overrun.
  168. *
  169. * buffer is a c null terminated string.
  170. */
  171. int string_insert(char *buffer, int max_length, int pos, const char *insert) {
  172. /*
  173. assert(max_length > pos);
  174. assert(buffer != NULL);
  175. assert(insert != NULL);
  176. */
  177. if (pos >= max_length)
  178. return 0;
  179. if (buffer == NULL)
  180. return 0;
  181. if (insert == NULL)
  182. return 0;
  183. if (strlen(insert) == 0)
  184. return 0;
  185. if (pos > strlen(buffer))
  186. return 0;
  187. if (strlen(buffer) + strlen(insert) >= max_length) {
  188. /*
  189. ZF_LOGD("string_insert() failed inserting [%s]", repr(insert));
  190. */
  191. return 0;
  192. }
  193. memmove(buffer + pos + strlen(insert), buffer + pos,
  194. strlen(buffer + pos) + 1);
  195. // cp + strlen(display), cp, strlen(cp) + 1);
  196. strncpy(buffer + pos, insert, strlen(insert));
  197. // (cp, display, strlen(display));
  198. return 1; // success
  199. }
  200. /*
  201. Pascal String Copy. Copy from pascal string, to C String.
  202. First char is pascal string length. (Max 255).
  203. */
  204. void pcopy(char *pstring, char *str) {
  205. int len = (int)*pstring;
  206. strncpy(str, pstring + 1, len);
  207. str[len] = 0;
  208. }