Bug Summary

File:OMCompiler/Parser/../3rdParty/antlr/3.2/libantlr3c-3.2/src/antlr3bitset.c
Warning:line 227, column 5
Potential leak of memory pointed to by 'bitSet'

Annotated Source Code

[?] Use j/k keys for keyboard navigation

1///
2/// \file
3/// Contains the C implementation of ANTLR3 bitsets as adapted from Terence Parr's
4/// Java implementation.
5///
6
7// [The "BSD licence"]
8// Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
9// http://www.temporal-wave.com
10// http://www.linkedin.com/in/jimidle
11//
12// All rights reserved.
13//
14// Redistribution and use in source and binary forms, with or without
15// modification, are permitted provided that the following conditions
16// are met:
17// 1. Redistributions of source code must retain the above copyright
18// notice, this list of conditions and the following disclaimer.
19// 2. Redistributions in binary form must reproduce the above copyright
20// notice, this list of conditions and the following disclaimer in the
21// documentation and/or other materials provided with the distribution.
22// 3. The name of the author may not be used to endorse or promote products
23// derived from this software without specific prior written permission.
24//
25// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
36#include <antlr3bitset.h>
37
38// External interface
39//
40
41static pANTLR3_BITSET antlr3BitsetClone (pANTLR3_BITSET inSet);
42static pANTLR3_BITSET antlr3BitsetOR (pANTLR3_BITSET bitset1, pANTLR3_BITSET bitset2);
43static void antlr3BitsetORInPlace (pANTLR3_BITSET bitset, pANTLR3_BITSET bitset2);
44static ANTLR3_UINT32 antlr3BitsetSize (pANTLR3_BITSET bitset);
45static void antlr3BitsetAdd (pANTLR3_BITSET bitset, ANTLR3_INT32 bit);
46static ANTLR3_BOOLEAN antlr3BitsetEquals (pANTLR3_BITSET bitset1, pANTLR3_BITSET bitset2);
47static ANTLR3_BOOLEAN antlr3BitsetMember (pANTLR3_BITSET bitset, ANTLR3_UINT32 bit);
48static ANTLR3_UINT32 antlr3BitsetNumBits (pANTLR3_BITSET bitset);
49static void antlr3BitsetRemove (pANTLR3_BITSET bitset, ANTLR3_UINT32 bit);
50static ANTLR3_BOOLEAN antlr3BitsetIsNil (pANTLR3_BITSET bitset);
51static pANTLR3_INT32 antlr3BitsetToIntList (pANTLR3_BITSET bitset);
52
53// Local functions
54//
55static void growToInclude (pANTLR3_BITSET bitset, ANTLR3_INT32 bit);
56static void grow (pANTLR3_BITSET bitset, ANTLR3_INT32 newSize);
57static ANTLR3_UINT64 bitMask (ANTLR3_UINT32 bitNumber);
58static ANTLR3_UINT32 numWordsToHold (ANTLR3_UINT32 bit);
59static ANTLR3_UINT32 wordNumber (ANTLR3_UINT32 bit);
60static void antlr3BitsetFree (pANTLR3_BITSET bitset);
61
62static void
63antlr3BitsetFree(pANTLR3_BITSET bitset)
64{
65 if (bitset->blist.bits != NULL((void*)0))
66 {
67 ANTLR3_FREE(bitset->blist.bits)free ((void *)(bitset->blist.bits));
68 bitset->blist.bits = NULL((void*)0);
69 }
70 ANTLR3_FREE(bitset)free ((void *)(bitset));
71
72 return;
73}
74
75ANTLR3_API pANTLR3_BITSET
76antlr3BitsetNew(ANTLR3_UINT32 numBits)
77{
78 pANTLR3_BITSET bitset;
79
80 ANTLR3_UINT32 numelements;
81
82 // Allocate memory for the bitset structure itself
83 //
84 bitset = (pANTLR3_BITSET) ANTLR3_MALLOC((size_t)sizeof(ANTLR3_BITSET))malloc ((size_t)((size_t)sizeof(ANTLR3_BITSET)));;
2
Within the expansion of the macro 'ANTLR3_MALLOC':
a
Memory is allocated
85
86 if (bitset == NULL((void*)0))
3
Assuming 'bitset' is not equal to NULL
4
Taking false branch
87 {
88 return NULL((void*)0);
89 }
90
91 // Avoid memory thrashing at the up front expense of a few bytes
92 //
93 if (numBits < (8 * ANTLR3_BITSET_BITS64))
5
Taking true branch
94 {
95 numBits = 8 * ANTLR3_BITSET_BITS64;
96 }
97
98 // No we need to allocate the memory for the number of bits asked for
99 // in multiples of ANTLR3_UINT64.
100 //
101 numelements = ((numBits -1) >> ANTLR3_BITSET_LOG_BITS6) + 1;
102
103 bitset->blist.bits = (pANTLR3_BITWORD) ANTLR3_MALLOC((size_t)(numelements * sizeof(ANTLR3_BITWORD)))malloc ((size_t)((size_t)(numelements * sizeof(ANTLR3_BITWORD
))));
;
104 memset(bitset->blist.bits, 0, (size_t)(numelements * sizeof(ANTLR3_BITWORD)));
105 bitset->blist.length = numelements;
106
107 if (bitset->blist.bits == NULL((void*)0))
6
Taking false branch
108 {
109 ANTLR3_FREE(bitset)free ((void *)(bitset));
110 return NULL((void*)0);
111 }
112
113 antlr3BitsetSetAPI(bitset);
114
115
116 // All seems good
117 //
118 return bitset;
119}
120
121ANTLR3_API void
122antlr3BitsetSetAPI(pANTLR3_BITSET bitset)
123{
124 bitset->clone = antlr3BitsetClone;
125 bitset->bor = antlr3BitsetOR;
126 bitset->borInPlace = antlr3BitsetORInPlace;
127 bitset->size = antlr3BitsetSize;
128 bitset->add = antlr3BitsetAdd;
129 bitset->grow = grow;
130 bitset->equals = antlr3BitsetEquals;
131 bitset->isMember = antlr3BitsetMember;
132 bitset->numBits = antlr3BitsetNumBits;
133 bitset->remove = antlr3BitsetRemove;
134 bitset->isNilNode = antlr3BitsetIsNil;
135 bitset->toIntList = antlr3BitsetToIntList;
136
137 bitset->free = antlr3BitsetFree;
138}
139
140ANTLR3_API pANTLR3_BITSET
141antlr3BitsetCopy(pANTLR3_BITSET_LIST blist)
142{
143 pANTLR3_BITSET bitset;
144 int numElements;
145
146 // Allocate memory for the bitset structure itself
147 //
148 bitset = (pANTLR3_BITSET) ANTLR3_MALLOC((size_t)sizeof(ANTLR3_BITSET))malloc ((size_t)((size_t)sizeof(ANTLR3_BITSET)));;
149
150 if (bitset == NULL((void*)0))
151 {
152 return NULL((void*)0);
153 }
154
155 numElements = blist->length;
156
157 // Avoid memory thrashing at the expense of a few more bytes
158 //
159 if (numElements < 8)
160 {
161 numElements = 8;
162 }
163
164 // Install the length in ANTLR3_UINT64 units
165 //
166 bitset->blist.length = numElements;
167
168 bitset->blist.bits = (pANTLR3_BITWORD)ANTLR3_MALLOC((size_t)(numElements * sizeof(ANTLR3_BITWORD)))malloc ((size_t)((size_t)(numElements * sizeof(ANTLR3_BITWORD
))));
;
169
170 if (bitset->blist.bits == NULL((void*)0))
171 {
172 ANTLR3_FREE(bitset)free ((void *)(bitset));
173 return NULL((void*)0);
174 }
175
176 ANTLR3_MEMCPY(bitset->blist.bits, blist->bits, (ANTLR3_UINT64)(numElements * sizeof(ANTLR3_BITWORD)))memcpy((void *)(bitset->blist.bits), (const void *)(blist->
bits), (size_t)((ANTLR3_UINT64)(numElements * sizeof(ANTLR3_BITWORD
))))
;
177
178 // All seems good
179 //
180 return bitset;
181}
182
183static pANTLR3_BITSET
184antlr3BitsetClone(pANTLR3_BITSET inSet)
185{
186 pANTLR3_BITSET bitset;
187
188 // Allocate memory for the bitset structure itself
189 //
190 bitset = antlr3BitsetNew(ANTLR3_BITSET_BITS64 * inSet->blist.length);
191
192 if (bitset == NULL((void*)0))
193 {
194 return NULL((void*)0);
195 }
196
197 // Install the actual bits in the source set
198 //
199 ANTLR3_MEMCPY(bitset->blist.bits, inSet->blist.bits, (ANTLR3_UINT64)(inSet->blist.length * sizeof(ANTLR3_BITWORD)))memcpy((void *)(bitset->blist.bits), (const void *)(inSet->
blist.bits), (size_t)((ANTLR3_UINT64)(inSet->blist.length *
sizeof(ANTLR3_BITWORD))))
;
200
201 // All seems good
202 //
203 return bitset;
204}
205
206
207ANTLR3_API pANTLR3_BITSET
208antlr3BitsetList(pANTLR3_HASH_TABLE list)
209{
210 pANTLR3_BITSET bitSet;
211 pANTLR3_HASH_ENUM en;
212 pANTLR3_HASH_KEY key;
213 ANTLR3_UINT64 bit;
214
215 // We have no idea what exactly is in the list
216 // so create a default bitset and then just add stuff
217 // as we enumerate.
218 //
219 bitSet = antlr3BitsetNew(0);
1
Calling 'antlr3BitsetNew'
7
Returned allocated memory
220
221 en = antlr3EnumNew(list);
222
223 while (en->next(en, &key, (void **)(&bit)) == ANTLR3_SUCCESS0)
8
Assuming the condition is false
9
Loop condition is false. Execution continues on line 227
224 {
225 bitSet->add(bitSet, (ANTLR3_UINT32)bit);
226 }
227 en->free(en);
10
Potential leak of memory pointed to by 'bitSet'
228
229 return NULL((void*)0);
230}
231
232///
233/// \brief
234/// Creates a new bitset with at least one 64 bit bset of bits, but as
235/// many 64 bit sets as are required.
236///
237/// \param[in] bset
238/// A variable number of bits to add to the set, ending in -1 (impossible bit).
239///
240/// \returns
241/// A new bit set with all of the specified bitmaps in it and the API
242/// initialized.
243///
244/// Call as:
245/// - pANTLR3_BITSET = antlrBitsetLoad(bset, bset11, ..., -1);
246/// - pANTLR3_BITSET = antlrBitsetOf(-1); Create empty bitset
247///
248/// \remarks
249/// Stdargs function - must supply -1 as last paremeter, which is NOT
250/// added to the set.
251///
252///
253ANTLR3_API pANTLR3_BITSET
254antlr3BitsetLoad(pANTLR3_BITSET_LIST inBits)
255{
256 pANTLR3_BITSET bitset;
257 ANTLR3_UINT32 count;
258
259 // Allocate memory for the bitset structure itself
260 // the input parameter is the bit number (0 based)
261 // to include in the bitset, so we need at at least
262 // bit + 1 bits. If any arguments indicate a
263 // a bit higher than the default number of bits (0 means default size)
264 // then Add() will take care
265 // of it.
266 //
267 bitset = antlr3BitsetNew(0);
268
269 if (bitset == NULL((void*)0))
270 {
271 return NULL((void*)0);
272 }
273
274 if (inBits != NULL((void*)0))
275 {
276 // Now we can add the element bits into the set
277 //
278 count=0;
279 while (count < inBits->length)
280 {
281 if (bitset->blist.length <= count)
282 {
283 bitset->grow(bitset, count+1);
284 }
285
286 bitset->blist.bits[count] = *((inBits->bits)+count);
287 count++;
288 }
289 }
290
291 // return the new bitset
292 //
293 return bitset;
294}
295
296///
297/// \brief
298/// Creates a new bitset with at least one element, but as
299/// many elements are required.
300///
301/// \param[in] bit
302/// A variable number of bits to add to the set, ending in -1 (impossible bit).
303///
304/// \returns
305/// A new bit set with all of the specified elements added into it.
306///
307/// Call as:
308/// - pANTLR3_BITSET = antlrBitsetOf(n, n1, n2, -1);
309/// - pANTLR3_BITSET = antlrBitsetOf(-1); Create empty bitset
310///
311/// \remarks
312/// Stdargs function - must supply -1 as last paremeter, which is NOT
313/// added to the set.
314///
315///
316ANTLR3_API pANTLR3_BITSET
317antlr3BitsetOf(ANTLR3_INT32 bit, ...)
318{
319 pANTLR3_BITSET bitset;
320
321 va_list ap;
322
323 // Allocate memory for the bitset structure itself
324 // the input parameter is the bit number (0 based)
325 // to include in the bitset, so we need at at least
326 // bit + 1 bits. If any arguments indicate a
327 // a bit higher than the default number of bits (0 menas default size)
328 // then Add() will take care
329 // of it.
330 //
331 bitset = antlr3BitsetNew(0);
332
333 if (bitset == NULL((void*)0))
334 {
335 return NULL((void*)0);
336 }
337
338 // Now we can add the element bits into the set
339 //
340 va_start(ap, bit)__builtin_va_start(ap, bit);
341 while (bit != -1)
342 {
343 antlr3BitsetAdd(bitset, bit);
344 bit = va_arg(ap, ANTLR3_UINT32)__builtin_va_arg(ap, ANTLR3_UINT32);
345 }
346 va_end(ap)__builtin_va_end(ap);
347
348 // return the new bitset
349 //
350 return bitset;
351}
352
353static pANTLR3_BITSET
354antlr3BitsetOR(pANTLR3_BITSET bitset1, pANTLR3_BITSET bitset2)
355{
356 pANTLR3_BITSET bitset;
357
358 if (bitset1 == NULL((void*)0))
359 {
360 return antlr3BitsetClone(bitset2);
361 }
362
363 if (bitset2 == NULL((void*)0))
364 {
365 return antlr3BitsetClone(bitset1);
366 }
367
368 // Allocate memory for the newly ordered bitset structure itself.
369 //
370 bitset = antlr3BitsetClone(bitset1);
371
372 antlr3BitsetORInPlace(bitset, bitset2);
373
374 return bitset;
375
376}
377
378static void
379antlr3BitsetAdd(pANTLR3_BITSET bitset, ANTLR3_INT32 bit)
380{
381 ANTLR3_UINT32 word;
382
383 word = wordNumber(bit);
384
385 if (word >= bitset->blist.length)
386 {
387 growToInclude(bitset, bit);
388 }
389
390 bitset->blist.bits[word] |= bitMask(bit);
391
392}
393
394static void
395grow(pANTLR3_BITSET bitset, ANTLR3_INT32 newSize)
396{
397 pANTLR3_BITWORD newBits;
398
399 // Space for newly sized bitset - TODO: come back to this and use realloc?, it may
400 // be more efficient...
401 //
402 newBits = (pANTLR3_BITWORD) ANTLR3_CALLOC(1, (size_t)(newSize * sizeof(ANTLR3_BITWORD)))calloc (1, (size_t)((size_t)(newSize * sizeof(ANTLR3_BITWORD)
)));
;
403 if (bitset->blist.bits != NULL((void*)0))
404 {
405 // Copy existing bits
406 //
407 ANTLR3_MEMCPY((void *)newBits, (const void *)bitset->blist.bits, (size_t)(bitset->blist.length * sizeof(ANTLR3_BITWORD)))memcpy((void *)((void *)newBits), (const void *)((const void *
)bitset->blist.bits), (size_t)((size_t)(bitset->blist.length
* sizeof(ANTLR3_BITWORD))))
;
408
409 // Out with the old bits... de de de derrr
410 //
411 ANTLR3_FREE(bitset->blist.bits)free ((void *)(bitset->blist.bits));
412 }
413
414 // In with the new bits... keerrrang.
415 //
416 bitset->blist.bits = newBits;
417 bitset->blist.length = newSize;
418}
419
420static void
421growToInclude(pANTLR3_BITSET bitset, ANTLR3_INT32 bit)
422{
423 ANTLR3_UINT32 bl;
424 ANTLR3_UINT32 nw;
425
426 bl = (bitset->blist.length << 1);
427 nw = numWordsToHold(bit);
428
429 if (bl > nw)
430 {
431 bitset->grow(bitset, bl);
432 }
433 else
434 {
435 bitset->grow(bitset, nw);
436 }
437}
438
439static void
440antlr3BitsetORInPlace(pANTLR3_BITSET bitset, pANTLR3_BITSET bitset2)
441{
442 ANTLR3_UINT32 minimum;
443 ANTLR3_UINT32 i;
444
445 if (bitset2 == NULL((void*)0))
446 {
447 return;
448 }
449
450
451 // First make sure that the target bitset is big enough
452 // for the new bits to be ored in.
453 //
454 if (bitset->blist.length < bitset2->blist.length)
455 {
456 growToInclude(bitset, (bitset2->blist.length * sizeof(ANTLR3_BITWORD)));
457 }
458
459 // Or the miniimum number of bits after any resizing went on
460 //
461 if (bitset->blist.length < bitset2->blist.length)
462 {
463 minimum = bitset->blist.length;
464 }
465 else
466 {
467 minimum = bitset2->blist.length;
468 }
469
470 for (i = minimum; i > 0; i--)
471 {
472 bitset->blist.bits[i-1] |= bitset2->blist.bits[i-1];
473 }
474}
475
476static ANTLR3_UINT64
477bitMask(ANTLR3_UINT32 bitNumber)
478{
479 return ((ANTLR3_UINT64)1) << (bitNumber & (ANTLR3_BITSET_MOD_MASK64 - 1));
480}
481
482static ANTLR3_UINT32
483antlr3BitsetSize(pANTLR3_BITSET bitset)
484{
485 ANTLR3_UINT32 degree;
486 ANTLR3_INT32 i;
487 ANTLR3_INT8 bit;
488
489 // TODO: Come back to this, it may be faster to & with 0x01
490 // then shift right a copy of the 4 bits, than shift left a constant of 1.
491 // But then again, the optimizer might just work this out
492 // anyway.
493 //
494 degree = 0;
495 for (i = bitset->blist.length - 1; i>= 0; i--)
496 {
497 if (bitset->blist.bits[i] != 0)
498 {
499 for (bit = ANTLR3_BITSET_BITS64 - 1; bit >= 0; bit--)
500 {
501 if ((bitset->blist.bits[i] & (((ANTLR3_BITWORD)1) << bit)) != 0)
502 {
503 degree++;
504 }
505 }
506 }
507 }
508 return degree;
509}
510
511static ANTLR3_BOOLEAN
512antlr3BitsetEquals(pANTLR3_BITSET bitset1, pANTLR3_BITSET bitset2)
513{
514 ANTLR3_INT32 minimum;
515 ANTLR3_INT32 i;
516
517 if (bitset1 == NULL((void*)0) || bitset2 == NULL((void*)0))
518 {
519 return ANTLR3_FALSE0;
520 }
521
522 // Work out the minimum comparison set
523 //
524 if (bitset1->blist.length < bitset2->blist.length)
525 {
526 minimum = bitset1->blist.length;
527 }
528 else
529 {
530 minimum = bitset2->blist.length;
531 }
532
533 // Make sure explict in common bits are equal
534 //
535 for (i = minimum - 1; i >=0 ; i--)
536 {
537 if (bitset1->blist.bits[i] != bitset2->blist.bits[i])
538 {
539 return ANTLR3_FALSE0;
540 }
541 }
542
543 // Now make sure the bits of the larger set are all turned
544 // off.
545 //
546 if (bitset1->blist.length > (ANTLR3_UINT32)minimum)
547 {
548 for (i = minimum ; (ANTLR3_UINT32)i < bitset1->blist.length; i++)
549 {
550 if (bitset1->blist.bits[i] != 0)
551 {
552 return ANTLR3_FALSE0;
553 }
554 }
555 }
556 else if (bitset2->blist.length > (ANTLR3_UINT32)minimum)
557 {
558 for (i = minimum; (ANTLR3_UINT32)i < bitset2->blist.length; i++)
559 {
560 if (bitset2->blist.bits[i] != 0)
561 {
562 return ANTLR3_FALSE0;
563 }
564 }
565 }
566
567 return ANTLR3_TRUE1;
568}
569
570static ANTLR3_BOOLEAN
571antlr3BitsetMember(pANTLR3_BITSET bitset, ANTLR3_UINT32 bit)
572{
573 ANTLR3_UINT32 wordNo;
574
575 wordNo = wordNumber(bit);
576
577 if (wordNo >= bitset->blist.length)
578 {
579 return ANTLR3_FALSE0;
580 }
581
582 if ((bitset->blist.bits[wordNo] & bitMask(bit)) == 0)
583 {
584 return ANTLR3_FALSE0;
585 }
586 else
587 {
588 return ANTLR3_TRUE1;
589 }
590}
591
592static void
593antlr3BitsetRemove(pANTLR3_BITSET bitset, ANTLR3_UINT32 bit)
594{
595 ANTLR3_UINT32 wordNo;
596
597 wordNo = wordNumber(bit);
598
599 if (wordNo < bitset->blist.length)
600 {
601 bitset->blist.bits[wordNo] &= ~(bitMask(bit));
602 }
603}
604static ANTLR3_BOOLEAN
605antlr3BitsetIsNil(pANTLR3_BITSET bitset)
606{
607 ANTLR3_INT32 i;
608
609 for (i = bitset->blist.length -1; i>= 0; i--)
610 {
611 if (bitset->blist.bits[i] != 0)
612 {
613 return ANTLR3_FALSE0;
614 }
615 }
616
617 return ANTLR3_TRUE1;
618}
619
620static ANTLR3_UINT32
621numWordsToHold(ANTLR3_UINT32 bit)
622{
623 return (bit >> ANTLR3_BITSET_LOG_BITS6) + 1;
624}
625
626static ANTLR3_UINT32
627wordNumber(ANTLR3_UINT32 bit)
628{
629 return bit >> ANTLR3_BITSET_LOG_BITS6;
630}
631
632static ANTLR3_UINT32
633antlr3BitsetNumBits(pANTLR3_BITSET bitset)
634{
635 return bitset->blist.length << ANTLR3_BITSET_LOG_BITS6;
636}
637
638/** Produce an integer list of all the bits that are turned on
639 * in this bitset. Used for error processing in the main as the bitset
640 * reresents a number of integer tokens which we use for follow sets
641 * and so on.
642 *
643 * The first entry is the number of elements following in the list.
644 */
645static pANTLR3_INT32
646antlr3BitsetToIntList (pANTLR3_BITSET bitset)
647{
648 ANTLR3_UINT32 numInts; // How many integers we will need
649 ANTLR3_UINT32 numBits; // How many bits are in the set
650 ANTLR3_UINT32 i;
651 ANTLR3_UINT32 index;
652
653 pANTLR3_INT32 intList;
654
655 numInts = bitset->size(bitset) + 1;
656 numBits = bitset->numBits(bitset);
657
658 intList = (pANTLR3_INT32)ANTLR3_MALLOC(numInts * sizeof(ANTLR3_INT32))malloc ((size_t)(numInts * sizeof(ANTLR3_INT32)));;
659
660 if (intList == NULL((void*)0))
661 {
662 return NULL((void*)0); // Out of memory
663 }
664
665 intList[0] = numInts;
666
667 // Enumerate the bits that are turned on
668 //
669 for (i = 0, index = 1; i<numBits; i++)
670 {
671 if (bitset->isMember(bitset, i) == ANTLR3_TRUE1)
672 {
673 intList[index++] = i;
674 }
675 }
676
677 // Result set
678 //
679 return intList;
680}
681