]> git.saurik.com Git - wxWidgets.git/blame - src/common/list.cpp
don't crash when loading images with verbose==false (patch 1449823)
[wxWidgets.git] / src / common / list.cpp
CommitLineData
fd3f686c 1////////////////////////////////////////////////////////////////////////////////
7ec69821 2// Name: src/common/list.cpp
c801d85f
KB
3// Purpose: wxList implementation
4// Author: Julian Smart
fd3f686c 5// Modified by: VZ at 16/11/98: WX_DECLARE_LIST() and typesafe lists added
c801d85f
KB
6// Created: 04/01/98
7// RCS-ID: $Id$
55d99c7a 8// Copyright: (c) Julian Smart
65571936 9// Licence: wxWindows licence
fd3f686c 10////////////////////////////////////////////////////////////////////////////////
c801d85f 11
fd3f686c
VZ
12// =============================================================================
13// declarations
14// =============================================================================
15
16// -----------------------------------------------------------------------------
17// headers
18// -----------------------------------------------------------------------------
7daab453 19
c801d85f
KB
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
fd3f686c 24 #pragma hdrstop
c801d85f
KB
25#endif
26
fd3f686c
VZ
27#include <stdarg.h>
28#include <stdlib.h>
29#include <string.h>
30
c801d85f 31#ifndef WX_PRECOMP
fd3f686c
VZ
32 #include "wx/defs.h"
33 #include "wx/list.h"
c801d85f
KB
34#endif
35
df5168c4
MB
36#if !wxUSE_STL
37
fd3f686c
VZ
38// =============================================================================
39// implementation
40// =============================================================================
c801d85f 41
ff528365
VZ
42// -----------------------------------------------------------------------------
43// wxListKey
44// -----------------------------------------------------------------------------
8a2c6ef8
JS
45wxListKey wxDefaultListKey;
46
ff528365
VZ
47bool wxListKey::operator==(wxListKeyValue value) const
48{
49 switch ( m_keyType )
50 {
51 default:
223d09f6 52 wxFAIL_MSG(wxT("bad key type."));
ff528365
VZ
53 // let compiler optimize the line above away in release build
54 // by not putting return here...
55
56 case wxKEY_STRING:
50920146 57 return wxStrcmp(m_key.string, value.string) == 0;
ff528365
VZ
58
59 case wxKEY_INTEGER:
60 return m_key.integer == value.integer;
61 }
77c5eefb 62}
ff528365 63
fd3f686c
VZ
64// -----------------------------------------------------------------------------
65// wxNodeBase
66// -----------------------------------------------------------------------------
c801d85f 67
fd3f686c
VZ
68wxNodeBase::wxNodeBase(wxListBase *list,
69 wxNodeBase *previous, wxNodeBase *next,
70 void *data, const wxListKey& key)
c801d85f 71{
fd3f686c
VZ
72 m_list = list;
73 m_data = data;
74 m_previous = previous;
75 m_next = next;
77c5eefb 76
fd3f686c
VZ
77 switch ( key.GetKeyType() )
78 {
79 case wxKEY_NONE:
80 break;
77c5eefb 81
fd3f686c
VZ
82 case wxKEY_INTEGER:
83 m_key.integer = key.GetNumber();
84 break;
77c5eefb 85
fd3f686c
VZ
86 case wxKEY_STRING:
87 // to be free()d later
50920146 88 m_key.string = wxStrdup(key.GetString());
fd3f686c 89 break;
77c5eefb 90
fd3f686c 91 default:
223d09f6 92 wxFAIL_MSG(wxT("invalid key type"));
fd3f686c 93 }
77c5eefb 94
fd3f686c
VZ
95 if ( previous )
96 previous->m_next = this;
77c5eefb 97
fd3f686c
VZ
98 if ( next )
99 next->m_previous = this;
100}
c801d85f 101
fd3f686c
VZ
102wxNodeBase::~wxNodeBase()
103{
104 // handle the case when we're being deleted from the list by the user (i.e.
105 // not by the list itself from DeleteNode) - we must do it for
106 // compatibility with old code
107 if ( m_list != NULL )
108 {
09914df7
VZ
109 if ( m_list->m_keyType == wxKEY_STRING )
110 {
111 free(m_key.string);
112 }
113
fd3f686c
VZ
114 m_list->DetachNode(this);
115 }
c801d85f
KB
116}
117
77c5eefb
VZ
118int wxNodeBase::IndexOf() const
119{
223d09f6 120 wxCHECK_MSG( m_list, wxNOT_FOUND, wxT("node doesn't belong to a list in IndexOf"));
77c5eefb
VZ
121
122 // It would be more efficient to implement IndexOf() completely inside
123 // wxListBase (only traverse the list once), but this is probably a more
124 // reusable way of doing it. Can always be optimized at a later date (since
125 // IndexOf() resides in wxListBase as well) if efficiency is a problem.
126 int i;
127 wxNodeBase *prev = m_previous;
128
129 for( i = 0; prev; i++ )
130 {
131 prev = prev->m_previous;
132 }
133
134 return i;
135}
136
fd3f686c
VZ
137// -----------------------------------------------------------------------------
138// wxListBase
139// -----------------------------------------------------------------------------
140
62448488 141void wxListBase::Init(wxKeyType keyType)
c801d85f 142{
fd3f686c
VZ
143 m_nodeFirst =
144 m_nodeLast = (wxNodeBase *) NULL;
145 m_count = 0;
f644b28c 146 m_destroy = false;
fd3f686c
VZ
147 m_keyType = keyType;
148}
c801d85f 149
fd3f686c
VZ
150wxListBase::wxListBase(size_t count, void *elements[])
151{
152 Init();
c801d85f 153
fd3f686c
VZ
154 for ( size_t n = 0; n < count; n++ )
155 {
156 Append(elements[n]);
157 }
c801d85f
KB
158}
159
fd3f686c 160void wxListBase::DoCopy(const wxListBase& list)
c801d85f 161{
fd3f686c 162 wxASSERT_MSG( !list.m_destroy,
223d09f6 163 wxT("copying list which owns it's elements is a bad idea") );
c801d85f 164
fd3f686c
VZ
165 m_destroy = list.m_destroy;
166 m_keyType = list.m_keyType;
167 m_nodeFirst =
168 m_nodeLast = (wxNodeBase *) NULL;
c801d85f 169
3d0145a5
VZ
170 switch (m_keyType)
171 {
ecf9e593
VS
172 case wxKEY_INTEGER:
173 {
bcaa23de 174 long key;
ecf9e593
VS
175 for ( wxNodeBase *node = list.GetFirst(); node; node = node->GetNext() )
176 {
177 key = node->GetKeyInteger();
178 Append(key, node->GetData());
179 }
180 break;
181 }
182
183 case wxKEY_STRING:
184 {
bcaa23de 185 const wxChar *key;
ecf9e593
VS
186 for ( wxNodeBase *node = list.GetFirst(); node; node = node->GetNext() )
187 {
188 key = node->GetKeyString();
189 Append(key, node->GetData());
190 }
191 break;
192 }
193
194 default:
195 {
196 for ( wxNodeBase *node = list.GetFirst(); node; node = node->GetNext() )
197 {
198 Append(node->GetData());
199 }
200 break;
201 }
fd3f686c 202 }
f6bcfd97
BP
203
204 wxASSERT_MSG( m_count == list.m_count, _T("logic error in wxList::DoCopy") );
c801d85f
KB
205}
206
fd3f686c 207wxListBase::~wxListBase()
c801d85f 208{
fd3f686c
VZ
209 wxNodeBase *each = m_nodeFirst;
210 while ( each != NULL )
211 {
212 wxNodeBase *next = each->GetNext();
213 DoDeleteNode(each);
214 each = next;
215 }
c801d85f
KB
216}
217
fd3f686c 218wxNodeBase *wxListBase::AppendCommon(wxNodeBase *node)
c801d85f 219{
fd3f686c
VZ
220 if ( !m_nodeFirst )
221 {
222 m_nodeFirst = node;
223 m_nodeLast = m_nodeFirst;
224 }
225 else
226 {
227 m_nodeLast->m_next = node;
228 m_nodeLast = node;
229 }
230
231 m_count++;
232
233 return node;
c801d85f
KB
234}
235
fd3f686c 236wxNodeBase *wxListBase::Append(void *object)
c801d85f 237{
fd3f686c
VZ
238 // all objects in a keyed list should have a key
239 wxCHECK_MSG( m_keyType == wxKEY_NONE, (wxNodeBase *)NULL,
223d09f6 240 wxT("need a key for the object to append") );
c801d85f 241
7daab453
VZ
242 // we use wxDefaultListKey even though it is the default parameter value
243 // because gcc under Mac OS X seems to miscompile this call otherwise
244 wxNodeBase *node = CreateNode(m_nodeLast, (wxNodeBase *)NULL, object,
245 wxDefaultListKey);
fd3f686c
VZ
246
247 return AppendCommon(node);
c801d85f
KB
248}
249
fd3f686c 250wxNodeBase *wxListBase::Append(long key, void *object)
c801d85f 251{
fd3f686c
VZ
252 wxCHECK_MSG( (m_keyType == wxKEY_INTEGER) ||
253 (m_keyType == wxKEY_NONE && m_count == 0),
254 (wxNodeBase *)NULL,
223d09f6 255 wxT("can't append object with numeric key to this list") );
fd3f686c
VZ
256
257 wxNodeBase *node = CreateNode(m_nodeLast, (wxNodeBase *)NULL, object, key);
258 return AppendCommon(node);
c801d85f
KB
259}
260
50920146 261wxNodeBase *wxListBase::Append (const wxChar *key, void *object)
c801d85f 262{
fd3f686c
VZ
263 wxCHECK_MSG( (m_keyType == wxKEY_STRING) ||
264 (m_keyType == wxKEY_NONE && m_count == 0),
265 (wxNodeBase *)NULL,
223d09f6 266 wxT("can't append object with string key to this list") );
fd3f686c
VZ
267
268 wxNodeBase *node = CreateNode(m_nodeLast, (wxNodeBase *)NULL, object, key);
269 return AppendCommon(node);
270}
c801d85f 271
fd3f686c
VZ
272wxNodeBase *wxListBase::Insert(wxNodeBase *position, void *object)
273{
274 // all objects in a keyed list should have a key
275 wxCHECK_MSG( m_keyType == wxKEY_NONE, (wxNodeBase *)NULL,
223d09f6 276 wxT("need a key for the object to insert") );
c801d85f 277
ff528365 278 wxCHECK_MSG( !position || position->m_list == this, (wxNodeBase *)NULL,
223d09f6 279 wxT("can't insert before a node from another list") );
ff528365
VZ
280
281 // previous and next node for the node being inserted
282 wxNodeBase *prev, *next;
fd3f686c 283 if ( position )
ff528365 284 {
fd3f686c 285 prev = position->GetPrevious();
ff528365
VZ
286 next = position;
287 }
288 else
289 {
290 // inserting in the beginning of the list
291 prev = (wxNodeBase *)NULL;
292 next = m_nodeFirst;
293 }
c801d85f 294
7daab453
VZ
295 // wxDefaultListKey: see comment in Append() above
296 wxNodeBase *node = CreateNode(prev, next, object, wxDefaultListKey);
fd3f686c 297 if ( !m_nodeFirst )
c801d85f 298 {
fd3f686c 299 m_nodeLast = node;
c801d85f 300 }
c801d85f 301
fd3f686c 302 if ( prev == NULL )
c801d85f 303 {
fd3f686c 304 m_nodeFirst = node;
c801d85f 305 }
c801d85f 306
fd3f686c
VZ
307 m_count++;
308
c801d85f
KB
309 return node;
310}
311
fd3f686c 312wxNodeBase *wxListBase::Item(size_t n) const
c801d85f 313{
fd3f686c 314 for ( wxNodeBase *current = GetFirst(); current; current = current->GetNext() )
c801d85f 315 {
fd3f686c
VZ
316 if ( n-- == 0 )
317 {
318 return current;
319 }
c801d85f 320 }
c801d85f 321
223d09f6 322 wxFAIL_MSG( wxT("invalid index in wxListBase::Item") );
c801d85f 323
1b4092eb 324 return (wxNodeBase *)NULL;
c801d85f
KB
325}
326
fd3f686c 327wxNodeBase *wxListBase::Find(const wxListKey& key) const
c801d85f 328{
fd3f686c 329 wxASSERT_MSG( m_keyType == key.GetKeyType(),
223d09f6 330 wxT("this list is not keyed on the type of this key") );
c801d85f 331
fd3f686c
VZ
332 for ( wxNodeBase *current = GetFirst(); current; current = current->GetNext() )
333 {
334 if ( key == current->m_key )
335 {
336 return current;
337 }
338 }
c801d85f 339
fd3f686c
VZ
340 // not found
341 return (wxNodeBase *)NULL;
c801d85f
KB
342}
343
22d080f3 344wxNodeBase *wxListBase::Find(const void *object) const
c801d85f 345{
fd3f686c 346 for ( wxNodeBase *current = GetFirst(); current; current = current->GetNext() )
c801d85f 347 {
fd3f686c
VZ
348 if ( current->GetData() == object )
349 return current;
c801d85f 350 }
fd3f686c
VZ
351
352 // not found
353 return (wxNodeBase *)NULL;
c801d85f
KB
354}
355
77c5eefb
VZ
356int wxListBase::IndexOf(void *object) const
357{
358 wxNodeBase *node = Find( object );
359
3c67202d 360 return node ? node->IndexOf() : wxNOT_FOUND;
77c5eefb
VZ
361}
362
fd3f686c 363void wxListBase::DoDeleteNode(wxNodeBase *node)
c801d85f 364{
fd3f686c
VZ
365 // free node's data
366 if ( m_keyType == wxKEY_STRING )
c801d85f 367 {
fd3f686c 368 free(node->m_key.string);
c801d85f 369 }
c801d85f 370
fd3f686c 371 if ( m_destroy )
c801d85f 372 {
fd3f686c 373 node->DeleteData();
c801d85f 374 }
c801d85f 375
09914df7
VZ
376 // so that the node knows that it's being deleted by the list
377 node->m_list = NULL;
fd3f686c 378 delete node;
c801d85f
KB
379}
380
fd3f686c 381wxNodeBase *wxListBase::DetachNode(wxNodeBase *node)
c801d85f 382{
223d09f6 383 wxCHECK_MSG( node, NULL, wxT("detaching NULL wxNodeBase") );
fd3f686c 384 wxCHECK_MSG( node->m_list == this, NULL,
223d09f6 385 wxT("detaching node which is not from this list") );
c801d85f 386
fd3f686c
VZ
387 // update the list
388 wxNodeBase **prevNext = node->GetPrevious() ? &node->GetPrevious()->m_next
389 : &m_nodeFirst;
390 wxNodeBase **nextPrev = node->GetNext() ? &node->GetNext()->m_previous
391 : &m_nodeLast;
c801d85f 392
fd3f686c
VZ
393 *prevNext = node->GetNext();
394 *nextPrev = node->GetPrevious();
c801d85f 395
fd3f686c 396 m_count--;
c801d85f 397
fd3f686c
VZ
398 // mark the node as not belonging to this list any more
399 node->m_list = NULL;
c801d85f 400
fd3f686c 401 return node;
c801d85f
KB
402}
403
fd3f686c 404bool wxListBase::DeleteNode(wxNodeBase *node)
c801d85f 405{
fd3f686c 406 if ( !DetachNode(node) )
f644b28c 407 return false;
fd3f686c
VZ
408
409 DoDeleteNode(node);
410
f644b28c 411 return true;
c801d85f
KB
412}
413
fd3f686c 414bool wxListBase::DeleteObject(void *object)
c801d85f 415{
fd3f686c
VZ
416 for ( wxNodeBase *current = GetFirst(); current; current = current->GetNext() )
417 {
418 if ( current->GetData() == object )
419 {
420 DeleteNode(current);
f644b28c 421 return true;
fd3f686c
VZ
422 }
423 }
424
425 // not found
f644b28c 426 return false;
c801d85f
KB
427}
428
fd3f686c 429void wxListBase::Clear()
c801d85f 430{
fd3f686c
VZ
431 wxNodeBase *current = m_nodeFirst;
432 while ( current )
c801d85f 433 {
fd3f686c
VZ
434 wxNodeBase *next = current->GetNext();
435 DoDeleteNode(current);
436 current = next;
c801d85f 437 }
fd3f686c
VZ
438
439 m_nodeFirst =
440 m_nodeLast = (wxNodeBase *)NULL;
441
442 m_count = 0;
c801d85f
KB
443}
444
fd3f686c 445void wxListBase::ForEach(wxListIterateFunction F)
c801d85f 446{
fd3f686c
VZ
447 for ( wxNodeBase *current = GetFirst(); current; current = current->GetNext() )
448 {
449 (*F)(current->GetData());
c801d85f
KB
450 }
451}
fd3f686c
VZ
452
453void *wxListBase::FirstThat(wxListIterateFunction F)
c801d85f 454{
fd3f686c
VZ
455 for ( wxNodeBase *current = GetFirst(); current; current = current->GetNext() )
456 {
457 if ( (*F)(current->GetData()) )
458 return current->GetData();
c801d85f 459 }
fd3f686c
VZ
460
461 return (wxNodeBase *)NULL;
c801d85f 462}
fd3f686c
VZ
463
464void *wxListBase::LastThat(wxListIterateFunction F)
c801d85f 465{
fd3f686c
VZ
466 for ( wxNodeBase *current = GetLast(); current; current = current->GetPrevious() )
467 {
468 if ( (*F)(current->GetData()) )
469 return current->GetData();
c801d85f 470 }
fd3f686c
VZ
471
472 return (wxNodeBase *)NULL;
c801d85f
KB
473}
474
475// (stefan.hammes@urz.uni-heidelberg.de)
476//
477// function for sorting lists. the concept is borrowed from 'qsort'.
478// by giving a sort function, arbitrary lists can be sorted.
479// method:
480// - put wxObject pointers into an array
481// - sort the array with qsort
482// - put back the sorted wxObject pointers into the list
483//
484// CAVE: the sort function receives pointers to wxObject pointers (wxObject **),
485// so dereference right!
486// EXAMPLE:
487// int listcompare(const void *arg1, const void *arg2)
488// {
489// return(compare(**(wxString **)arg1,
490// **(wxString **)arg2));
491// }
492//
493// void main()
fd3f686c
VZ
494// {
495// wxListBase list;
c801d85f
KB
496//
497// list.Append(new wxString("DEF"));
498// list.Append(new wxString("GHI"));
499// list.Append(new wxString("ABC"));
500// list.Sort(listcompare);
501// }
502
fd3f686c 503void wxListBase::Sort(const wxSortCompareFunction compfunc)
c801d85f 504{
fd3f686c
VZ
505 // allocate an array for the wxObject pointers of the list
506 const size_t num = GetCount();
507 void **objArray = new void *[num];
508 void **objPtr = objArray;
509
510 // go through the list and put the pointers into the array
511 wxNodeBase *node;
b1d4dd7a 512 for ( node = GetFirst(); node; node = node->GetNext() )
fd3f686c 513 {
b1d4dd7a 514 *objPtr++ = node->GetData();
fd3f686c
VZ
515 }
516
517 // sort the array
1c193821
JS
518 qsort((void *)objArray,num,sizeof(wxObject *),
519#ifdef __WXWINCE__
520 (int (__cdecl *)(const void *,const void *))
521#endif
522 compfunc);
fd3f686c
VZ
523
524 // put the sorted pointers back into the list
525 objPtr = objArray;
b1d4dd7a 526 for ( node = GetFirst(); node; node = node->GetNext() )
fd3f686c
VZ
527 {
528 node->SetData(*objPtr++);
529 }
530
531 // free the array
532 delete[] objArray;
c801d85f
KB
533}
534
df5168c4
MB
535void wxListBase::Reverse()
536{
537 wxNodeBase* node = m_nodeFirst;
538 wxNodeBase* tmp;
539
540 while (node)
541 {
542 // swap prev and next pointers
543 tmp = node->m_next;
544 node->m_next = node->m_previous;
545 node->m_previous = tmp;
546
547 // this is the node that was next before swapping
548 node = tmp;
549 }
550
551 // swap first and last node
552 tmp = m_nodeFirst; m_nodeFirst = m_nodeLast; m_nodeLast = tmp;
553}
554
555void wxListBase::DeleteNodes(wxNodeBase* first, wxNodeBase* last)
556{
557 wxNodeBase* node = first;
558
559 while (node != last)
560 {
561 wxNodeBase* next = node->GetNext();
562 DeleteNode(node);
563 node = next;
564 }
565}
566
f98bd52a
VZ
567// ============================================================================
568// compatibility section from now on
569// ============================================================================
570
571#ifdef wxLIST_COMPATIBILITY
572
fd3f686c
VZ
573// -----------------------------------------------------------------------------
574// wxList (a.k.a. wxObjectList)
575// -----------------------------------------------------------------------------
c801d85f 576
f98bd52a
VZ
577IMPLEMENT_DYNAMIC_CLASS(wxList, wxObject)
578
b1d4dd7a
RL
579wxList::wxList( int key_type )
580 : wxObjectList( (wxKeyType)key_type )
581{
582}
583
fd3f686c 584void wxObjectListNode::DeleteData()
c801d85f 585{
fd3f686c 586 delete (wxObject *)GetData();
c801d85f
KB
587}
588
f526f752 589// ----------------------------------------------------------------------------
fd3f686c 590// wxStringList
f526f752
MB
591// ----------------------------------------------------------------------------
592
f526f752
MB
593static inline wxChar* MYcopystring(const wxChar* s)
594{
595 wxChar* copy = new wxChar[wxStrlen(s) + 1];
596 return wxStrcpy(copy, s);
597}
fd3f686c 598
f98bd52a
VZ
599IMPLEMENT_DYNAMIC_CLASS(wxStringList, wxObject)
600
fd3f686c
VZ
601// instead of WX_DEFINE_LIST(wxStringListBase) we define this function
602// ourselves
603void wxStringListNode::DeleteData()
341287bf 604{
fd3f686c 605 delete [] (char *)GetData();
341287bf
JS
606}
607
50920146 608bool wxStringList::Delete(const wxChar *s)
f0824a5a
VZ
609{
610 wxStringListNode *current;
611
612 for ( current = GetFirst(); current; current = current->GetNext() )
613 {
50920146 614 if ( wxStrcmp(current->GetData(), s) == 0 )
f0824a5a
VZ
615 {
616 DeleteNode(current);
f644b28c 617 return true;
f0824a5a
VZ
618 }
619 }
620
621 // not found
f644b28c 622 return false;
f0824a5a
VZ
623}
624
db9504c5
VZ
625void wxStringList::DoCopy(const wxStringList& other)
626{
627 wxASSERT( GetCount() == 0 ); // this list must be empty before copying!
628
629 size_t count = other.GetCount();
630 for ( size_t n = 0; n < count; n++ )
631 {
77c5eefb 632 Add(other.Item(n)->GetData());
db9504c5
VZ
633 }
634}
635
b1d4dd7a
RL
636wxStringList::wxStringList()
637{
f644b28c 638 DeleteContents(true);
b1d4dd7a
RL
639}
640
c801d85f
KB
641// Variable argument list, terminated by a zero
642// Makes new storage for the strings
50920146 643wxStringList::wxStringList (const wxChar *first, ...)
c801d85f 644{
f644b28c 645 DeleteContents(true);
fd3f686c 646 if ( !first )
c801d85f
KB
647 return;
648
649 va_list ap;
fd3f686c 650 va_start(ap, first);
c801d85f 651
50920146 652 const wxChar *s = first;
c801d85f 653 for (;;)
fd3f686c
VZ
654 {
655 Add(s);
656
2cfcf22d
VZ
657 // icc gives this warning in its own va_arg() macro, argh
658#ifdef __INTELC__
659 #pragma warning(push)
660 #pragma warning(disable: 1684)
661#endif
662
50920146 663 s = va_arg(ap, const wxChar *);
2cfcf22d
VZ
664
665#ifdef __INTELC__
666 #pragma warning(pop)
c801d85f 667#endif
2cfcf22d
VZ
668
669 if ( !s )
fd3f686c
VZ
670 break;
671 }
c801d85f 672
fd3f686c 673 va_end(ap);
341287bf
JS
674}
675
f644b28c 676// Only makes new strings if arg is true
50920146 677wxChar **wxStringList::ListToArray(bool new_copies) const
341287bf 678{
50920146 679 wxChar **string_array = new wxChar *[GetCount()];
fd3f686c
VZ
680 wxStringListNode *node = GetFirst();
681 for (size_t i = 0; i < GetCount(); i++)
c801d85f 682 {
50920146 683 wxChar *s = node->GetData();
fd3f686c 684 if ( new_copies )
f526f752 685 string_array[i] = MYcopystring(s);
fd3f686c
VZ
686 else
687 string_array[i] = s;
688 node = node->GetNext();
c801d85f 689 }
c801d85f 690
fd3f686c 691 return string_array;
c801d85f
KB
692}
693
fd3f686c 694// Checks whether s is a member of the list
50920146 695bool wxStringList::Member(const wxChar *s) const
c801d85f 696{
fd3f686c 697 for ( wxStringListNode *node = GetFirst(); node; node = node->GetNext() )
c801d85f 698 {
50920146
OK
699 const wxChar *s1 = node->GetData();
700 if (s == s1 || wxStrcmp (s, s1) == 0)
f644b28c 701 return true;
c801d85f 702 }
fd3f686c 703
f644b28c 704 return false;
c801d85f
KB
705}
706
1c193821
JS
707#ifdef __WXWINCE__
708extern "C" int __cdecl
709#else
90350682 710extern "C" int LINKAGEMODE
1c193821
JS
711#endif
712
fd3f686c 713wx_comparestrings(const void *arg1, const void *arg2)
c801d85f 714{
50920146
OK
715 wxChar **s1 = (wxChar **) arg1;
716 wxChar **s2 = (wxChar **) arg2;
c801d85f 717
50920146 718 return wxStrcmp (*s1, *s2);
c801d85f
KB
719}
720
721// Sort a list of strings - deallocates old nodes, allocates new
fd3f686c 722void wxStringList::Sort()
c801d85f 723{
fd3f686c 724 size_t N = GetCount();
50920146 725 wxChar **array = new wxChar *[N];
2a040d3f 726 wxStringListNode *node;
c801d85f 727
fd3f686c 728 size_t i = 0;
2a040d3f 729 for ( node = GetFirst(); node; node = node->GetNext() )
c801d85f 730 {
fd3f686c 731 array[i++] = node->GetData();
c801d85f 732 }
341287bf 733
50920146 734 qsort (array, N, sizeof (wxChar *), wx_comparestrings);
341287bf 735
9257d0b7
VZ
736 i = 0;
737 for ( node = GetFirst(); node; node = node->GetNext() )
738 node->SetData( array[i++] );
341287bf 739
9257d0b7 740 delete [] array;
341287bf 741}
f98bd52a 742
f526f752
MB
743wxNode *wxStringList::Add(const wxChar *s)
744{
d4d8988c
VZ
745 return (wxNode *)(wxStringListBase::Node *)
746 wxStringListBase::Append(MYcopystring(s));
f526f752 747}
f644b28c 748
f526f752
MB
749wxNode *wxStringList::Prepend(const wxChar *s)
750{
d4d8988c
VZ
751 return (wxNode *)(wxStringListBase::Node *)
752 wxStringListBase::Insert(MYcopystring(s));
f526f752
MB
753}
754
f98bd52a
VZ
755#endif // wxLIST_COMPATIBILITY
756
ed1288c1
VZ
757#else // wxUSE_STL = 1
758
7ec69821 759 #include "wx/listimpl.cpp"
412e0d47 760 WX_DEFINE_LIST(wxObjectList)
3543c79e
MB
761
762// with wxUSE_STL wxStringList contains wxString objects, not pointers
30a29593 763void _WX_LIST_HELPER_wxStringListBase::DeleteFunction( wxString WXUNUSED(X) )
3543c79e
MB
764{
765}
ed1288c1 766
df5168c4 767#endif // !wxUSE_STL