Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
2.7 KiB

  1. /* Copyright (C) Boris Nikolaus, Germany, 1996-1997. All rights reserved. */
  2. /* Copyright (C) Microsoft Corporation, 1997-1998. All rights reserved. */
  3. #include "precomp.h"
  4. /* get length of a singly linked list */
  5. size_t SLlength(void *head, size_t offset)
  6. {
  7. size_t nelem = 0;
  8. while (head) {
  9. /*LINTED*/
  10. head = *(void **)((char *)head + offset);
  11. nelem++;
  12. }
  13. return nelem;
  14. }
  15. /* search for an element in a singly linked list */
  16. int SLcontains(void *head, size_t offset, void *elem)
  17. {
  18. while (head) {
  19. if (head == elem)
  20. return 1;
  21. /*LINTED pointer cast may result in improper alignment*/
  22. head = *(void **)((char *)head + offset);
  23. }
  24. return 0;
  25. }
  26. /* copy elements of a singly linked list into an array */
  27. void SLtoA(void *head, size_t offset, size_t elemsize, void **base, size_t *nelem)
  28. {
  29. void *p;
  30. *nelem = SLlength(head, offset);
  31. if (!*nelem) {
  32. *base = NULL;
  33. return;
  34. }
  35. p = *base = malloc(*nelem * elemsize);
  36. /*LINTED*/
  37. for (; head; head = *(void **)((char *)head + offset)) {
  38. memcpy(p, head, elemsize);
  39. p = (void *)((char *)p + elemsize);
  40. }
  41. }
  42. /* copy pointers to elements of a singly linked list into an array */
  43. void SLtoAP(void *head, size_t offset, void ***base, size_t *nelem)
  44. {
  45. void **p;
  46. *nelem = SLlength(head, offset);
  47. if (!*nelem) {
  48. *base = NULL;
  49. return;
  50. }
  51. p = *base = (void **)malloc(*nelem * sizeof(void *));
  52. /*LINTED*/
  53. for (; head; head = *(void **)((char *)head + offset)) {
  54. *p++ = head;
  55. }
  56. }
  57. /* copy elements of an array into a singly linked list */
  58. void AtoSL(void *base, size_t offset, size_t nelem, size_t elemsize, void **head)
  59. {
  60. while (nelem--) {
  61. *head = malloc(elemsize);
  62. memcpy(*head, base, elemsize);
  63. base = (void *)((char *)base + elemsize);
  64. /*LINTED*/
  65. head = (void **)((char *)*head + offset);
  66. }
  67. *head = NULL;
  68. }
  69. /* user defined compare function of qsortSL */
  70. static int (*qsortSL_CmpFnCb)(const void *, const void *, void *);
  71. static void *qsortSL_Context;
  72. /* compare function of qsortSL */
  73. static int __cdecl qsortSL_CmpFn(const void *p1, const void *p2)
  74. {
  75. return qsortSL_CmpFnCb(*(void **)p1, *(void **)p2, qsortSL_Context);
  76. }
  77. /* sort a singly linked list */
  78. void qsortSL(void **head, size_t offset, int (*cmpfn)(const void *, const void *, void *), void *context)
  79. {
  80. void **base, **p;
  81. size_t nelem;
  82. SLtoAP(*head, offset, &base, &nelem);
  83. qsortSL_CmpFnCb = cmpfn;
  84. qsortSL_Context = context;
  85. qsort(base, nelem, sizeof(void *), qsortSL_CmpFn);
  86. p = base;
  87. while (nelem--) {
  88. *head = *p++;
  89. /*LINTED*/
  90. head = (void **)((char *)*head + offset);
  91. }
  92. *head = NULL;
  93. free(base);
  94. }