test-basic 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. #!/bin/sh
  2. . $(dirname $(readlink -f $0))/framework.sh
  3. # Check for non-existing files
  4. testfailure triehash -C /does/not/exist1 -H /does/not/exist1 /does/not/exist/input
  5. # Check that we can specify - for -C and -H
  6. testsuccessequal "#ifndef TRIE_HASH_PerfectHash
  7. #define TRIE_HASH_PerfectHash
  8. #include <stddef.h>
  9. #include <stdint.h>
  10. enum PerfectKey {
  11. Unknown = -1,
  12. };
  13. static enum PerfectKey PerfectHash(const char *string, size_t length);
  14. static enum PerfectKey PerfectHash(const char *string, size_t length)
  15. {
  16. switch (length) {
  17. default:
  18. return Unknown;
  19. }
  20. }
  21. #endif /* TRIE_HASH_PerfectHash */" triehash --multi-byte=0 -C - -H -
  22. # Check that split files work
  23. testsuccess triehash -C test.c -H test.h --multi-byte=0
  24. testfileequal "#include \"test.h\"
  25. enum PerfectKey PerfectHash(const char *string, size_t length)
  26. {
  27. switch (length) {
  28. default:
  29. return Unknown;
  30. }
  31. }" test.c
  32. testfileequal "#ifndef TRIE_HASH_PerfectHash
  33. #define TRIE_HASH_PerfectHash
  34. #include <stddef.h>
  35. #include <stdint.h>
  36. enum PerfectKey {
  37. Unknown = -1,
  38. };
  39. enum PerfectKey PerfectHash(const char *string, size_t length);
  40. #endif /* TRIE_HASH_PerfectHash */" test.h
  41. # Check the C code generator
  42. testsuccess triehash -C test.c -H test.c /dev/stdin
  43. testfileequal "#ifndef TRIE_HASH_PerfectHash
  44. #define TRIE_HASH_PerfectHash
  45. #include <stddef.h>
  46. #include <stdint.h>
  47. enum PerfectKey {
  48. VeryLongWord = 43,
  49. Word = 42,
  50. Word___0 = 0,
  51. Label = 44,
  52. Unknown = -9,
  53. };
  54. static enum PerfectKey PerfectHash(const char *string, size_t length);
  55. #ifdef __GNUC__
  56. typedef uint16_t __attribute__((aligned (1))) triehash_uu16;
  57. typedef char static_assert16[__alignof__(triehash_uu16) == 1 ? 1 : -1];
  58. typedef uint32_t __attribute__((aligned (1))) triehash_uu32;
  59. typedef char static_assert32[__alignof__(triehash_uu32) == 1 ? 1 : -1];
  60. typedef uint64_t __attribute__((aligned (1))) triehash_uu64;
  61. typedef char static_assert64[__alignof__(triehash_uu64) == 1 ? 1 : -1];
  62. #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
  63. #define onechar(c, s, l) (((uint64_t)(c)) << (s))
  64. #else
  65. #define onechar(c, s, l) (((uint64_t)(c)) << (l-8-s))
  66. #endif
  67. #if (!defined(__ARM_ARCH) || defined(__ARM_FEATURE_UNALIGNED)) && !defined(TRIE_HASH_NO_MULTI_BYTE)
  68. #define TRIE_HASH_MULTI_BYTE
  69. #endif
  70. #endif /*GNUC */
  71. #ifdef TRIE_HASH_MULTI_BYTE
  72. static enum PerfectKey PerfectHash4(const char *string)
  73. {
  74. switch(*((triehash_uu32*) &string[0])) {
  75. case 0| onechar('W', 0, 32)| onechar('o', 8, 32)| onechar('r', 16, 32)| onechar('d', 24, 32):
  76. return Word;
  77. }
  78. return Unknown;
  79. }
  80. static enum PerfectKey PerfectHash5(const char *string)
  81. {
  82. switch(*((triehash_uu32*) &string[0])) {
  83. case 0| onechar('W', 0, 32)| onechar('o', 8, 32)| onechar('r', 16, 32)| onechar('d', 24, 32):
  84. switch(string[4]) {
  85. case 0| onechar('2', 0, 8):
  86. return Label;
  87. }
  88. }
  89. return Unknown;
  90. }
  91. static enum PerfectKey PerfectHash7(const char *string)
  92. {
  93. switch(*((triehash_uu32*) &string[0])) {
  94. case 0| onechar('W', 0, 32)| onechar('o', 8, 32)| onechar('r', 16, 32)| onechar('d', 24, 32):
  95. switch(string[4]) {
  96. case 0| onechar('-', 0, 8):
  97. switch(string[5]) {
  98. case 0| onechar('_', 0, 8):
  99. switch(string[6]) {
  100. case 0| onechar('0', 0, 8):
  101. return Word___0;
  102. }
  103. }
  104. }
  105. }
  106. return Unknown;
  107. }
  108. static enum PerfectKey PerfectHash12(const char *string)
  109. {
  110. switch(*((triehash_uu64*) &string[0])) {
  111. case 0| onechar('V', 0, 64)| onechar('e', 8, 64)| onechar('r', 16, 64)| onechar('y', 24, 64)| onechar('L', 32, 64)| onechar('o', 40, 64)| onechar('n', 48, 64)| onechar('g', 56, 64):
  112. switch(*((triehash_uu32*) &string[8])) {
  113. case 0| onechar('W', 0, 32)| onechar('o', 8, 32)| onechar('r', 16, 32)| onechar('d', 24, 32):
  114. return VeryLongWord;
  115. }
  116. }
  117. return Unknown;
  118. }
  119. #else
  120. static enum PerfectKey PerfectHash4(const char *string)
  121. {
  122. switch(string[0]) {
  123. case 'W':
  124. switch(string[1]) {
  125. case 'o':
  126. switch(string[2]) {
  127. case 'r':
  128. switch(string[3]) {
  129. case 'd':
  130. return Word;
  131. }
  132. }
  133. }
  134. }
  135. return Unknown;
  136. }
  137. static enum PerfectKey PerfectHash5(const char *string)
  138. {
  139. switch(string[0]) {
  140. case 'W':
  141. switch(string[1]) {
  142. case 'o':
  143. switch(string[2]) {
  144. case 'r':
  145. switch(string[3]) {
  146. case 'd':
  147. switch(string[4]) {
  148. case '2':
  149. return Label;
  150. }
  151. }
  152. }
  153. }
  154. }
  155. return Unknown;
  156. }
  157. static enum PerfectKey PerfectHash7(const char *string)
  158. {
  159. switch(string[0]) {
  160. case 'W':
  161. switch(string[1]) {
  162. case 'o':
  163. switch(string[2]) {
  164. case 'r':
  165. switch(string[3]) {
  166. case 'd':
  167. switch(string[4]) {
  168. case '-':
  169. switch(string[5]) {
  170. case '_':
  171. switch(string[6]) {
  172. case '0':
  173. return Word___0;
  174. }
  175. }
  176. }
  177. }
  178. }
  179. }
  180. }
  181. return Unknown;
  182. }
  183. static enum PerfectKey PerfectHash12(const char *string)
  184. {
  185. switch(string[0]) {
  186. case 'V':
  187. switch(string[1]) {
  188. case 'e':
  189. switch(string[2]) {
  190. case 'r':
  191. switch(string[3]) {
  192. case 'y':
  193. switch(string[4]) {
  194. case 'L':
  195. switch(string[5]) {
  196. case 'o':
  197. switch(string[6]) {
  198. case 'n':
  199. switch(string[7]) {
  200. case 'g':
  201. switch(string[8]) {
  202. case 'W':
  203. switch(string[9]) {
  204. case 'o':
  205. switch(string[10]) {
  206. case 'r':
  207. switch(string[11]) {
  208. case 'd':
  209. return VeryLongWord;
  210. }
  211. }
  212. }
  213. }
  214. }
  215. }
  216. }
  217. }
  218. }
  219. }
  220. }
  221. }
  222. return Unknown;
  223. }
  224. #endif /* TRIE_HASH_MULTI_BYTE */
  225. static enum PerfectKey PerfectHash(const char *string, size_t length)
  226. {
  227. switch (length) {
  228. case 4:
  229. return PerfectHash4(string);
  230. case 5:
  231. return PerfectHash5(string);
  232. case 7:
  233. return PerfectHash7(string);
  234. case 12:
  235. return PerfectHash12(string);
  236. default:
  237. return Unknown;
  238. }
  239. }
  240. #endif /* TRIE_HASH_PerfectHash */" test.c