PageRenderTime 32ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/src/qt/qtbase/src/3rdparty/xkbcommon/src/atom.c

https://gitlab.com/x33n/phantomjs
C | 225 lines | 119 code | 28 blank | 78 comment | 29 complexity | 91518a270f2a9fee6c1dedefd94154b7 MD5 | raw file
  1. /***********************************************************
  2. * Copyright 1987, 1998 The Open Group
  3. *
  4. * Permission to use, copy, modify, distribute, and sell this software and its
  5. * documentation for any purpose is hereby granted without fee, provided that
  6. * the above copyright notice appear in all copies and that both that
  7. * copyright notice and this permission notice appear in supporting
  8. * documentation.
  9. *
  10. * The above copyright notice and this permission notice shall be included in
  11. * all copies or substantial portions of the Software.
  12. *
  13. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. * OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  17. * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  18. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  19. *
  20. * Except as contained in this notice, the name of The Open Group shall not be
  21. * used in advertising or otherwise to promote the sale, use or other dealings
  22. * in this Software without prior written authorization from The Open Group.
  23. *
  24. *
  25. * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
  26. *
  27. * All Rights Reserved
  28. *
  29. * Permission to use, copy, modify, and distribute this software and its
  30. * documentation for any purpose and without fee is hereby granted,
  31. * provided that the above copyright notice appear in all copies and that
  32. * both that copyright notice and this permission notice appear in
  33. * supporting documentation, and that the name of Digital not be
  34. * used in advertising or publicity pertaining to distribution of the
  35. * software without specific, written prior permission.
  36. *
  37. * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  38. * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  39. * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  40. * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  41. * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  42. * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  43. * SOFTWARE.
  44. *
  45. ******************************************************************/
  46. /************************************************************
  47. * Copyright 1994 by Silicon Graphics Computer Systems, Inc.
  48. *
  49. * Permission to use, copy, modify, and distribute this
  50. * software and its documentation for any purpose and without
  51. * fee is hereby granted, provided that the above copyright
  52. * notice appear in all copies and that both that copyright
  53. * notice and this permission notice appear in supporting
  54. * documentation, and that the name of Silicon Graphics not be
  55. * used in advertising or publicity pertaining to distribution
  56. * of the software without specific prior written permission.
  57. * Silicon Graphics makes no representation about the suitability
  58. * of this software for any purpose. It is provided "as is"
  59. * without any express or implied warranty.
  60. *
  61. * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  62. * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  63. * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
  64. * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
  65. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  66. * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  67. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
  68. * THE USE OR PERFORMANCE OF THIS SOFTWARE.
  69. *
  70. ********************************************************/
  71. #include "utils.h"
  72. #include "atom.h"
  73. struct atom_node {
  74. xkb_atom_t left, right;
  75. xkb_atom_t atom;
  76. unsigned int fingerprint;
  77. char *string;
  78. };
  79. struct atom_table {
  80. xkb_atom_t root;
  81. darray(struct atom_node) table;
  82. };
  83. struct atom_table *
  84. atom_table_new(void)
  85. {
  86. struct atom_table *table;
  87. table = calloc(1, sizeof(*table));
  88. if (!table)
  89. return NULL;
  90. darray_init(table->table);
  91. /* The original throw-away root is here, at the illegal atom 0. */
  92. darray_resize0(table->table, 1);
  93. return table;
  94. }
  95. void
  96. atom_table_free(struct atom_table *table)
  97. {
  98. struct atom_node *node;
  99. if (!table)
  100. return;
  101. darray_foreach(node, table->table)
  102. free(node->string);
  103. darray_free(table->table);
  104. free(table);
  105. }
  106. const char *
  107. atom_text(struct atom_table *table, xkb_atom_t atom)
  108. {
  109. if (atom == XKB_ATOM_NONE || atom >= darray_size(table->table))
  110. return NULL;
  111. return darray_item(table->table, atom).string;
  112. }
  113. static bool
  114. find_atom_pointer(struct atom_table *table, const char *string, size_t len,
  115. xkb_atom_t **atomp_out, unsigned int *fingerprint_out)
  116. {
  117. xkb_atom_t *atomp = &table->root;
  118. unsigned int fingerprint = 0;
  119. bool found = false;
  120. for (size_t i = 0; i < (len + 1) / 2; i++) {
  121. fingerprint = fingerprint * 27 + string[i];
  122. fingerprint = fingerprint * 27 + string[len - 1 - i];
  123. }
  124. while (*atomp != XKB_ATOM_NONE) {
  125. struct atom_node *node = &darray_item(table->table, *atomp);
  126. if (fingerprint < node->fingerprint) {
  127. atomp = &node->left;
  128. }
  129. else if (fingerprint > node->fingerprint) {
  130. atomp = &node->right;
  131. }
  132. else {
  133. /* Now start testing the strings. */
  134. const int cmp = strncmp(string, node->string, len);
  135. if (cmp < 0 || (cmp == 0 && len < strlen(node->string))) {
  136. atomp = &node->left;
  137. }
  138. else if (cmp > 0) {
  139. atomp = &node->right;
  140. }
  141. else {
  142. found = true;
  143. break;
  144. }
  145. }
  146. }
  147. if (fingerprint_out)
  148. *fingerprint_out = fingerprint;
  149. if (atomp_out)
  150. *atomp_out = atomp;
  151. return found;
  152. }
  153. xkb_atom_t
  154. atom_lookup(struct atom_table *table, const char *string, size_t len)
  155. {
  156. xkb_atom_t *atomp;
  157. if (!string)
  158. return XKB_ATOM_NONE;
  159. if (!find_atom_pointer(table, string, len, &atomp, NULL))
  160. return XKB_ATOM_NONE;
  161. return *atomp;
  162. }
  163. /*
  164. * If steal is true, we do not strdup @string; therefore it must be
  165. * dynamically allocated, NUL-terminated, not be free'd by the caller
  166. * and not be used afterwards. Use to avoid some redundant allocations.
  167. */
  168. xkb_atom_t
  169. atom_intern(struct atom_table *table, const char *string, size_t len,
  170. bool steal)
  171. {
  172. xkb_atom_t *atomp;
  173. struct atom_node node;
  174. unsigned int fingerprint;
  175. if (!string)
  176. return XKB_ATOM_NONE;
  177. if (find_atom_pointer(table, string, len, &atomp, &fingerprint)) {
  178. if (steal)
  179. free(UNCONSTIFY(string));
  180. return *atomp;
  181. }
  182. if (steal) {
  183. node.string = UNCONSTIFY(string);
  184. }
  185. else {
  186. node.string = strndup(string, len);
  187. if (!node.string)
  188. return XKB_ATOM_NONE;
  189. }
  190. node.left = node.right = XKB_ATOM_NONE;
  191. node.fingerprint = fingerprint;
  192. node.atom = darray_size(table->table);
  193. /* Do this before the append, as it may realloc and change the offsets. */
  194. *atomp = node.atom;
  195. darray_append(table->table, node);
  196. return node.atom;
  197. }