utils.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4. #include "utils.h"
  5. // http://c-faq.com/lib/randrange.html
  6. int randint(int N) { return rand() / (RAND_MAX / N + 1); }
  7. // http://c-faq.com/lib/randrange.html
  8. // numbers in the range [M, N] could be generated with something like
  9. int randrange(int M, int N) {
  10. return M + rand() / (RAND_MAX / (N - M + 1) + 1);
  11. }
  12. /**
  13. * Display a repr of the given string.
  14. *
  15. * This converts most \n\r\v\f\t codes,
  16. * defaults to \xHH (hex value).
  17. */
  18. char *repr(const char *data) {
  19. static char buffer[40960];
  20. char *cp;
  21. strcpy(buffer, data);
  22. cp = buffer;
  23. while (*cp != 0) {
  24. char c = *cp;
  25. if (c == ' ') {
  26. cp++;
  27. continue;
  28. };
  29. /* Ok, it's form-feed ('\f'), newline ('\n'), carriage return ('\r'),
  30. * horizontal tab ('\t'), and vertical tab ('\v') */
  31. if (strchr("\f\n\r\t\v\?", c) != NULL) {
  32. memmove(cp + 1, cp, strlen(cp) + 1);
  33. *cp = '\\';
  34. cp++;
  35. switch (c) {
  36. case '\f':
  37. *cp = 'f';
  38. cp++;
  39. break;
  40. case '\n':
  41. *cp = 'n';
  42. cp++;
  43. break;
  44. case '\r':
  45. *cp = 'r';
  46. cp++;
  47. break;
  48. case '\t':
  49. *cp = 't';
  50. cp++;
  51. break;
  52. case '\v':
  53. *cp = 'v';
  54. cp++;
  55. break;
  56. default:
  57. *cp = '?';
  58. cp++;
  59. break;
  60. }
  61. continue;
  62. }
  63. if (c == '\\') {
  64. memmove(cp + 1, cp, strlen(cp) + 1);
  65. *cp = '\\';
  66. cp += 2;
  67. continue;
  68. }
  69. if (c == '"') {
  70. memmove(cp + 1, cp, strlen(cp) + 1);
  71. *cp = '\\';
  72. cp += 2;
  73. continue;
  74. }
  75. if (strchr("[()]{}:;,.<>?!@#$%^&*", c) != NULL) {
  76. cp++;
  77. continue;
  78. }
  79. if (strchr("0123456789", c) != NULL) {
  80. cp++;
  81. continue;
  82. }
  83. if (strchr("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", c) !=
  84. NULL) {
  85. cp++;
  86. continue;
  87. }
  88. // Ok, default to \xHH output.
  89. memmove(cp + 3, cp, strlen(cp) + 1);
  90. char buffer[10];
  91. sprintf(buffer, "\\x%02x", (int)c & 0xff);
  92. strncpy(cp, buffer, 4);
  93. cp += 4;
  94. continue;
  95. }
  96. return buffer;
  97. }
  98. /*
  99. * strnstr()
  100. *
  101. * buffer safe version that looks for a string.
  102. */
  103. const char *strnstr(const char *source, int len, const char *needle) {
  104. int pos;
  105. for (pos = 0; pos < len; pos++) {
  106. if (source[pos] == needle[0]) {
  107. if (strncmp(source + pos, needle, strlen(needle)) == 0) {
  108. return source + pos;
  109. }
  110. }
  111. }
  112. return NULL;
  113. }
  114. /*
  115. * rstrnstr() Reverse string find in a string
  116. *
  117. * This obeys the len, and handles nulls in buffer.
  118. * find is a c-string (null terminated)
  119. */
  120. int rstrnstr(const char *buffer, int len, const char *find) {
  121. int flen = strlen(find);
  122. if (len < flen) {
  123. // I can't find a string in a buffer smaller then it is!
  124. return -1;
  125. }
  126. int pos = len - flen;
  127. while (pos > 0) {
  128. if (buffer[pos] == find[0]) {
  129. // First chars match, check them all.
  130. if (strncmp(buffer + pos, find, flen) == 0) {
  131. return pos;
  132. }
  133. }
  134. pos--;
  135. }
  136. return -1;
  137. }