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