PageRenderTime 60ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/gcc/d/dfrontend/array.c

https://github.com/DW8Reaper/GDC
C | 256 lines | 204 code | 39 blank | 13 comment | 25 complexity | 1b145279bed1264a521a19449f4e8bf0 MD5 | raw file
Possible License(s): AGPL-1.0
  1. // Copyright (c) 1999-2010 by Digital Mars
  2. // All Rights Reserved
  3. // written by Walter Bright
  4. // http://www.digitalmars.com
  5. // License for redistribution is by either the Artistic License
  6. // in artistic.txt, or the GNU General Public License in gnu.txt.
  7. // See the included readme.txt for details.
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <stdarg.h>
  11. #include <string.h>
  12. #include <assert.h>
  13. #if (defined (__SVR4) && defined (__sun))
  14. #include <alloca.h>
  15. #endif
  16. #if _MSC_VER || __MINGW32__
  17. #include <malloc.h>
  18. #endif
  19. #ifdef IN_GCC
  20. #include "gdc_alloca.h"
  21. #endif
  22. #if _WIN32
  23. #include <windows.h>
  24. #endif
  25. #ifndef _WIN32
  26. #include <sys/types.h>
  27. #include <sys/stat.h>
  28. #include <fcntl.h>
  29. #include <errno.h>
  30. #include <unistd.h>
  31. #include <utime.h>
  32. #endif
  33. //#include "port.h"
  34. #include "root.h"
  35. #include "rmem.h"
  36. /********************************* Array ****************************/
  37. Array::Array()
  38. {
  39. data = SMALLARRAYCAP ? &smallarray[0] : NULL;
  40. dim = 0;
  41. allocdim = SMALLARRAYCAP;
  42. }
  43. Array::~Array()
  44. {
  45. if (data != &smallarray[0])
  46. mem.free(data);
  47. }
  48. void Array::mark()
  49. { unsigned u;
  50. mem.mark(data);
  51. for (u = 0; u < dim; u++)
  52. mem.mark(data[u]); // BUG: what if arrays of Object's?
  53. }
  54. void Array::reserve(unsigned nentries)
  55. {
  56. //printf("Array::reserve: dim = %d, allocdim = %d, nentries = %d\n", dim, allocdim, nentries);
  57. if (allocdim - dim < nentries)
  58. {
  59. if (allocdim == 0)
  60. { // Not properly initialized, someone memset it to zero
  61. if (nentries <= SMALLARRAYCAP)
  62. { allocdim = SMALLARRAYCAP;
  63. data = SMALLARRAYCAP ? &smallarray[0] : NULL;
  64. }
  65. else
  66. { allocdim = nentries;
  67. data = (void **)mem.malloc(allocdim * sizeof(*data));
  68. }
  69. }
  70. else if (allocdim == SMALLARRAYCAP)
  71. {
  72. allocdim = dim + nentries;
  73. data = (void **)mem.malloc(allocdim * sizeof(*data));
  74. memcpy(data, &smallarray[0], dim * sizeof(*data));
  75. }
  76. else
  77. { allocdim = dim + nentries;
  78. data = (void **)mem.realloc(data, allocdim * sizeof(*data));
  79. }
  80. }
  81. }
  82. void Array::setDim(unsigned newdim)
  83. {
  84. if (dim < newdim)
  85. {
  86. reserve(newdim - dim);
  87. }
  88. dim = newdim;
  89. }
  90. void Array::fixDim()
  91. {
  92. if (dim != allocdim)
  93. {
  94. if (allocdim >= SMALLARRAYCAP)
  95. {
  96. if (dim <= SMALLARRAYCAP)
  97. {
  98. memcpy(&smallarray[0], data, dim * sizeof(*data));
  99. mem.free(data);
  100. }
  101. else
  102. data = (void **)mem.realloc(data, dim * sizeof(*data));
  103. }
  104. allocdim = dim;
  105. }
  106. }
  107. void Array::push(void *ptr)
  108. {
  109. reserve(1);
  110. data[dim++] = ptr;
  111. }
  112. void *Array::pop()
  113. {
  114. return data[--dim];
  115. }
  116. void Array::shift(void *ptr)
  117. {
  118. reserve(1);
  119. memmove(data + 1, data, dim * sizeof(*data));
  120. data[0] = ptr;
  121. dim++;
  122. }
  123. void Array::insert(unsigned index, void *ptr)
  124. {
  125. reserve(1);
  126. memmove(data + index + 1, data + index, (dim - index) * sizeof(*data));
  127. data[index] = ptr;
  128. dim++;
  129. }
  130. void Array::insert(unsigned index, Array *a)
  131. {
  132. if (a)
  133. { unsigned d;
  134. d = a->dim;
  135. reserve(d);
  136. if (dim != index)
  137. memmove(data + index + d, data + index, (dim - index) * sizeof(*data));
  138. memcpy(data + index, a->data, d * sizeof(*data));
  139. dim += d;
  140. }
  141. }
  142. /***********************************
  143. * Append array a to this array.
  144. */
  145. void Array::append(Array *a)
  146. {
  147. insert(dim, a);
  148. }
  149. void Array::remove(unsigned i)
  150. {
  151. if (dim - i - 1)
  152. memmove(data + i, data + i + 1, (dim - i - 1) * sizeof(data[0]));
  153. dim--;
  154. }
  155. char *Array::toChars()
  156. {
  157. unsigned len;
  158. unsigned u;
  159. char **buf;
  160. char *str;
  161. char *p;
  162. buf = (char **)malloc(dim * sizeof(char *));
  163. assert(buf);
  164. len = 2;
  165. for (u = 0; u < dim; u++)
  166. {
  167. buf[u] = ((Object *)data[u])->toChars();
  168. len += strlen(buf[u]) + 1;
  169. }
  170. str = (char *)mem.malloc(len);
  171. str[0] = '[';
  172. p = str + 1;
  173. for (u = 0; u < dim; u++)
  174. {
  175. if (u)
  176. *p++ = ',';
  177. len = strlen(buf[u]);
  178. memcpy(p,buf[u],len);
  179. p += len;
  180. }
  181. *p++ = ']';
  182. *p = 0;
  183. free(buf);
  184. return str;
  185. }
  186. void Array::zero()
  187. {
  188. memset(data,0,dim * sizeof(data[0]));
  189. }
  190. void *Array::tos()
  191. {
  192. return dim ? data[dim - 1] : NULL;
  193. }
  194. int
  195. #if _WIN32
  196. __cdecl
  197. #endif
  198. Array_sort_compare(const void *x, const void *y)
  199. {
  200. Object *ox = *(Object **)x;
  201. Object *oy = *(Object **)y;
  202. return ox->compare(oy);
  203. }
  204. void Array::sort()
  205. {
  206. if (dim)
  207. {
  208. qsort(data, dim, sizeof(Object *), Array_sort_compare);
  209. }
  210. }
  211. Array *Array::copy()
  212. {
  213. Array *a = new Array();
  214. a->setDim(dim);
  215. memcpy(a->data, data, dim * sizeof(void *));
  216. return a;
  217. }