1 /********************************************************************/
2 /* */
3 /* arr_rtl.c Primitive actions for the array type. */
4 /* Copyright (C) 1989 - 2016, 2018, 2019 Thomas Mertes */
5 /* */
6 /* This file is part of the Seed7 Runtime Library. */
7 /* */
8 /* The Seed7 Runtime Library is free software; you can */
9 /* redistribute it and/or modify it under the terms of the GNU */
10 /* Lesser General Public License as published by the Free Software */
11 /* Foundation; either version 2.1 of the License, or (at your */
12 /* option) any later version. */
13 /* */
14 /* The Seed7 Runtime Library is distributed in the hope that it */
15 /* will be useful, but WITHOUT ANY WARRANTY; without even the */
16 /* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR */
17 /* PURPOSE. See the GNU Lesser General Public License for more */
18 /* details. */
19 /* */
20 /* You should have received a copy of the GNU Lesser General */
21 /* Public License along with this program; if not, write to the */
22 /* Free Software Foundation, Inc., 51 Franklin Street, */
23 /* Fifth Floor, Boston, MA 02110-1301, USA. */
24 /* */
25 /* Module: Seed7 Runtime Library */
26 /* File: seed7/src/arr_rtl.c */
27 /* Changes: 1991 - 1994, 2005, 2006, 2013 Thomas Mertes */
28 /* Content: Primitive actions for the array type. */
29 /* */
30 /* The functions from this file should only be used in compiled */
31 /* Seed7 programs. The interpreter should not use functions of */
32 /* this file. */
33 /* */
34 /* The functions in this file use type declarations from the */
35 /* include file data_rtl.h instead of data.h. Therefore the types */
36 /* rtlArrayType and rtlObjectType are declared different than the */
37 /* types arrayType and objectType in the interpreter. */
38 /* */
39 /********************************************************************/
40
41 #define LOG_FUNCTIONS 0
42 #define VERBOSE_EXCEPTIONS 0
43
44 #include "version.h"
45
46 #include "stdlib.h"
47 #include "stdio.h"
48 #include "string.h"
49
50 #include "common.h"
51 #include "data_rtl.h"
52 #include "os_decls.h"
53 #include "heaputl.h"
54 #include "striutl.h"
55 #include "str_rtl.h"
56 #include "cmd_rtl.h"
57 #include "cmd_drv.h"
58 #include "rtl_err.h"
59
60 #undef EXTERN
61 #define EXTERN
62 #include "arr_rtl.h"
63
64
65 #define QSORT_LIMIT 8
66
67
68
69 #if ANY_LOG_ACTIVE
70 #ifdef USE_WMAIN
printArgv(const int argc,const wstriType * const argv)71 static void printArgv (const int argc, const wstriType *const argv)
72 #else
73 static void printArgv (const int argc, const cstriType *const argv)
74 #endif
75
76 {
77 int pos;
78
79 /* printArgv */
80 if (argv == NULL) {
81 printf("NULL");
82 } else {
83 printf("{");
84 for (pos = 0; pos <= argc; pos++) {
85 if (pos != 0) {
86 printf(", ");
87 } /* if */
88 #ifdef USE_WMAIN
89 printf("\"" FMT_S_OS "\"", argv[pos]);
90 #else
91 printf("\"%s\"", argv[pos]);
92 #endif
93 } /* for */
94 printf("}");
95 }
96 } /* printArgv */
97 #endif
98
99
100
101 /**
102 * Sort an array of 'rtlObjectType' elements with the quicksort algorithm.
103 * In contrast to qsort() this function uses a different compare function.
104 * The compare function of qsort() has two void pointers as parameters.
105 * @param begin_sort Pointer to first element to be sorted.
106 * @param end_sort Pointer to the last element to be sorted.
107 * @param cmp_func Pointer to a compare function that gets two values as
108 * 'genericType' and compares them.
109 */
rtl_qsort_array(rtlObjectType * begin_sort,rtlObjectType * end_sort,compareType cmp_func)110 static void rtl_qsort_array (rtlObjectType *begin_sort, rtlObjectType *end_sort,
111 compareType cmp_func)
112
113 {
114 genericType compare_elem;
115 genericType help_element;
116 rtlObjectType *middle_elem;
117 rtlObjectType *less_elem;
118 rtlObjectType *greater_elem;
119 intType cmp;
120
121 /* rtl_qsort_array */
122 if (end_sort - begin_sort < QSORT_LIMIT) {
123 /* Use insertion sort */
124 for (middle_elem = begin_sort + 1; middle_elem <= end_sort; middle_elem++) {
125 compare_elem = middle_elem->value.genericValue;
126 less_elem = begin_sort - 1;
127 do {
128 less_elem++;
129 cmp = cmp_func(less_elem->value.genericValue, compare_elem);
130 } while (cmp < 0);
131 memmove(&less_elem[1], less_elem, (memSizeType)
132 (middle_elem - less_elem) * sizeof(rtlObjectType));
133 less_elem->value.genericValue = compare_elem;
134 } /* for */
135 } else {
136 middle_elem = &begin_sort[((memSizeType)(end_sort - begin_sort)) >> 1];
137 compare_elem = middle_elem->value.genericValue;
138 middle_elem->value.genericValue = end_sort->value.genericValue;
139 end_sort->value.genericValue = compare_elem;
140 less_elem = begin_sort - 1;
141 greater_elem = end_sort;
142 do {
143 do {
144 less_elem++;
145 cmp = cmp_func(less_elem->value.genericValue, compare_elem);
146 } while (cmp < 0);
147 do {
148 greater_elem--;
149 cmp = cmp_func(greater_elem->value.genericValue, compare_elem);
150 } while (cmp > 0 && greater_elem != begin_sort);
151 help_element = less_elem->value.genericValue;
152 less_elem->value.genericValue = greater_elem->value.genericValue;
153 greater_elem->value.genericValue = help_element;
154 } while (greater_elem > less_elem);
155 greater_elem->value.genericValue = less_elem->value.genericValue;
156 less_elem->value.genericValue = compare_elem;
157 end_sort->value.genericValue = help_element;
158 rtl_qsort_array(begin_sort, less_elem - 1, cmp_func);
159 rtl_qsort_array(less_elem + 1, end_sort, cmp_func);
160 } /* if */
161 } /* rtl_qsort_array */
162
163
164
165 /**
166 * Get the name of the program without path and extension.
167 * @param arg_0 Parameter argv[0] from the function main() as string.
168 * @return the name of the program.
169 */
getProgramName(const const_striType arg_0)170 static striType getProgramName (const const_striType arg_0)
171
172 {
173 memSizeType name_len;
174 #if defined LINKED_PROGRAM_EXTENSION || defined EXECUTABLE_FILE_EXTENSION
175 striType exeExtension;
176 #endif
177 intType lastSlashPos;
178 striType program_name;
179
180 /* getProgramName */
181 logFunction(printf("getProgramName(\"%s\")",
182 striAsUnquotedCStri(arg_0));
183 fflush(stdout););
184 name_len = arg_0->size;
185 #if defined LINKED_PROGRAM_EXTENSION || defined EXECUTABLE_FILE_EXTENSION
186 #ifdef LINKED_PROGRAM_EXTENSION
187 exeExtension = CSTRI_LITERAL_TO_STRI(LINKED_PROGRAM_EXTENSION);
188 #else
189 exeExtension = CSTRI_LITERAL_TO_STRI(EXECUTABLE_FILE_EXTENSION);
190 #endif
191 if (name_len > exeExtension->size &&
192 memcmp(&arg_0->mem[arg_0->size - exeExtension->size],
193 exeExtension->mem, exeExtension->size * sizeof(strElemType)) == 0) {
194 name_len -= exeExtension->size;
195 } /* if */
196 FREE_STRI(exeExtension, exeExtension->size);
197 #endif
198 lastSlashPos = strRChPos(arg_0, (charType) '/');
199 name_len -= (memSizeType) lastSlashPos;
200 if (ALLOC_STRI_SIZE_OK(program_name, name_len)) {
201 program_name->size = name_len;
202 memcpy(program_name->mem, &arg_0->mem[lastSlashPos],
203 name_len * sizeof(strElemType));
204 } /* if */
205 logFunctionResult(printf("\"%s\"\n", striAsUnquotedCStri(program_name)););
206 return program_name;
207 } /* getProgramName */
208
209
210
211 /**
212 * Copy the arguments from argv to an array of strings.
213 * @param argv Parameter from the function main().
214 */
copyArgv(const int argc,const os_striType * const argv)215 static rtlArrayType copyArgv (const int argc, const os_striType *const argv)
216
217 {
218 memSizeType arg_c;
219 rtlArrayType arg_v;
220 memSizeType number;
221 errInfoType err_info = OKAY_NO_ERROR;
222 striType stri;
223
224 /* copyArgv */
225 logFunction(printf("copyArgv(%d, ...)\n", argc););
226 if (unlikely(argc < 0)) {
227 logError(printf("copyArgv(%d, ...): Argc is negative.\n",
228 argc););
229 raise_error(RANGE_ERROR);
230 arg_v = NULL;
231 } else {
232 arg_c = (memSizeType) (argc);
233 if (unlikely(!ALLOC_RTL_ARRAY(arg_v, arg_c))) {
234 raise_error(MEMORY_ERROR);
235 } else {
236 arg_v->min_position = 1;
237 arg_v->max_position = (intType) (arg_c);
238 for (number = 0; number < arg_c; number++) {
239 stri = os_stri_to_stri(argv[number], &err_info);
240 if (likely(stri != NULL)) {
241 arg_v->arr[number].value.striValue = stri;
242 } else {
243 while (number >= 1) {
244 number--;
245 stri = arg_v->arr[number].value.striValue;
246 FREE_STRI(stri, stri->size);
247 } /* while */
248 FREE_RTL_ARRAY(arg_v, arg_c);
249 logError(printf("copyArgv(%d, ...): "
250 "os_stri_to_stri(\"" FMT_S_OS "\", *) failed:\n"
251 "err_info=%d\n",
252 argc, argv[number], err_info););
253 raise_error(err_info);
254 arg_v = NULL;
255 number = arg_c; /* leave for-loop */
256 } /* if */
257 } /* for */
258 } /* if */
259 } /* if */
260 logFunction(printf("copyArgv -->\n"););
261 return arg_v;
262 } /* copyArgv */
263
264
265
266 /**
267 * Get the Seed7 argument vector of a program.
268 * The name of the program is not part of the Seed7 argument vector.
269 * @param argc Parameter from the function main().
270 * @param argv Parameter from the function main().
271 * @param arg_0 NULL or address to which argv[0] is copied.
272 * @param programName NULL or address to which the program name
273 * (without path and extension) is copied.
274 * @param exePath NULL or address to which the absolute path of the
275 * executable is copied (symbolic links of the path are resolved).
276 * @return an array with the argument vector.
277 */
278 #ifdef USE_WMAIN
getArgv(const int argc,const wstriType * const argv,striType * arg_0,striType * programName,striType * exePath)279 rtlArrayType getArgv (const int argc, const wstriType *const argv,
280 striType *arg_0, striType *programName, striType *exePath)
281
282 {
283 errInfoType err_info = OKAY_NO_ERROR;
284 striType arg_0_temp;
285 rtlArrayType arg_v;
286
287 /* getArgv */
288 logFunction(printf("getArgv(%d, ", argc);
289 printArgv(argc, argv);
290 printf(", %s", arg_0 != NULL ? "*" : "NULL");
291 printf(", %s", programName != NULL ? "*" : "NULL");
292 printf(", %s)\n", exePath != NULL ? "*" : "NULL"););
293 #if EMULATE_ROOT_CWD
294 initEmulatedCwd(&err_info);
295 if (unlikely(err_info != OKAY_NO_ERROR)) {
296 logError(printf("getArgv(%d, ...): initEmulatedCwd(*) failed:\n"
297 "err_info=%d\n",
298 argc, err_info););
299 raise_error(err_info);
300 arg_v = NULL;
301 } else
302 #endif
303 {
304 arg_0_temp = cp_from_os_path(argv[0], &err_info);
305 if (unlikely(arg_0_temp == NULL)) {
306 logError(printf("getArgv(%d, ...): "
307 "cp_from_os_path(\"%ls\", *) failed:\n"
308 "err_info=%d\n",
309 argc, argv[0], err_info););
310 } else {
311 if (programName != NULL) {
312 *programName = getProgramName(arg_0_temp);
313 if (*programName == NULL) {
314 err_info = MEMORY_ERROR;
315 } /* if */
316 } /* if */
317 if (exePath != NULL) {
318 *exePath = getExecutablePath(arg_0_temp);
319 if (*exePath == NULL) {
320 err_info = MEMORY_ERROR;
321 } /* if */
322 } /* if */
323 if (arg_0 != NULL) {
324 *arg_0 = arg_0_temp;
325 } else {
326 FREE_STRI(arg_0_temp, arg_0_temp->size);
327 } /* if */
328 } /* if */
329 if (unlikely(err_info != OKAY_NO_ERROR)) {
330 raise_error(err_info);
331 arg_v = NULL;
332 } else {
333 arg_v = copyArgv(argc - 1, &argv[1]);
334 } /* if */
335 }
336 logFunction(printf("getArgv(%d, ", argc);
337 printArgv(argc, argv);
338 printf(", \"%s\"",
339 striAsUnquotedCStri(arg_0 != NULL ? *arg_0 : NULL));
340 printf(", \"%s\"",
341 striAsUnquotedCStri(programName != NULL ? *programName : NULL));
342 printf(", \"%s\") -->\n",
343 striAsUnquotedCStri(exePath != NULL ? *exePath : NULL)));
344 return arg_v;
345 } /* getArgv */
346
347 #elif defined OS_STRI_WCHAR
348
349
350
getArgv(const int argc,const cstriType * const argv,striType * arg_0,striType * programName,striType * exePath)351 rtlArrayType getArgv (const int argc, const cstriType *const argv,
352 striType *arg_0, striType *programName, striType *exePath)
353
354 {
355 int w_argc;
356 os_striType *w_argv;
357 errInfoType err_info = OKAY_NO_ERROR;
358 striType arg_0_temp;
359 rtlArrayType arg_v;
360
361 /* getArgv */
362 logFunction(printf("getArgv(%d, ", argc);
363 printArgv(argc, argv);
364 printf(", %s", arg_0 != NULL ? "*" : "NULL");
365 printf(", %s", programName != NULL ? "*" : "NULL");
366 printf(", %s)\n", exePath != NULL ? "*" : "NULL"););
367 #if EMULATE_ROOT_CWD
368 initEmulatedCwd(&err_info);
369 if (unlikely(err_info != OKAY_NO_ERROR)) {
370 logError(printf("getArgv(%d, ...): initEmulatedCwd(*) failed:\n"
371 "err_info=%d\n",
372 argc, err_info););
373 raise_error(err_info);
374 arg_v = NULL;
375 } else
376 #endif
377 {
378 w_argv = getUtf16Argv(&w_argc);
379 if (unlikely(w_argv == NULL)) {
380 raise_error(MEMORY_ERROR);
381 arg_v = NULL;
382 } else {
383 arg_0_temp = cp_from_os_path(w_argv[0], &err_info);
384 if (unlikely(arg_0_temp == NULL)) {
385 logError(printf("getArgv(%d, ...): "
386 "cp_from_os_path(\"" FMT_S_OS "\", *) failed:\n"
387 "err_info=%d\n",
388 argc, w_argv[0], err_info););
389 } else {
390 if (programName != NULL) {
391 *programName = getProgramName(arg_0_temp);
392 if (*programName == NULL) {
393 err_info = MEMORY_ERROR;
394 } /* if */
395 } /* if */
396 if (exePath != NULL) {
397 *exePath = getExecutablePath(arg_0_temp);
398 if (*exePath == NULL) {
399 err_info = MEMORY_ERROR;
400 } /* if */
401 } /* if */
402 if (arg_0 != NULL) {
403 *arg_0 = arg_0_temp;
404 } else {
405 FREE_STRI(arg_0_temp, arg_0_temp->size);
406 } /* if */
407 } /* if */
408 if (unlikely(err_info != OKAY_NO_ERROR)) {
409 raise_error(err_info);
410 arg_v = NULL;
411 } else {
412 arg_v = copyArgv(w_argc - 1, &w_argv[1]);
413 } /* if */
414 freeUtf16Argv(w_argv);
415 } /* if */
416 }
417 logFunction(printf("getArgv(%d, ", argc);
418 printArgv(argc, argv);
419 printf(", \"%s\"",
420 striAsUnquotedCStri(arg_0 != NULL ? *arg_0 : NULL));
421 printf(", \"%s\"",
422 striAsUnquotedCStri(programName != NULL ? *programName : NULL));
423 printf(", \"%s\") -->\n",
424 striAsUnquotedCStri(exePath != NULL ? *exePath : NULL)));
425 return arg_v;
426 } /* getArgv */
427
428 #else
429
430
431
getArgv(const int argc,const cstriType * const argv,striType * arg_0,striType * programName,striType * exePath)432 rtlArrayType getArgv (const int argc, const cstriType *const argv,
433 striType *arg_0, striType *programName, striType *exePath)
434
435 {
436 errInfoType err_info = OKAY_NO_ERROR;
437 striType arg_0_temp;
438 rtlArrayType arg_v;
439
440 /* getArgv */
441 logFunction(printf("getArgv(%d, ", argc);
442 printArgv(argc, argv);
443 printf(", %s", arg_0 != NULL ? "*" : "NULL");
444 printf(", %s", programName != NULL ? "*" : "NULL");
445 printf(", %s)\n", exePath != NULL ? "*" : "NULL"););
446 #if EMULATE_ROOT_CWD
447 initEmulatedCwd(&err_info);
448 if (unlikely(err_info != OKAY_NO_ERROR)) {
449 logError(printf("getArgv(%d, ...): initEmulatedCwd(*) failed:\n"
450 "err_info=%d\n",
451 argc, err_info););
452 raise_error(err_info);
453 arg_v = NULL;
454 } else
455 #endif
456 {
457 arg_0_temp = cp_from_os_path(argv[0], &err_info);
458 if (unlikely(arg_0_temp == NULL)) {
459 logError(printf("getArgv(%d, ...): "
460 "cp_from_os_path(\"%s\", *) failed:\n"
461 "err_info=%d\n",
462 argc, argv[0], err_info););
463 } else {
464 if (programName != NULL) {
465 *programName = getProgramName(arg_0_temp);
466 if (*programName == NULL) {
467 err_info = MEMORY_ERROR;
468 } /* if */
469 } /* if */
470 if (exePath != NULL) {
471 *exePath = getExecutablePath(arg_0_temp);
472 if (*exePath == NULL) {
473 err_info = MEMORY_ERROR;
474 } /* if */
475 } /* if */
476 if (arg_0 != NULL) {
477 *arg_0 = arg_0_temp;
478 } else {
479 FREE_STRI(arg_0_temp, arg_0_temp->size);
480 } /* if */
481 } /* if */
482 if (unlikely(err_info != OKAY_NO_ERROR)) {
483 raise_error(err_info);
484 arg_v = NULL;
485 } else {
486 arg_v = copyArgv(argc - 1, &argv[1]);
487 } /* if */
488 }
489 logFunction(printf("getArgv(%d, ", argc);
490 printArgv(argc, argv);
491 printf(", \"%s\"",
492 striAsUnquotedCStri(arg_0 != NULL ? *arg_0 : NULL));
493 printf(", \"%s\"",
494 striAsUnquotedCStri(programName != NULL ? *programName : NULL));
495 printf(", \"%s\") -->\n",
496 striAsUnquotedCStri(exePath != NULL ? *exePath : NULL)));
497 return arg_v;
498 } /* getArgv */
499
500 #endif
501
502
503
504 #ifndef OS_STRI_WCHAR
505 /**
506 * Examine all directories in the search path and look for fileName.
507 * @return the path to the executable, or
508 * NULL if it was not found.
509 */
examineSearchPath(const const_striType fileName)510 striType examineSearchPath (const const_striType fileName)
511
512 {
513 rtlArrayType searchPath;
514 memSizeType searchPathSize;
515 memSizeType pos;
516 striType aPath;
517 striType result;
518
519 /* examineSearchPath */
520 logFunction(printf("examineSearchPath\n"););
521 result = NULL;
522 searchPath = cmdGetSearchPath();
523 if (searchPath != NULL) {
524 searchPathSize = arraySize(searchPath);
525 for (pos = 0; result == NULL && pos < searchPathSize; pos++) {
526 aPath = searchPath->arr[pos].value.striValue;
527 if (aPath->size != 0 && aPath->mem[aPath->size - 1] != (charType) '/') {
528 strPush(&aPath, (charType) '/');
529 } /* if */
530 strAppend(&aPath, fileName);
531 if (cmdFileType(aPath) == FILE_REGULAR) {
532 result = aPath;
533 } else {
534 FREE_STRI(aPath, aPath->size);
535 } /* if */
536 } /* for */
537 for (; pos < searchPathSize; pos++) {
538 aPath = searchPath->arr[pos].value.striValue;
539 FREE_STRI(aPath, aPath->size);
540 } /* for */
541 FREE_RTL_ARRAY(searchPath, searchPathSize);
542 } /* if */
543 logFunction(printf("examineSearchPath --> \"%s\"\n",
544 striAsUnquotedCStri(result)););
545 return result;
546 } /* examineSearchPath */
547 #endif
548
549
550
freeRtlStriArray(rtlArrayType work_array,intType used_max_position)551 void freeRtlStriArray (rtlArrayType work_array, intType used_max_position)
552
553 {
554 memSizeType position;
555
556 /* freeRtlStriArray */
557 for (position = 0; position < (uintType) used_max_position; position++) {
558 FREE_STRI(work_array->arr[position].value.striValue,
559 work_array->arr[position].value.striValue->size);
560 } /* for */
561 FREE_RTL_ARRAY(work_array, (uintType) work_array->max_position);
562 } /* freeRtlStriArray */
563
564
565
566 /**
567 * Fill an array of 'len' objects with the generic value 'element'.
568 * This function uses loop unrolling inspired by Duff's device.
569 * The use of indices relative to pos allows the C compiler
570 * to do more optimizations.
571 * @param dest Destination array with object values.
572 * @param element Generic value to be filled into 'dest'.
573 * @param len Specifies how often 'element' is filled into 'dest'.
574 */
memsetGeneric(register rtlObjectType * const dest,register const genericType element,memSizeType len)575 static void memsetGeneric (register rtlObjectType *const dest,
576 register const genericType element, memSizeType len)
577
578 {
579 register memSizeType pos;
580
581 /* memsetGeneric */
582 if (len != 0) {
583 pos = (len + 31) & ~(memSizeType) 31;
584 switch (len & 31) {
585 do {
586 case 0: dest[pos - 1].value.genericValue = element;
587 case 31: dest[pos - 2].value.genericValue = element;
588 case 30: dest[pos - 3].value.genericValue = element;
589 case 29: dest[pos - 4].value.genericValue = element;
590 case 28: dest[pos - 5].value.genericValue = element;
591 case 27: dest[pos - 6].value.genericValue = element;
592 case 26: dest[pos - 7].value.genericValue = element;
593 case 25: dest[pos - 8].value.genericValue = element;
594 case 24: dest[pos - 9].value.genericValue = element;
595 case 23: dest[pos - 10].value.genericValue = element;
596 case 22: dest[pos - 11].value.genericValue = element;
597 case 21: dest[pos - 12].value.genericValue = element;
598 case 20: dest[pos - 13].value.genericValue = element;
599 case 19: dest[pos - 14].value.genericValue = element;
600 case 18: dest[pos - 15].value.genericValue = element;
601 case 17: dest[pos - 16].value.genericValue = element;
602 case 16: dest[pos - 17].value.genericValue = element;
603 case 15: dest[pos - 18].value.genericValue = element;
604 case 14: dest[pos - 19].value.genericValue = element;
605 case 13: dest[pos - 20].value.genericValue = element;
606 case 12: dest[pos - 21].value.genericValue = element;
607 case 11: dest[pos - 22].value.genericValue = element;
608 case 10: dest[pos - 23].value.genericValue = element;
609 case 9: dest[pos - 24].value.genericValue = element;
610 case 8: dest[pos - 25].value.genericValue = element;
611 case 7: dest[pos - 26].value.genericValue = element;
612 case 6: dest[pos - 27].value.genericValue = element;
613 case 5: dest[pos - 28].value.genericValue = element;
614 case 4: dest[pos - 29].value.genericValue = element;
615 case 3: dest[pos - 30].value.genericValue = element;
616 case 2: dest[pos - 31].value.genericValue = element;
617 case 1: dest[pos - 32].value.genericValue = element;
618 } while ((pos -= 32) != 0);
619 } /* switch */
620 } /* if */
621 } /* memsetGeneric */
622
623
624
625 /**
626 * Append the array 'extension' to the array 'arr_variable'.
627 * @exception MEMORY_ERROR Not enough memory for the concatenated
628 * array.
629 */
arrAppend(rtlArrayType * const arr_variable,const rtlArrayType extension)630 void arrAppend (rtlArrayType *const arr_variable, const rtlArrayType extension)
631
632 {
633 rtlArrayType arr_to;
634 memSizeType new_size;
635 memSizeType arr_to_size;
636 memSizeType extension_size;
637
638 /* arrAppend */
639 logFunction(printf("arrAppend(arr1 (size=" FMT_U_MEM "), arr2 (size=" FMT_U_MEM "))\n",
640 arraySize(*arr_variable), arraySize(extension)););
641 extension_size = arraySize(extension);
642 if (extension_size != 0) {
643 arr_to = *arr_variable;
644 arr_to_size = arraySize(arr_to);
645 if (unlikely(arr_to_size > MAX_RTL_ARR_LEN - extension_size ||
646 arr_to->max_position > (intType) (MAX_MEM_INDEX - extension_size))) {
647 raise_error(MEMORY_ERROR);
648 } else {
649 new_size = arr_to_size + extension_size;
650 arr_to = REALLOC_RTL_ARRAY(arr_to, arr_to_size, new_size);
651 if (unlikely(arr_to == NULL)) {
652 raise_error(MEMORY_ERROR);
653 } else {
654 COUNT3_RTL_ARRAY(arr_to_size, new_size);
655 *arr_variable = arr_to;
656 arr_to->max_position = arrayMaxPos(arr_to->min_position, new_size);
657 memcpy(&arr_to->arr[arr_to_size], extension->arr,
658 (size_t) (extension_size * sizeof(rtlObjectType)));
659 FREE_RTL_ARRAY(extension, extension_size);
660 } /* if */
661 } /* if */
662 } /* if */
663 logFunction(printf("arrAppend --> arr (size=" FMT_U_MEM ")\n",
664 arraySize(*arr_variable)););
665 } /* arrAppend */
666
667
668
arrArrlit2(intType start_position,rtlArrayType arr1)669 rtlArrayType arrArrlit2 (intType start_position, rtlArrayType arr1)
670
671 {
672 memSizeType result_size;
673
674 /* arrArrlit2 */
675 result_size = arraySize(arr1);
676 if (unlikely(start_position < MIN_MEM_INDEX ||
677 start_position > MAX_MEM_INDEX ||
678 (result_size != 0 &&
679 start_position > (intType) (MAX_MEM_INDEX - result_size + 1)) ||
680 (result_size == 0 && start_position == MIN_MEM_INDEX))) {
681 logError(printf("arrArrlit2(" FMT_D ", arr1 (size=" FMT_U_MEM ")): "
682 "Minimum or maximum index out of range.\n",
683 start_position, result_size););
684 raise_error(RANGE_ERROR);
685 arr1 = NULL;
686 } else {
687 arr1->min_position = start_position;
688 arr1->max_position = arrayMaxPos(start_position, result_size);
689 } /* if */
690 return arr1;
691 } /* arrArrlit2 */
692
693
694
arrBaselit(const genericType element)695 rtlArrayType arrBaselit (const genericType element)
696
697 {
698 memSizeType result_size;
699 rtlArrayType result;
700
701 /* arrBaselit */
702 result_size = 1;
703 if (unlikely(!ALLOC_RTL_ARRAY(result, result_size))) {
704 raise_error(MEMORY_ERROR);
705 } else {
706 result->min_position = 1;
707 result->max_position = 1;
708 result->arr[0].value.genericValue = element;
709 } /* if */
710 return result;
711 } /* arrBaselit */
712
713
714
arrBaselit2(intType start_position,const genericType element)715 rtlArrayType arrBaselit2 (intType start_position, const genericType element)
716
717 {
718 memSizeType result_size;
719 rtlArrayType result;
720
721 /* arrBaselit2 */
722 result_size = 1;
723 if (unlikely(!ALLOC_RTL_ARRAY(result, result_size))) {
724 raise_error(MEMORY_ERROR);
725 } else {
726 result->min_position = start_position;
727 result->max_position = start_position;
728 result->arr[0].value.genericValue = element;
729 } /* if */
730 return result;
731 } /* arrBaselit2 */
732
733
734
735 /**
736 * Concatenate two arrays.
737 * @return the result of the concatenation.
738 * @exception MEMORY_ERROR Not enough memory for the concatenated
739 * array.
740 */
arrCat(rtlArrayType arr1,const rtlArrayType arr2)741 rtlArrayType arrCat (rtlArrayType arr1, const rtlArrayType arr2)
742
743 {
744 memSizeType arr1_size;
745 memSizeType arr2_size;
746 memSizeType result_size;
747 rtlArrayType result;
748
749 /* arrCat */
750 arr1_size = arraySize(arr1);
751 arr2_size = arraySize(arr2);
752 if (unlikely(arr1_size > MAX_RTL_ARR_LEN - arr2_size ||
753 arr1->max_position > (intType) (MAX_MEM_INDEX - arr2_size))) {
754 raise_error(MEMORY_ERROR);
755 result = NULL;
756 } else {
757 result_size = arr1_size + arr2_size;
758 result = REALLOC_RTL_ARRAY(arr1, arr1_size, result_size);
759 if (unlikely(result == NULL)) {
760 raise_error(MEMORY_ERROR);
761 } else {
762 COUNT3_RTL_ARRAY(arr1_size, result_size);
763 result->max_position = arrayMaxPos(result->min_position, result_size);
764 memcpy(&result->arr[arr1_size], arr2->arr, arr2_size * sizeof(rtlObjectType));
765 FREE_RTL_ARRAY(arr2, arr2_size);
766 } /* if */
767 } /* if */
768 return result;
769 } /* arrCat */
770
771
772
773 /**
774 * Concatenate an array and an element.
775 * @return the result of the concatenation.
776 * @exception MEMORY_ERROR Not enough memory for the concatenated
777 * array.
778 */
arrExtend(rtlArrayType arr1,const genericType element)779 rtlArrayType arrExtend (rtlArrayType arr1, const genericType element)
780
781 {
782 memSizeType arr1_size;
783 memSizeType result_size;
784 rtlArrayType result;
785
786 /* arrExtend */
787 arr1_size = arraySize(arr1);
788 if (unlikely(arr1_size > MAX_RTL_ARR_LEN - 1 ||
789 arr1->max_position > (intType) (MAX_MEM_INDEX - 1))) {
790 raise_error(MEMORY_ERROR);
791 result = NULL;
792 } else {
793 result_size = arr1_size + 1;
794 result = REALLOC_RTL_ARRAY(arr1, arr1_size, result_size);
795 if (unlikely(result == NULL)) {
796 raise_error(MEMORY_ERROR);
797 } else {
798 COUNT3_RTL_ARRAY(arr1_size, result_size);
799 result->max_position++;
800 result->arr[arr1_size].value.genericValue = element;
801 } /* if */
802 } /* if */
803 return result;
804 } /* arrExtend */
805
806
807
808 /**
809 * Free the memory referred by 'oldArray'.
810 * This function is used by the compiler to define array destructor
811 * functions. It is asssumed that, before arrFree is called,
812 * destructors have been called for all elements of 'oldArray'.
813 * After arrFree is left 'oldArray' refers to not existing memory.
814 * The memory where 'oldArray' is stored can be freed afterwards.
815 */
arrFree(rtlArrayType oldArray)816 void arrFree (rtlArrayType oldArray)
817
818 {
819 memSizeType size;
820
821 /* arrFree */
822 size = arraySize(oldArray);
823 FREE_RTL_ARRAY(oldArray, size);
824 } /* arrFree */
825
826
827
828 /**
829 * Generate an array from the concatenation of two elements.
830 * @return the result of the concatenation.
831 * @exception MEMORY_ERROR Not enough memory for the concatenated
832 * array.
833 */
arrGen(const genericType element1,const genericType element2)834 rtlArrayType arrGen (const genericType element1, const genericType element2)
835
836 {
837 memSizeType result_size;
838 rtlArrayType result;
839
840 /* arrGen */
841 result_size = 2;
842 if (unlikely(!ALLOC_RTL_ARRAY(result, result_size))) {
843 raise_error(MEMORY_ERROR);
844 } else {
845 result->min_position = 1;
846 result->max_position = 2;
847 result->arr[0].value.genericValue = element1;
848 result->arr[1].value.genericValue = element2;
849 } /* if */
850 return result;
851 } /* arrGen */
852
853
854
855 /**
856 * Get a sub array ending at the position 'stop'.
857 * @return the sub array ending at the stop position.
858 * @exception INDEX_ERROR The stop position is less than pred(minIdx(arr1)).
859 * @exception MEMORY_ERROR Not enough memory to represent the result.
860 */
arrHead(const const_rtlArrayType arr1,intType stop)861 rtlArrayType arrHead (const const_rtlArrayType arr1, intType stop)
862
863 {
864 memSizeType arr1_size;
865 memSizeType result_size;
866 rtlArrayType result;
867
868 /* arrHead */
869 arr1_size = arraySize(arr1);
870 if (stop >= arr1->min_position && arr1_size >= 1) {
871 if (stop > arr1->max_position) {
872 stop = arr1->max_position;
873 } /* if */
874 result_size = arraySize2(arr1->min_position, stop);
875 if (unlikely(!ALLOC_RTL_ARRAY(result, result_size))) {
876 raise_error(MEMORY_ERROR);
877 } else {
878 result->min_position = arr1->min_position;
879 result->max_position = stop;
880 memcpy(result->arr, arr1->arr,
881 (size_t) (result_size * sizeof(rtlObjectType)));
882 } /* if */
883 } else if (unlikely(stop < arr1->min_position - 1)) {
884 logError(printf("arrHead(arr1 (minIdx=" FMT_D "), " FMT_D "): "
885 "Stop less than pred(minIdx(arr1)).\n",
886 arr1->min_position, stop););
887 raise_error(INDEX_ERROR);
888 result = NULL;
889 } else if (unlikely(arr1->min_position == MIN_MEM_INDEX)) {
890 logError(printf("arrHead(arr1 (size=" FMT_U_MEM "), " FMT_D "): "
891 "Cannot create empty array with minimum index.\n",
892 arr1_size, stop););
893 raise_error(RANGE_ERROR);
894 result = NULL;
895 } else {
896 if (unlikely(!ALLOC_RTL_ARRAY(result, 0))) {
897 raise_error(MEMORY_ERROR);
898 } else {
899 result->min_position = arr1->min_position;
900 result->max_position = arr1->min_position - 1;
901 } /* if */
902 } /* if */
903 return result;
904 } /* arrHead */
905
906
907
908 /**
909 * Get a sub array ending at the position 'stop'.
910 * ArrHeadTemp is used by the compiler if 'arr_temp' is a temporary
911 * value that can be reused.
912 * @return the sub array ending at the stop position.
913 * @exception INDEX_ERROR The stop position is less than pred(minIdx(arr1)).
914 * @exception MEMORY_ERROR Not enough memory to represent the result.
915 */
arrHeadTemp(rtlArrayType * arr_temp,intType stop)916 rtlArrayType arrHeadTemp (rtlArrayType *arr_temp, intType stop)
917
918 {
919 rtlArrayType arr1;
920 memSizeType arr1_size;
921 memSizeType result_size;
922 rtlArrayType new_arr1;
923 rtlArrayType result;
924
925 /* arrHeadTemp */
926 arr1 = *arr_temp;
927 arr1_size = arraySize(arr1);
928 if (stop >= arr1->min_position && arr1_size >= 1) {
929 if (stop >= arr1->max_position) {
930 result = arr1;
931 *arr_temp = NULL;
932 } else {
933 result_size = arraySize2(arr1->min_position, stop);
934 if (unlikely(!ALLOC_RTL_ARRAY(new_arr1, arr1_size - result_size))) {
935 raise_error(MEMORY_ERROR);
936 result = NULL;
937 } else {
938 new_arr1->min_position = stop + 1;
939 new_arr1->max_position = arr1->max_position;
940 memcpy(new_arr1->arr, &arr1->arr[result_size],
941 (size_t) ((arr1_size - result_size) * sizeof(rtlObjectType)));
942 result = REALLOC_RTL_ARRAY(arr1, arr1_size, result_size);
943 if (unlikely(result == NULL)) {
944 FREE_RTL_ARRAY(new_arr1, arr1_size - result_size);
945 raise_error(MEMORY_ERROR);
946 } else {
947 COUNT3_RTL_ARRAY(arr1_size, result_size);
948 result->max_position = stop;
949 *arr_temp = new_arr1;
950 } /* if */
951 } /* if */
952 } /* if */
953 } else if (unlikely(stop < arr1->min_position - 1)) {
954 logError(printf("arrHeadTemp(arr1 (minIdx=" FMT_U_MEM "), " FMT_D "): "
955 "Stop less than pred(minIdx(arr1)).\n",
956 arr1->min_position, stop););
957 raise_error(INDEX_ERROR);
958 result = NULL;
959 } else if (unlikely(arr1->min_position == MIN_MEM_INDEX)) {
960 logError(printf("arrHeadTemp(arr1 (size=" FMT_U_MEM "), " FMT_D "): "
961 "Cannot create empty array with minimum index.\n",
962 arr1_size, stop););
963 raise_error(RANGE_ERROR);
964 result = NULL;
965 } else {
966 if (unlikely(!ALLOC_RTL_ARRAY(result, 0))) {
967 raise_error(MEMORY_ERROR);
968 } else {
969 result->min_position = arr1->min_position;
970 result->max_position = arr1->min_position - 1;
971 } /* if */
972 } /* if */
973 return result;
974 } /* arrHeadTemp */
975
976
977
978 /**
979 * Access one element from the array 'arr_temp'.
980 * The compiler uses this function if the array is destroyed
981 * after the indexing. To avoid problems the indexed element is
982 * removed from the array.
983 * @return the element with the specified 'position' from 'arr_temp'.
984 * @exception INDEX_ERROR If 'position' is less than minIdx(arr) or
985 * greater than maxIdx(arr)
986 */
arrIdxTemp(rtlArrayType * arr_temp,intType position)987 genericType arrIdxTemp (rtlArrayType *arr_temp, intType position)
988
989 {
990 rtlArrayType arr1;
991 memSizeType arr1_size;
992 rtlArrayType resized_arr1;
993 genericType result;
994
995 /* arrIdxTemp */
996 arr1 = *arr_temp;
997 if (unlikely(position < arr1->min_position ||
998 position > arr1->max_position)) {
999 logError(printf("arrIdxTemp(arr1, " FMT_D "): "
1000 "Index out of range (" FMT_D " .. " FMT_D ").\n",
1001 position, arr1->min_position, arr1->max_position););
1002 raise_error(INDEX_ERROR);
1003 result = 0;
1004 } else {
1005 arr1_size = arraySize(arr1);
1006 result = arr1->arr[position - arr1->min_position].value.genericValue;
1007 if (position != arr1->max_position) {
1008 arr1->arr[position - arr1->min_position].value.genericValue =
1009 arr1->arr[arr1_size - 1].value.genericValue;
1010 } /* if */
1011 resized_arr1 = REALLOC_RTL_ARRAY(arr1, arr1_size, arr1_size - 1);
1012 if (unlikely(resized_arr1 == NULL)) {
1013 raise_error(MEMORY_ERROR);
1014 } else {
1015 COUNT3_RTL_ARRAY(arr1_size, arr1_size - 1);
1016 resized_arr1->max_position--;
1017 *arr_temp = resized_arr1;
1018 } /* if */
1019 } /* if */
1020 return result;
1021 } /* arrIdxTemp */
1022
1023
1024
1025 /**
1026 * Insert 'element' at 'position' into 'arr_to'.
1027 * @exception INDEX_ERROR If 'position' is less than minIdx(arr) or
1028 * greater than succ(maxIdx(arr))
1029 */
arrInsert(rtlArrayType * arr_to,intType position,genericType element)1030 void arrInsert (rtlArrayType *arr_to, intType position, genericType element)
1031
1032 {
1033 rtlArrayType arr1;
1034 rtlArrayType resized_arr1;
1035 rtlObjectType *array_pointer;
1036 memSizeType arr1_size;
1037
1038 /* arrInsert */
1039 arr1 = *arr_to;
1040 logFunction(printf("arrInsert(" FMT_U_MEM " (size=" FMT_U_MEM "), "
1041 FMT_D ", " FMT_U "))\n",
1042 arr1, arraySize(arr1), position, element););
1043 if (unlikely(position < arr1->min_position ||
1044 position > arr1->max_position + 1)) {
1045 logError(printf("arrInsert(arr1, " FMT_D ", *): "
1046 "Index out of range (" FMT_D " .. " FMT_D ").\n",
1047 position, arr1->min_position, arr1->max_position + 1););
1048 raise_error(INDEX_ERROR);
1049 } else {
1050 arr1_size = arraySize(arr1);
1051 resized_arr1 = REALLOC_RTL_ARRAY(arr1, arr1_size, arr1_size + 1);
1052 if (unlikely(resized_arr1 == NULL)) {
1053 raise_error(MEMORY_ERROR);
1054 } else {
1055 arr1 = resized_arr1;
1056 COUNT3_RTL_ARRAY(arr1_size, arr1_size + 1);
1057 array_pointer = arr1->arr;
1058 memmove(&array_pointer[position - arr1->min_position + 1],
1059 &array_pointer[position - arr1->min_position],
1060 arraySize2(position, arr1->max_position) * sizeof(rtlObjectType));
1061 array_pointer[position - arr1->min_position].value.genericValue = element;
1062 arr1->max_position++;
1063 *arr_to = arr1;
1064 } /* if */
1065 } /* if */
1066 } /* arrInsert */
1067
1068
1069
1070 /**
1071 * Insert 'elements' at 'position' into 'arr1'.
1072 * @exception INDEX_ERROR If 'position' is less than minIdx(arr1) or
1073 * greater than succ(maxIdx(arr1))
1074 */
arrInsertArray(rtlArrayType * arr_to,intType position,rtlArrayType elements)1075 void arrInsertArray (rtlArrayType *arr_to, intType position,
1076 rtlArrayType elements)
1077
1078 {
1079 rtlArrayType arr1;
1080 rtlArrayType resized_arr1;
1081 rtlObjectType *array_pointer;
1082 memSizeType new_size;
1083 memSizeType arr1_size;
1084 memSizeType elements_size;
1085
1086 /* arrInsertArray */
1087 logFunction(printf("arrInsertArray\n"););
1088 arr1 = *arr_to;
1089 if (unlikely(position < arr1->min_position ||
1090 position > arr1->max_position + 1)) {
1091 logError(printf("arrInsert(arr1, " FMT_D ", *): "
1092 "Index out of range (" FMT_D " .. " FMT_D ").\n",
1093 position, arr1->min_position, arr1->max_position + 1););
1094 raise_error(INDEX_ERROR);
1095 } else {
1096 elements_size = arraySize(elements);
1097 if (elements_size != 0) {
1098 arr1_size = arraySize(arr1);
1099 if (unlikely(arr1_size > MAX_RTL_ARR_LEN - elements_size ||
1100 arr1->max_position > (intType) (MAX_MEM_INDEX - elements_size))) {
1101 raise_error(MEMORY_ERROR);
1102 } else {
1103 new_size = arr1_size + elements_size;
1104 resized_arr1 = REALLOC_RTL_ARRAY(arr1, arr1_size, new_size);
1105 if (unlikely(resized_arr1 == NULL)) {
1106 raise_error(MEMORY_ERROR);
1107 } else {
1108 COUNT3_RTL_ARRAY(arr1_size, new_size);
1109 *arr_to = resized_arr1;
1110 array_pointer = resized_arr1->arr;
1111 memmove(&array_pointer[arrayIndex(resized_arr1, position) + elements_size],
1112 &array_pointer[arrayIndex(resized_arr1, position)],
1113 arraySize2(position, resized_arr1->max_position) * sizeof(rtlObjectType));
1114 /* It is possible that arr1 == elements holds. */
1115 /* In this case the new hole in arr1 must be */
1116 /* considered. */
1117 if (unlikely(arr1 == elements)) {
1118 memcpy(&array_pointer[arrayIndex(resized_arr1, position)],
1119 array_pointer, arrayIndex(resized_arr1, position) * sizeof(rtlObjectType));
1120 memcpy(&array_pointer[2 * arrayIndex(resized_arr1, position)],
1121 &array_pointer[arrayIndex(resized_arr1, position) + elements_size],
1122 (elements_size - arrayIndex(resized_arr1, position)) * sizeof(rtlObjectType));
1123 } else {
1124 memcpy(&array_pointer[arrayIndex(resized_arr1, position)],
1125 elements->arr, elements_size * sizeof(rtlObjectType));
1126 } /* if */
1127 resized_arr1->max_position = arrayMaxPos(resized_arr1->min_position, new_size);
1128 FREE_RTL_ARRAY(elements, elements_size);
1129 } /* if */
1130 } /* if */
1131 } /* if */
1132 } /* if */
1133 logFunction(printf("arrInsertArray -->\n"););
1134 } /* arrInsertArray */
1135
1136
1137
1138 /**
1139 * Allocate memory for an array with given min and max positions.
1140 * The min and max positions of the created array are set.
1141 * @return A reference to the memory suitable for the array.
1142 * @exception MEMORY_ERROR The min or max index is not in the
1143 * allowed range, or there is not enough memory to
1144 * allocate the array.
1145 * @exception RANGE_ERROR If min and max indicate that the array
1146 * would have a negative number of elements.
1147 */
arrMalloc(intType minPosition,intType maxPosition)1148 rtlArrayType arrMalloc (intType minPosition, intType maxPosition)
1149
1150 {
1151 memSizeType size;
1152 rtlArrayType result;
1153
1154 /* arrMalloc */
1155 if (unlikely(minPosition < MIN_MEM_INDEX ||
1156 maxPosition > MAX_MEM_INDEX ||
1157 (minPosition == MIN_MEM_INDEX &&
1158 maxPosition == MAX_MEM_INDEX))) {
1159 raise_error(MEMORY_ERROR);
1160 result = NULL;
1161 } else if (unlikely(minPosition > MIN_MEM_INDEX &&
1162 minPosition - 1 > maxPosition)) {
1163 raise_error(RANGE_ERROR);
1164 result = NULL;
1165 } else {
1166 size = arraySize2(minPosition, maxPosition);
1167 if (unlikely(size > MAX_RTL_ARR_LEN ||
1168 !ALLOC_RTL_ARRAY(result, (memSizeType) size))) {
1169 raise_error(MEMORY_ERROR);
1170 result = NULL;
1171 } else {
1172 result->min_position = minPosition;
1173 result->max_position = maxPosition;
1174 } /* if */
1175 } /* if */
1176 return result;
1177 } /* arrMalloc */
1178
1179
1180
1181 /**
1182 * Append the given 'element' to the array 'arr_variable'.
1183 * @exception MEMORY_ERROR Not enough memory for the concatenated
1184 * array.
1185 */
arrPush(rtlArrayType * const arr_variable,const genericType element)1186 void arrPush (rtlArrayType *const arr_variable, const genericType element)
1187
1188 {
1189 rtlArrayType arr_to;
1190 memSizeType new_size;
1191 memSizeType arr_to_size;
1192
1193 /* arrPush */
1194 arr_to = *arr_variable;
1195 arr_to_size = arraySize(arr_to);
1196 if (unlikely(arr_to_size > MAX_RTL_ARR_LEN - 1 ||
1197 arr_to->max_position > (intType) (MAX_MEM_INDEX - 1))) {
1198 raise_error(MEMORY_ERROR);
1199 } else {
1200 new_size = arr_to_size + 1;
1201 arr_to = REALLOC_RTL_ARRAY(arr_to, arr_to_size, new_size);
1202 if (unlikely(arr_to == NULL)) {
1203 raise_error(MEMORY_ERROR);
1204 } else {
1205 COUNT3_RTL_ARRAY(arr_to_size, new_size);
1206 *arr_variable = arr_to;
1207 arr_to->max_position ++;
1208 arr_to->arr[arr_to_size].value.genericValue = element;
1209 } /* if */
1210 } /* if */
1211 } /* arrPush */
1212
1213
1214
1215 /**
1216 * Get a sub array from the position 'start' to the position 'stop'.
1217 * @return the sub array from position 'start' to 'stop'.
1218 * @exception INDEX_ERROR The start position is less than minIdx(arr1), or
1219 * the stop position is less than pred(start).
1220 * @exception MEMORY_ERROR Not enough memory to represent the result.
1221 */
arrRange(const const_rtlArrayType arr1,intType start,intType stop)1222 rtlArrayType arrRange (const const_rtlArrayType arr1, intType start, intType stop)
1223
1224 {
1225 memSizeType arr1_size;
1226 memSizeType result_size;
1227 memSizeType start_idx;
1228 rtlArrayType result;
1229
1230 /* arrRange */
1231 arr1_size = arraySize(arr1);
1232 if (unlikely(start < arr1->min_position)) {
1233 raise_error(INDEX_ERROR);
1234 result = NULL;
1235 } else if (stop >= start && start <= arr1->max_position &&
1236 stop >= arr1->min_position && arr1_size >= 1) {
1237 if (stop > arr1->max_position) {
1238 stop = arr1->max_position;
1239 } /* if */
1240 result_size = arraySize2(start, stop);
1241 if (unlikely(!ALLOC_RTL_ARRAY(result, result_size))) {
1242 raise_error(MEMORY_ERROR);
1243 } else {
1244 result->min_position = arr1->min_position;
1245 result->max_position = arrayMaxPos(arr1->min_position, result_size);
1246 start_idx = arrayIndex(arr1, start);
1247 memcpy(result->arr, &arr1->arr[start_idx],
1248 (size_t) (result_size * sizeof(rtlObjectType)));
1249 } /* if */
1250 } else if (unlikely(stop < start - 1)) {
1251 raise_error(INDEX_ERROR);
1252 result = NULL;
1253 } else if (unlikely(arr1->min_position == MIN_MEM_INDEX)) {
1254 logError(printf("arrRange(arr1 (size=" FMT_U_MEM "), " FMT_D ", " FMT_D "): "
1255 "Cannot create empty array with minimum index.\n",
1256 arr1_size, start, stop););
1257 raise_error(RANGE_ERROR);
1258 result = NULL;
1259 } else {
1260 if (unlikely(!ALLOC_RTL_ARRAY(result, 0))) {
1261 raise_error(MEMORY_ERROR);
1262 } else {
1263 result->min_position = arr1->min_position;
1264 result->max_position = arr1->min_position - 1;
1265 } /* if */
1266 } /* if */
1267 return result;
1268 } /* arrRange */
1269
1270
1271
1272 /**
1273 * Get a sub array from the position 'start' to the position 'stop'.
1274 * ArrRangeTemp is used by the compiler if 'arr_temp' is a temporary
1275 * value that can be reused.
1276 * @return the sub array from position 'start' to 'stop'.
1277 * @exception INDEX_ERROR The start position is less than minIdx(arr1), or
1278 * the stop position is less than pred(start).
1279 * @exception MEMORY_ERROR Not enough memory to represent the result.
1280 */
arrRangeTemp(rtlArrayType * arr_temp,intType start,intType stop)1281 rtlArrayType arrRangeTemp (rtlArrayType *arr_temp, intType start, intType stop)
1282
1283 {
1284 rtlArrayType arr1;
1285 memSizeType arr1_size;
1286 memSizeType result_size;
1287 memSizeType start_idx;
1288 memSizeType stop_idx;
1289 rtlArrayType resized_arr1;
1290 rtlArrayType result;
1291
1292 /* arrRangeTemp */
1293 arr1 = *arr_temp;
1294 arr1_size = arraySize(arr1);
1295 if (unlikely(start < arr1->min_position)) {
1296 raise_error(INDEX_ERROR);
1297 result = NULL;
1298 } else if (stop >= start && start <= arr1->max_position && arr1_size >= 1) {
1299 if (stop > arr1->max_position) {
1300 stop = arr1->max_position;
1301 } /* if */
1302 result_size = arraySize2(start, stop);
1303 if (result_size == arr1_size) {
1304 result = arr1;
1305 *arr_temp = NULL;
1306 } else {
1307 if (unlikely(!ALLOC_RTL_ARRAY(result, result_size))) {
1308 raise_error(MEMORY_ERROR);
1309 } else {
1310 result->min_position = arr1->min_position;
1311 result->max_position = arrayMaxPos(arr1->min_position, result_size);
1312 start_idx = arrayIndex(arr1, start);
1313 stop_idx = arrayIndex(arr1, stop);
1314 memcpy(result->arr, &arr1->arr[start_idx],
1315 (size_t) (result_size * sizeof(rtlObjectType)));
1316 memmove(&arr1->arr[start_idx], &arr1->arr[stop_idx + 1],
1317 (size_t) ((arr1_size - stop_idx - 1) * sizeof(rtlObjectType)));
1318 resized_arr1 = REALLOC_RTL_ARRAY(arr1, arr1_size, arr1_size - result_size);
1319 if (unlikely(resized_arr1 == NULL)) {
1320 memcpy(&arr1->arr[arr1_size - result_size], result->arr,
1321 (size_t) (result_size * sizeof(rtlObjectType)));
1322 FREE_RTL_ARRAY(result, result_size);
1323 raise_error(MEMORY_ERROR);
1324 result = NULL;
1325 } else {
1326 COUNT3_RTL_ARRAY(arr1_size, arr1_size - result_size);
1327 resized_arr1->max_position = arrayMaxPos(resized_arr1->min_position,
1328 arr1_size - result_size);
1329 *arr_temp = resized_arr1;
1330 } /* if */
1331 } /* if */
1332 } /* if */
1333 } else if (unlikely(stop < start - 1)) {
1334 raise_error(INDEX_ERROR);
1335 result = NULL;
1336 } else if (unlikely(arr1->min_position == MIN_MEM_INDEX)) {
1337 logError(printf("arrRangeTemp(arr1 (size=" FMT_U_MEM "), " FMT_D ", " FMT_D "): "
1338 "Cannot create empty array with minimum index.\n",
1339 arr1_size, start, stop););
1340 raise_error(RANGE_ERROR);
1341 result = NULL;
1342 } else {
1343 if (unlikely(!ALLOC_RTL_ARRAY(result, 0))) {
1344 raise_error(MEMORY_ERROR);
1345 } else {
1346 result->min_position = arr1->min_position;
1347 result->max_position = arr1->min_position - 1;
1348 } /* if */
1349 } /* if */
1350 return result;
1351 } /* arrRangeTemp */
1352
1353
1354
1355 /**
1356 * Reallocate memory for an array from 'oldSize' to 'newSize'.
1357 * This function is used by the compiler if an array is copied
1358 * and the sizes of source and destination array are different.
1359 * @return A reference to the memory of the array with 'newSize'.
1360 * @exception MEMORY_ERROR There is not enough memory to
1361 * reallocate the array.
1362 */
arrRealloc(rtlArrayType arr,memSizeType oldSize,memSizeType newSize)1363 rtlArrayType arrRealloc (rtlArrayType arr, memSizeType oldSize, memSizeType newSize)
1364
1365 {
1366 rtlArrayType resized_arr;
1367
1368 /* arrRealloc */
1369 resized_arr = REALLOC_RTL_ARRAY(arr, oldSize, newSize);
1370 if (unlikely(resized_arr == NULL)) {
1371 if (oldSize >= newSize) {
1372 resized_arr = arr;
1373 } /* if */
1374 raise_error(MEMORY_ERROR);
1375 } else {
1376 COUNT3_RTL_ARRAY(oldSize, newSize);
1377 } /* if */
1378 return resized_arr;
1379 } /* arrRealloc */
1380
1381
1382
1383 /**
1384 * Remove the element with 'position' from 'arr_to' and return the removed element.
1385 * @return the removed element.
1386 * @exception INDEX_ERROR If 'position' is less than minIdx(arr) or
1387 * greater than maxIdx(arr)
1388 */
arrRemove(rtlArrayType * arr_to,intType position)1389 genericType arrRemove (rtlArrayType *arr_to, intType position)
1390
1391 {
1392 rtlArrayType arr1;
1393 rtlArrayType resized_arr1;
1394 rtlObjectType *array_pointer;
1395 memSizeType arr1_size;
1396 genericType result;
1397
1398 /* arrRemove */
1399 arr1 = *arr_to;
1400 logFunction(printf("arrRemove(" FMT_U_MEM " (size=" FMT_U_MEM "), " FMT_D "))\n",
1401 arr1, arraySize(arr1), position););
1402 if (unlikely(position < arr1->min_position ||
1403 position > arr1->max_position)) {
1404 logError(printf("arrRemove(arr1, " FMT_D "): "
1405 "Index out of range (" FMT_D " .. " FMT_D ").\n",
1406 position, arr1->min_position, arr1->max_position););
1407 raise_error(INDEX_ERROR);
1408 result = 0;
1409 } else {
1410 array_pointer = arr1->arr;
1411 result = array_pointer[position - arr1->min_position].value.genericValue;
1412 memmove(&array_pointer[position - arr1->min_position],
1413 &array_pointer[position - arr1->min_position + 1],
1414 (arraySize2(position, arr1->max_position) - 1) * sizeof(rtlObjectType));
1415 arr1_size = arraySize(arr1);
1416 resized_arr1 = REALLOC_RTL_ARRAY(arr1, arr1_size, arr1_size - 1);
1417 if (unlikely(resized_arr1 == NULL)) {
1418 /* A realloc, which shrinks memory, usually succeeds. */
1419 /* The probability that this code path is executed is */
1420 /* probably zero. The code below restores the old */
1421 /* value of arr1. */
1422 memmove(&array_pointer[position - arr1->min_position + 1],
1423 &array_pointer[position - arr1->min_position],
1424 (arraySize2(position, arr1->max_position) - 1) * sizeof(rtlObjectType));
1425 array_pointer[position - arr1->min_position].value.genericValue = result;
1426 raise_error(MEMORY_ERROR);
1427 result = 0;
1428 } else {
1429 arr1 = resized_arr1;
1430 COUNT3_RTL_ARRAY(arr1_size, arr1_size - 1);
1431 arr1->max_position--;
1432 *arr_to = arr1;
1433 } /* if */
1434 } /* if */
1435 return result;
1436 } /* arrRemove */
1437
1438
1439
1440 /**
1441 * Remove the sub-array with 'position' and 'length' from 'arr1'.
1442 * @return the removed sub-array.
1443 * @exception INDEX_ERROR If 'position' is less than arr_minidx(arr2) or
1444 * greater than arr_maxidx(arr2)
1445 */
arrRemoveArray(rtlArrayType * arr_to,intType position,intType length)1446 rtlArrayType arrRemoveArray (rtlArrayType *arr_to, intType position, intType length)
1447
1448 {
1449 rtlArrayType arr1;
1450 rtlArrayType resized_arr1;
1451 rtlObjectType *array_pointer;
1452 memSizeType arr1_size;
1453 memSizeType result_size;
1454 rtlArrayType result;
1455
1456 /* arrRemoveArray */
1457 arr1 = *arr_to;
1458 logFunction(printf("arrRemoveArray(" FMT_U_MEM " (size=" FMT_U_MEM "), "
1459 FMT_D ", " FMT_D "))\n",
1460 arr1, arraySize(arr1), position, length););
1461 if (unlikely(length < 0)) {
1462 logError(printf("arrRemoveArray(arr1, " FMT_D ", " FMT_D "): "
1463 "Length is negative.\n", position, length););
1464 raise_error(RANGE_ERROR);
1465 result = NULL;
1466 } else if (unlikely(position < arr1->min_position ||
1467 position > arr1->max_position)) {
1468 logError(printf("arrRemoveArray(arr1, " FMT_D "): "
1469 "Index out of range (" FMT_D " .. " FMT_D ").\n",
1470 position, arr1->min_position, arr1->max_position););
1471 raise_error(INDEX_ERROR);
1472 result = NULL;
1473 } else {
1474 arr1_size = arraySize(arr1);
1475 if ((uintType) length > MAX_RTL_ARR_LEN) {
1476 result_size = MAX_RTL_ARR_LEN;
1477 } else {
1478 result_size = (memSizeType) (uintType) (length);
1479 } /* if */
1480 if (result_size > arraySize2(position, arr1->max_position)) {
1481 result_size = arraySize2(position, arr1->max_position);
1482 } /* if */
1483 if (unlikely(!ALLOC_RTL_ARRAY(result, result_size))) {
1484 raise_error(MEMORY_ERROR);
1485 return NULL;
1486 } else {
1487 result->min_position = arr1->min_position;
1488 result->max_position = arrayMaxPos(arr1->min_position, result_size);
1489 array_pointer = arr1->arr;
1490 memcpy(result->arr, &array_pointer[arrayIndex(arr1, position)],
1491 result_size * sizeof(rtlObjectType));
1492 memmove(&array_pointer[arrayIndex(arr1, position)],
1493 &array_pointer[arrayIndex(arr1, position) + result_size],
1494 (arraySize2(position, arr1->max_position) - result_size) * sizeof(rtlObjectType));
1495 arr1_size = arraySize(arr1);
1496 resized_arr1 = REALLOC_RTL_ARRAY(arr1, arr1_size, arr1_size - result_size);
1497 if (unlikely(resized_arr1 == NULL)) {
1498 /* A realloc, which shrinks memory, usually succeeds. */
1499 /* The probability that this code path is executed is */
1500 /* probably zero. The code below restores the old */
1501 /* value of arr1. */
1502 memmove(&array_pointer[arrayIndex(arr1, position) + result_size],
1503 &array_pointer[arrayIndex(arr1, position)],
1504 (arraySize2(position, arr1->max_position) - result_size) * sizeof(rtlObjectType));
1505 memcpy(&array_pointer[arrayIndex(arr1, position)], result->arr,
1506 result_size * sizeof(rtlObjectType));
1507 FREE_RTL_ARRAY(result, result_size);
1508 raise_error(MEMORY_ERROR);
1509 return NULL;
1510 } else {
1511 arr1 = resized_arr1;
1512 COUNT3_RTL_ARRAY(arr1_size, arr1_size - result_size);
1513 arr1->max_position = arrayMaxPos(arr1->min_position, arr1_size - result_size);
1514 *arr_to = arr1;
1515 } /* if */
1516 } /* if */
1517 } /* if */
1518 return result;
1519 } /* arrRemoveArray */
1520
1521
1522
arrSort(rtlArrayType arr1,compareType cmp_func)1523 rtlArrayType arrSort (rtlArrayType arr1, compareType cmp_func)
1524
1525 { /* arrSort */
1526 /* printf("arrSort(%lX, %ld, %ld)\n", arr1, arr1->min_position, arr1->max_position); */
1527 rtl_qsort_array(arr1->arr, &arr1->arr[arr1->max_position - arr1->min_position], cmp_func);
1528 return arr1;
1529 } /* arrSort */
1530
1531
1532
1533 /**
1534 * Get a sub array from the position 'start' with maximum length 'length'.
1535 * @return the sub array from position 'start' with maximum length 'length'.
1536 * @exception INDEX_ERROR The start position is less than minIdx(arr1), or
1537 * the length is negative.
1538 * @exception MEMORY_ERROR Not enough memory to represent the result.
1539 */
arrSubarr(const const_rtlArrayType arr1,intType start,intType length)1540 rtlArrayType arrSubarr (const const_rtlArrayType arr1, intType start, intType length)
1541
1542 {
1543 memSizeType arr1_size;
1544 memSizeType result_size;
1545 memSizeType start_idx;
1546 rtlArrayType result;
1547
1548 /* arrSubarr */
1549 if (unlikely(start < arr1->min_position || length < 0)) {
1550 raise_error(INDEX_ERROR);
1551 result = NULL;
1552 } else {
1553 arr1_size = arraySize(arr1);
1554 if (length != 0 && start <= arr1->max_position && arr1_size >= 1) {
1555 if (length - 1 > arr1->max_position - start) {
1556 length = arr1->max_position - start + 1;
1557 } /* if */
1558 result_size = (memSizeType) (uintType) (length);
1559 if (unlikely(!ALLOC_RTL_ARRAY(result, result_size))) {
1560 raise_error(MEMORY_ERROR);
1561 } else {
1562 result->min_position = arr1->min_position;
1563 result->max_position = arrayMaxPos(arr1->min_position, result_size);
1564 start_idx = arrayIndex(arr1, start);
1565 memcpy(result->arr, &arr1->arr[start_idx],
1566 (size_t) (result_size * sizeof(rtlObjectType)));
1567 } /* if */
1568 } else if (unlikely(arr1->min_position == MIN_MEM_INDEX)) {
1569 logError(printf("arrSubarr(arr1 (size=" FMT_U_MEM "), " FMT_D ", " FMT_D "): "
1570 "Cannot create empty array with minimum index.\n",
1571 arr1_size, start, length););
1572 raise_error(RANGE_ERROR);
1573 result = NULL;
1574 } else {
1575 if (unlikely(!ALLOC_RTL_ARRAY(result, 0))) {
1576 raise_error(MEMORY_ERROR);
1577 } else {
1578 result->min_position = arr1->min_position;
1579 result->max_position = arr1->min_position - 1;
1580 } /* if */
1581 } /* if */
1582 } /* if */
1583 return result;
1584 } /* arrSubarr */
1585
1586
1587
1588 /**
1589 * Get a sub array from the position 'start' with maximum length 'length'.
1590 * ArrSubarrTemp is used by the compiler if 'arr_temp' is a temporary
1591 * value that can be reused.
1592 * @return the sub array from position 'start' with maximum length 'length'.
1593 * @exception INDEX_ERROR The start position is less than minIdx(arr1), or
1594 * the length is negative.
1595 * @exception MEMORY_ERROR Not enough memory to represent the result.
1596 */
arrSubarrTemp(rtlArrayType * arr_temp,intType start,intType length)1597 rtlArrayType arrSubarrTemp (rtlArrayType *arr_temp, intType start, intType length)
1598
1599 {
1600 rtlArrayType arr1;
1601 memSizeType arr1_size;
1602 memSizeType result_size;
1603 memSizeType start_idx;
1604 memSizeType stop_idx;
1605 rtlArrayType resized_arr1;
1606 rtlArrayType result;
1607
1608 /* arrSubarrTemp */
1609 arr1 = *arr_temp;
1610 if (unlikely(start < arr1->min_position || length < 0)) {
1611 raise_error(INDEX_ERROR);
1612 result = NULL;
1613 } else {
1614 arr1_size = arraySize(arr1);
1615 if (length >= 1 && start <= arr1->max_position && arr1_size >= 1) {
1616 if (length - 1 > arr1->max_position - start) {
1617 length = arr1->max_position - start + 1;
1618 } /* if */
1619 result_size = (memSizeType) (uintType) (length);
1620 if (result_size == arr1_size) {
1621 result = arr1;
1622 *arr_temp = NULL;
1623 } else {
1624 if (unlikely(!ALLOC_RTL_ARRAY(result, result_size))) {
1625 raise_error(MEMORY_ERROR);
1626 } else {
1627 result->min_position = arr1->min_position;
1628 result->max_position = arrayMaxPos(arr1->min_position, result_size);
1629 start_idx = arrayIndex(arr1, start);
1630 stop_idx = arrayIndex(arr1, start + length - 1);
1631 memcpy(result->arr, &arr1->arr[start_idx],
1632 (size_t) (result_size * sizeof(rtlObjectType)));
1633 memmove(&arr1->arr[start_idx], &arr1->arr[stop_idx + 1],
1634 (size_t) ((arr1_size - stop_idx - 1) * sizeof(rtlObjectType)));
1635 resized_arr1 = REALLOC_RTL_ARRAY(arr1, arr1_size, arr1_size - result_size);
1636 if (unlikely(resized_arr1 == NULL)) {
1637 memcpy(&arr1->arr[arr1_size - result_size], result->arr,
1638 (size_t) (result_size * sizeof(rtlObjectType)));
1639 FREE_RTL_ARRAY(result, result_size);
1640 raise_error(MEMORY_ERROR);
1641 result = NULL;
1642 } else {
1643 COUNT3_RTL_ARRAY(arr1_size, arr1_size - result_size);
1644 resized_arr1->max_position = arrayMaxPos(resized_arr1->min_position,
1645 arr1_size - result_size);
1646 *arr_temp = resized_arr1;
1647 } /* if */
1648 } /* if */
1649 } /* if */
1650 } else if (unlikely(arr1->min_position == MIN_MEM_INDEX)) {
1651 logError(printf("arrSubarrTemp(arr1 (size=" FMT_U_MEM "), " FMT_D ", " FMT_D "): "
1652 "Cannot create empty array with minimum index.\n",
1653 arr1_size, start, length););
1654 raise_error(RANGE_ERROR);
1655 result = NULL;
1656 } else {
1657 if (unlikely(!ALLOC_RTL_ARRAY(result, 0))) {
1658 raise_error(MEMORY_ERROR);
1659 } else {
1660 result->min_position = arr1->min_position;
1661 result->max_position = arr1->min_position - 1;
1662 } /* if */
1663 } /* if */
1664 } /* if */
1665 return result;
1666 } /* arrSubarrTemp */
1667
1668
1669
1670 /**
1671 * Get a sub array beginning at the position 'start'.
1672 * @return the sub array beginning at the start position.
1673 * @exception INDEX_ERROR The start position is less than minIdx(arr1).
1674 * @exception MEMORY_ERROR Not enough memory to represent the result.
1675 */
arrTail(const const_rtlArrayType arr1,intType start)1676 rtlArrayType arrTail (const const_rtlArrayType arr1, intType start)
1677
1678 {
1679 memSizeType arr1_size;
1680 memSizeType result_size;
1681 memSizeType start_idx;
1682 rtlArrayType result;
1683
1684 /* arrTail */
1685 arr1_size = arraySize(arr1);
1686 if (unlikely(start < arr1->min_position)) {
1687 logError(printf("arrTail(arr1 (minIdx=" FMT_D "), " FMT_D "): "
1688 "Start less than minIdx(arr1).\n",
1689 arr1->min_position, start););
1690 raise_error(INDEX_ERROR);
1691 result = NULL;
1692 } else if (start <= arr1->max_position && arr1_size >= 1) {
1693 result_size = arraySize2(start, arr1->max_position);
1694 if (unlikely(!ALLOC_RTL_ARRAY(result, result_size))) {
1695 raise_error(MEMORY_ERROR);
1696 } else {
1697 result->min_position = arr1->min_position;
1698 result->max_position = arrayMaxPos(arr1->min_position, result_size);
1699 start_idx = arrayIndex(arr1, start);
1700 memcpy(result->arr, &arr1->arr[start_idx],
1701 (size_t) (result_size * sizeof(rtlObjectType)));
1702 } /* if */
1703 } else if (unlikely(arr1->min_position == MIN_MEM_INDEX)) {
1704 logError(printf("arrTail(arr1 (size=" FMT_U_MEM "), " FMT_D "): "
1705 "Cannot create empty array with minimum index.\n",
1706 arr1_size, start););
1707 raise_error(RANGE_ERROR);
1708 result = NULL;
1709 } else {
1710 if (unlikely(!ALLOC_RTL_ARRAY(result, 0))) {
1711 raise_error(MEMORY_ERROR);
1712 } else {
1713 result->min_position = arr1->min_position;
1714 result->max_position = arr1->min_position - 1;
1715 } /* if */
1716 } /* if */
1717 return result;
1718 } /* arrTail */
1719
1720
1721
1722 /**
1723 * Get a sub array beginning at the position 'start'.
1724 * ArrTailTemp is used by the compiler if 'arr_temp' is a temporary
1725 * value that can be reused.
1726 * @return the sub array beginning at the start position.
1727 * @exception INDEX_ERROR The start position is less than minIdx(arr1).
1728 * @exception MEMORY_ERROR Not enough memory to represent the result.
1729 */
arrTailTemp(rtlArrayType * arr_temp,intType start)1730 rtlArrayType arrTailTemp (rtlArrayType *arr_temp, intType start)
1731
1732 {
1733 rtlArrayType arr1;
1734 memSizeType arr1_size;
1735 memSizeType result_size;
1736 memSizeType start_idx;
1737 rtlArrayType resized_arr1;
1738 rtlArrayType result;
1739
1740 /* arrTailTemp */
1741 arr1 = *arr_temp;
1742 arr1_size = arraySize(arr1);
1743 if (start <= arr1->min_position) {
1744 if (unlikely(start < arr1->min_position)) {
1745 logError(printf("arrTailTemp(arr1 (minIdx=" FMT_D "), " FMT_D "): "
1746 "Start less than minIdx(arr1).\n",
1747 arr1->min_position, start););
1748 raise_error(INDEX_ERROR);
1749 result = NULL;
1750 } else {
1751 result = arr1;
1752 *arr_temp = NULL;
1753 } /* if */
1754 } else if (start <= arr1->max_position && arr1_size >= 1) {
1755 result_size = arraySize2(start, arr1->max_position);
1756 if (unlikely(!ALLOC_RTL_ARRAY(result, result_size))) {
1757 raise_error(MEMORY_ERROR);
1758 } else {
1759 result->min_position = arr1->min_position;
1760 result->max_position = arrayMaxPos(arr1->min_position, result_size);
1761 start_idx = arrayIndex(arr1, start);
1762 memcpy(result->arr, &arr1->arr[start_idx],
1763 (size_t) (result_size * sizeof(rtlObjectType)));
1764 resized_arr1 = REALLOC_RTL_ARRAY(arr1, arr1_size, arr1_size - result_size);
1765 if (unlikely(resized_arr1 == NULL)) {
1766 FREE_RTL_ARRAY(result, result_size);
1767 raise_error(MEMORY_ERROR);
1768 result = NULL;
1769 } else {
1770 COUNT3_RTL_ARRAY(arr1_size, arr1_size - result_size);
1771 resized_arr1->max_position = start - 1;
1772 *arr_temp = resized_arr1;
1773 } /* if */
1774 } /* if */
1775 } else if (unlikely(arr1->min_position == MIN_MEM_INDEX)) {
1776 logError(printf("arrTailTemp(arr1 (size=" FMT_U_MEM "), " FMT_D "): "
1777 "Cannot create empty array with minimum index.\n",
1778 arr1_size, start););
1779 raise_error(RANGE_ERROR);
1780 result = NULL;
1781 } else {
1782 if (unlikely(!ALLOC_RTL_ARRAY(result, 0))) {
1783 raise_error(MEMORY_ERROR);
1784 } else {
1785 result->min_position = arr1->min_position;
1786 result->max_position = arr1->min_position - 1;
1787 } /* if */
1788 } /* if */
1789 return result;
1790 } /* arrTailTemp */
1791
1792
1793
1794 /**
1795 * Create array with given 'min' and 'max' positions and 'element'.
1796 * The 'min' and 'max' positions of the created array are set and
1797 * the array is filled with 'element' values.
1798 * @return The new created array.
1799 * @exception MEMORY_ERROR The min or max index is not in the
1800 * allowed range, or there is not enough memory to
1801 * allocate the array.
1802 * @exception RANGE_ERROR If min and max indicate that the array
1803 * would have a negative number of elements.
1804 */
arrTimes(intType minPosition,intType maxPosition,const genericType element)1805 rtlArrayType arrTimes (intType minPosition, intType maxPosition,
1806 const genericType element)
1807
1808 {
1809 memSizeType size;
1810 rtlArrayType result;
1811
1812 /* arrTimes */
1813 result = arrMalloc(minPosition, maxPosition);
1814 if (result != NULL) {
1815 size = arraySize2(minPosition, maxPosition);
1816 memsetGeneric(result->arr, element, size);
1817 } /* if */
1818 return result;
1819 } /* arrTimes */
1820