PageRenderTime 4028ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/gcc/d/dfrontend/array.c

http://github.com/D-Programming-GDC/GDC
C | 257 lines | 205 code | 39 blank | 13 comment | 25 complexity | 6d704c0bdf5f9d79bfdde036bce3551e 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 "dchar.h"
  36. #include "rmem.h"
  37. /********************************* Array ****************************/
  38. Array::Array()
  39. {
  40. data = SMALLARRAYCAP ? &smallarray[0] : NULL;
  41. dim = 0;
  42. allocdim = SMALLARRAYCAP;
  43. }
  44. Array::~Array()
  45. {
  46. if (data != &smallarray[0])
  47. mem.free(data);
  48. }
  49. void Array::mark()
  50. { unsigned u;
  51. mem.mark(data);
  52. for (u = 0; u < dim; u++)
  53. mem.mark(data[u]); // BUG: what if arrays of Object's?
  54. }
  55. void Array::reserve(unsigned nentries)
  56. {
  57. //printf("Array::reserve: dim = %d, allocdim = %d, nentries = %d\n", dim, allocdim, nentries);
  58. if (allocdim - dim < nentries)
  59. {
  60. if (allocdim == 0)
  61. { // Not properly initialized, someone memset it to zero
  62. if (nentries <= SMALLARRAYCAP)
  63. { allocdim = SMALLARRAYCAP;
  64. data = SMALLARRAYCAP ? &smallarray[0] : NULL;
  65. }
  66. else
  67. { allocdim = nentries;
  68. data = (void **)mem.malloc(allocdim * sizeof(*data));
  69. }
  70. }
  71. else if (allocdim == SMALLARRAYCAP)
  72. {
  73. allocdim = dim + nentries;
  74. data = (void **)mem.malloc(allocdim * sizeof(*data));
  75. memcpy(data, &smallarray[0], dim * sizeof(*data));
  76. }
  77. else
  78. { allocdim = dim + nentries;
  79. data = (void **)mem.realloc(data, allocdim * sizeof(*data));
  80. }
  81. }
  82. }
  83. void Array::setDim(unsigned newdim)
  84. {
  85. if (dim < newdim)
  86. {
  87. reserve(newdim - dim);
  88. }
  89. dim = newdim;
  90. }
  91. void Array::fixDim()
  92. {
  93. if (dim != allocdim)
  94. {
  95. if (allocdim >= SMALLARRAYCAP)
  96. {
  97. if (dim <= SMALLARRAYCAP)
  98. {
  99. memcpy(&smallarray[0], data, dim * sizeof(*data));
  100. mem.free(data);
  101. }
  102. else
  103. data = (void **)mem.realloc(data, dim * sizeof(*data));
  104. }
  105. allocdim = dim;
  106. }
  107. }
  108. void Array::push(void *ptr)
  109. {
  110. reserve(1);
  111. data[dim++] = ptr;
  112. }
  113. void *Array::pop()
  114. {
  115. return data[--dim];
  116. }
  117. void Array::shift(void *ptr)
  118. {
  119. reserve(1);
  120. memmove(data + 1, data, dim * sizeof(*data));
  121. data[0] = ptr;
  122. dim++;
  123. }
  124. void Array::insert(unsigned index, void *ptr)
  125. {
  126. reserve(1);
  127. memmove(data + index + 1, data + index, (dim - index) * sizeof(*data));
  128. data[index] = ptr;
  129. dim++;
  130. }
  131. void Array::insert(unsigned index, Array *a)
  132. {
  133. if (a)
  134. { unsigned d;
  135. d = a->dim;
  136. reserve(d);
  137. if (dim != index)
  138. memmove(data + index + d, data + index, (dim - index) * sizeof(*data));
  139. memcpy(data + index, a->data, d * sizeof(*data));
  140. dim += d;
  141. }
  142. }
  143. /***********************************
  144. * Append array a to this array.
  145. */
  146. void Array::append(Array *a)
  147. {
  148. insert(dim, a);
  149. }
  150. void Array::remove(unsigned i)
  151. {
  152. if (dim - i - 1)
  153. memmove(data + i, data + i + 1, (dim - i - 1) * sizeof(data[0]));
  154. dim--;
  155. }
  156. char *Array::toChars()
  157. {
  158. unsigned len;
  159. unsigned u;
  160. char **buf;
  161. char *str;
  162. char *p;
  163. buf = (char **)malloc(dim * sizeof(char *));
  164. assert(buf);
  165. len = 2;
  166. for (u = 0; u < dim; u++)
  167. {
  168. buf[u] = ((Object *)data[u])->toChars();
  169. len += strlen(buf[u]) + 1;
  170. }
  171. str = (char *)mem.malloc(len);
  172. str[0] = '[';
  173. p = str + 1;
  174. for (u = 0; u < dim; u++)
  175. {
  176. if (u)
  177. *p++ = ',';
  178. len = strlen(buf[u]);
  179. memcpy(p,buf[u],len);
  180. p += len;
  181. }
  182. *p++ = ']';
  183. *p = 0;
  184. free(buf);
  185. return str;
  186. }
  187. void Array::zero()
  188. {
  189. memset(data,0,dim * sizeof(data[0]));
  190. }
  191. void *Array::tos()
  192. {
  193. return dim ? data[dim - 1] : NULL;
  194. }
  195. int
  196. #if _WIN32
  197. __cdecl
  198. #endif
  199. Array_sort_compare(const void *x, const void *y)
  200. {
  201. Object *ox = *(Object **)x;
  202. Object *oy = *(Object **)y;
  203. return ox->compare(oy);
  204. }
  205. void Array::sort()
  206. {
  207. if (dim)
  208. {
  209. qsort(data, dim, sizeof(Object *), Array_sort_compare);
  210. }
  211. }
  212. Array *Array::copy()
  213. {
  214. Array *a = new Array();
  215. a->setDim(dim);
  216. memcpy(a->data, data, dim * sizeof(void *));
  217. return a;
  218. }