18 WPLString
= 0x57504c01,
20 WPLArray
= 0x57504c03,
21 WPLDictionary
= 0x57504c04
25 typedef struct W_PropList
{
40 static unsigned hashPropList(WMPropList
*plist
);
44 typedef unsigned (*hashFunc
)(const void*);
45 typedef Bool (*isEqualFunc
)(const void*, const void*);
46 typedef void* (*retainFunc
)(const void*);
47 typedef void (*releaseFunc
)(const void*);
49 static const WMHashTableCallbacks WMPropListHashCallbacks
= {
50 (hashFunc
)hashPropList
,
51 (isEqualFunc
)WMIsPropListEqualToPropList
,
57 static WMCompareDataProc
*strCmp
= (WMCompareDataProc
*) strcmp
;
60 #define MaxHashLength 64
64 hashPropList(WMPropList
*plist
)
71 switch (plist
->type
) {
73 key
= plist
->d
.string
;
74 len
= WMIN(strlen(key
), MaxHashLength
);
75 for (i
=0; i
<len
; i
++) {
76 ret
^= tolower(key
[i
]) << ctr
;
77 ctr
= (ctr
+ 1) % sizeof (char *);
80 ret ^= tolower(*key++) << ctr;
81 ctr = (ctr + 1) % sizeof (char *);
84 /*return strlen(plist->d.string);*/
87 key
= WMDataBytes(plist
->d
.data
);
88 len
= WMIN(WMGetDataLength(plist
->d
.data
), MaxHashLength
);
89 for (i
=0; i
<len
; i
++) {
91 ctr
= (ctr
+ 1) % sizeof (char *);
94 /*return WMGetDataLength(plist->d.data);*/
97 wwarning(_("Only string or data is supported for a proplist dictionary key"));
102 /*WMSetPropListStringComparisonCaseSensitive
103 WMSetPropListStringComparerIsCaseSensitive
104 WMSetPLStringComparisonCaseSensitive*/
107 retainPropListByCount(WMPropList
*plist
, int count
)
109 WMPropList
*key
, *value
;
113 plist
->retainCount
+= count
;
115 switch(plist
->type
) {
120 for (i
=0; i
<WMGetArrayItemCount(plist
->d
.array
); i
++) {
121 retainPropListByCount(WMGetFromArray(plist
->d
.array
, i
), count
);
125 e
= WMEnumerateHashTable(plist
->d
.dict
);
126 while (WMNextHashEnumeratorItemAndKey(&e
, (void**)&value
, (void**)&key
)) {
127 retainPropListByCount(key
, count
);
128 retainPropListByCount(value
, count
);
132 wwarning(_("Used proplist functions on non-WMPropLists objects"));
133 wassertrv(False
, NULL
);
141 releasePropListByCount(WMPropList
*plist
, int count
)
143 WMPropList
*key
, *value
;
147 plist
->retainCount
-= count
;
149 switch(plist
->type
) {
151 if (plist
->retainCount
< 1) {
152 wfree(plist
->d
.string
);
157 if (plist
->retainCount
< 1) {
158 WMReleaseData(plist
->d
.data
);
163 for (i
=0; i
<WMGetArrayItemCount(plist
->d
.array
); i
++) {
164 releasePropListByCount(WMGetFromArray(plist
->d
.array
, i
), count
);
166 if (plist
->retainCount
< 1) {
167 WMFreeArray(plist
->d
.array
);
172 e
= WMEnumerateHashTable(plist
->d
.dict
);
173 while (WMNextHashEnumeratorItemAndKey(&e
, (void**)&value
, (void**)&key
)) {
174 releasePropListByCount(key
, count
);
175 releasePropListByCount(value
, count
);
177 if (plist
->retainCount
< 1) {
178 WMFreeHashTable(plist
->d
.dict
);
183 wwarning(_("Used proplist functions on non-WMPropLists objects"));
189 #define num2char(num) ((num) < 0xa ? ((num)+'0') : ((num)+0x57))
192 dataDescription(WMPropList
*plist
)
194 const unsigned char *data
;
198 data
= WMDataBytes(plist
->d
.data
);
199 length
= WMGetDataLength(plist
->d
.data
);
201 retVal
= (char*)wmalloc(2*length
+length
/4+3);
204 for (i
=0, j
=1; i
<length
; i
++) {
205 retVal
[j
++] = num2char((data
[i
]>>4) & 0x0f);
206 retVal
[j
++] = num2char(data
[i
] & 0x0f);
207 if ((i
& 0x03)==3 && i
!=length
-1) {
208 /* if we've just finished a 32-bit int, add a space */
220 stringDescription(WMPropList
*plist
)
223 char *retVal
, *sPtr
, *dPtr
;
227 str
= plist
->d
.string
;
229 if (strlen(str
) == 0) {
230 return wstrdup("\"\"");
233 /* FIXME: make this work with unichars. */
235 #define inrange(ch, min, max) ((ch)>=(min) && (ch)<=(max))
236 #define noquote(ch) (inrange(ch, 'a', 'z') || inrange(ch, 'A', 'Z') || inrange(ch, '0', '9') || ((ch)=='_') || ((ch)=='.') || ((ch)=='$'))
237 #define charesc(ch) (inrange(ch, 0x07, 0x0c) || ((ch)=='"') || ((ch)=='\\'))
238 #define numesc(ch) (((ch)<=0x06) || inrange(ch, 0x0d, 0x1f) || ((ch)>0x7e))
243 while ((ch
= *sPtr
)) {
258 retVal
= (char*)wmalloc(len
+1);
266 while ((ch
= *sPtr
)) {
270 case '\a': *dPtr
= 'a'; break;
271 case '\b': *dPtr
= 'b'; break;
272 case '\t': *dPtr
= 't'; break;
273 case '\n': *dPtr
= 'n'; break;
274 case '\v': *dPtr
= 'v'; break;
275 case '\f': *dPtr
= 'f'; break;
276 default: *dPtr
= ch
; /* " or \ */
278 } else if (numesc(ch
)) {
280 *(dPtr
++) = '0' + ((ch
>>6)&07);
281 *(dPtr
++) = '0' + ((ch
>>3)&07);
282 *dPtr
= '0' + (ch
&07);
300 description(WMPropList
*plist
)
302 WMPropList
*key
, *val
;
303 char *retstr
, *str
, *tmp
, *skey
, *sval
;
307 switch (plist
->type
) {
309 return stringDescription(plist
);
311 return dataDescription(plist
);
313 retstr
= wstrdup("(");
314 for (i
=0; i
<WMGetArrayItemCount(plist
->d
.array
); i
++) {
315 str
= description(WMGetFromArray(plist
->d
.array
, i
));
317 retstr
= wstrappend(retstr
, str
);
319 tmp
= (char *)wmalloc(strlen(retstr
)+strlen(str
)+3);
320 sprintf(tmp
, "%s, %s", retstr
, str
);
326 retstr
= wstrappend(retstr
, ")");
329 retstr
= wstrdup("{");
330 e
= WMEnumerateHashTable(plist
->d
.dict
);
331 while (WMNextHashEnumeratorItemAndKey(&e
, (void**)&val
, (void**)&key
)) {
332 skey
= description(key
);
333 sval
= description(val
);
334 tmp
= (char*)wmalloc(strlen(retstr
)+strlen(skey
)+strlen(sval
)+5);
335 sprintf(tmp
, "%s%s = %s;", retstr
, skey
, sval
);
341 retstr
= wstrappend(retstr
, "}");
344 wwarning(_("Used proplist functions on non-WMPropLists objects"));
345 wassertrv(False
, NULL
);
353 indentedDescription(WMPropList
*plist
, int level
)
355 WMPropList
*key
, *val
;
356 char *retstr
, *str
, *tmp
, *skey
, *sval
;
360 switch (plist
->type
) {
362 return stringDescription(plist
);
364 return dataDescription(plist
);
366 retstr
= wstrdup("(\n");
367 for (i
=0; i
<WMGetArrayItemCount(plist
->d
.array
); i
++) {
368 str
= indentedDescription(WMGetFromArray(plist
->d
.array
, i
),
371 tmp
= (char*)wmalloc(2*(level
+1)+strlen(retstr
)+strlen(str
)+1);
372 sprintf(tmp
, "%s%*s%s", retstr
, 2*(level
+1), "", str
);
376 tmp
= (char*)wmalloc(2*(level
+1)+strlen(retstr
)+strlen(str
)+3);
377 sprintf(tmp
, "%s,\n%*s%s", retstr
, 2*(level
+1), "", str
);
383 tmp
= (char*)wmalloc(strlen(retstr
) + 2*level
+ 3);
384 sprintf(tmp
, "%s\n%*s)", retstr
, 2*level
, "");
389 retstr
= wstrdup("{\n");
390 e
= WMEnumerateHashTable(plist
->d
.dict
);
391 while (WMNextHashEnumeratorItemAndKey(&e
, (void**)&val
, (void**)&key
)) {
392 skey
= indentedDescription(key
, level
+1);
393 sval
= indentedDescription(val
, level
+1);
394 tmp
= (char*)wmalloc(2*(level
+1) + strlen(retstr
) + strlen(skey
)
396 sprintf(tmp
, "%s%*s%s = %s;\n", retstr
, 2*(level
+1), "",
403 tmp
= (char*)wmalloc(strlen(retstr
) + 2*level
+ 2);
404 sprintf(tmp
, "%s%*s}", retstr
, 2*level
, "");
409 wwarning(_("Used proplist functions on non-WMPropLists objects"));
410 wassertrv(False
, NULL
);
418 WMSetPropListStringComparer(WMCompareDataProc
*comparer
)
421 strCmp
= (WMCompareDataProc
*) strcmp
;
428 WMCreatePropListString(char *str
)
432 wassertrv(str
!=NULL
, NULL
);
434 plist
= (WMPropList
*)wmalloc(sizeof(W_PropList
));
436 plist
->type
= WPLString
;
437 plist
->d
.string
= wstrdup(str
);
438 plist
->retainCount
= 1;
445 WMCreatePropListDataWithBytes(unsigned char *bytes
, unsigned int length
)
449 wassertrv(bytes
!=NULL
, NULL
);
451 plist
= (WMPropList
*)wmalloc(sizeof(W_PropList
));
453 plist
->type
= WPLData
;
454 plist
->d
.data
= WMCreateDataWithBytes(bytes
, length
);
455 plist
->retainCount
= 1;
462 WMCreatePropListDataWithBytesNoCopy(unsigned char *bytes
, unsigned int length
,
463 WMFreeDataProc
*destructor
)
467 wassertrv(bytes
!=NULL
, NULL
);
469 plist
= (WMPropList
*)wmalloc(sizeof(W_PropList
));
471 plist
->type
= WPLData
;
472 plist
->d
.data
= WMCreateDataWithBytesNoCopy(bytes
, length
, destructor
);
473 plist
->retainCount
= 1;
480 WMCreatePropListDataWithData(WMData
*data
)
484 wassertrv(data
!=NULL
, NULL
);
486 plist
= (WMPropList
*)wmalloc(sizeof(W_PropList
));
488 plist
->type
= WPLData
;
489 plist
->d
.data
= WMRetainData(data
);
490 plist
->retainCount
= 1;
497 WMCreatePropListArrayFromElements(WMPropList
*elem
, ...)
499 WMPropList
*plist
, *nelem
;
502 plist
= (WMPropList
*)wmalloc(sizeof(W_PropList
));
503 plist
->type
= WPLArray
;
504 plist
->d
.array
= WMCreateArray(4);
505 plist
->retainCount
= 1;
510 WMAddToArray(plist
->d
.array
, WMRetainPropList(elem
));
515 nelem
= va_arg(ap
, WMPropList
*);
520 WMAddToArray(plist
->d
.array
, WMRetainPropList(nelem
));
526 WMCreatePropListDictionaryFromEntries(WMPropList
*key
, WMPropList
*value
, ...)
528 WMPropList
*plist
, *nkey
, *nvalue
, *k
, *v
;
531 plist
= (WMPropList
*)wmalloc(sizeof(W_PropList
));
532 plist
->type
= WPLDictionary
;
533 plist
->d
.dict
= WMCreateHashTable(WMPropListHashCallbacks
);
534 plist
->retainCount
= 1;
539 WMHashInsert(plist
->d
.dict
, WMRetainPropList(key
), WMRetainPropList(value
));
544 nkey
= va_arg(ap
, WMPropList
*);
549 nvalue
= va_arg(ap
, WMPropList
*);
554 if (WMHashGetItemAndKey(plist
->d
.dict
, nkey
, (void**)&v
, (void**)&k
)) {
555 WMHashRemove(plist
->d
.dict
, k
);
556 WMReleasePropList(k
);
557 WMReleasePropList(v
);
559 WMHashInsert(plist
->d
.dict
, WMRetainPropList(nkey
),
560 WMRetainPropList(nvalue
));
566 WMInsertPropListArrayElement(WMPropList
*plist
, WMPropList
*item
, int index
)
568 wassertr(plist
->type
==WPLArray
);
570 retainPropListByCount(item
, plist
->retainCount
);
571 WMInsertInArray(plist
->d
.array
, index
, item
);
576 WMAppendPropListArrayElement(WMPropList
*plist
, WMPropList
*item
)
578 wassertr(plist
->type
==WPLArray
);
580 retainPropListByCount(item
, plist
->retainCount
);
581 WMAddToArray(plist
->d
.array
, item
);
586 WMRemovePropListArrayElement(WMPropList
*plist
, int index
)
590 wassertr(plist
->type
==WPLArray
);
592 item
= WMGetFromArray(plist
->d
.array
, index
);
594 WMDeleteFromArray(plist
->d
.array
, index
);
595 releasePropListByCount(item
, plist
->retainCount
);
601 WMInsertPropListDictionaryEntry(WMPropList
*plist
, WMPropList
*key
,
604 wassertr(plist
->type
==WPLDictionary
);
606 WMRemovePropListDictionaryEntry(plist
, key
);
607 retainPropListByCount(key
, plist
->retainCount
);
608 retainPropListByCount(value
, plist
->retainCount
);
609 WMHashInsert(plist
->d
.dict
, key
, value
);
614 WMRemovePropListDictionaryEntry(WMPropList
*plist
, WMPropList
*key
)
618 wassertr(plist
->type
==WPLDictionary
);
620 if (WMHashGetItemAndKey(plist
->d
.dict
, key
, (void**)&v
, (void**)&k
)) {
621 WMHashRemove(plist
->d
.dict
, k
);
622 releasePropListByCount(k
, plist
->retainCount
);
623 releasePropListByCount(v
, plist
->retainCount
);
629 WMMergePropListDictionaries(WMPropList
*dest
, WMPropList
*source
)
631 WMPropList
*key
, *value
;
634 wassertr(source
->type
==WPLDictionary
&& dest
->type
==WPLDictionary
);
636 e
= WMEnumerateHashTable(source
->d
.dict
);
637 while (WMNextHashEnumeratorItemAndKey(&e
, (void**)&value
, (void**)&key
)) {
638 WMInsertPropListDictionaryEntry(dest
, key
, value
);
646 WMRetainPropList(WMPropList
*plist
)
648 WMPropList
*key
, *value
;
652 plist
->retainCount
++;
654 switch(plist
->type
) {
659 for (i
=0; i
<WMGetArrayItemCount(plist
->d
.array
); i
++) {
660 WMRetainPropList(WMGetFromArray(plist
->d
.array
, i
));
664 e
= WMEnumerateHashTable(plist
->d
.dict
);
665 while (WMNextHashEnumeratorItemAndKey(&e
, (void**)&value
, (void**)&key
)) {
666 WMRetainPropList(key
);
667 WMRetainPropList(value
);
671 wwarning(_("Used proplist functions on non-WMPropLists objects"));
672 wassertrv(False
, NULL
);
680 WMReleasePropList(WMPropList
*plist
)
682 WMPropList
*key
, *value
;
686 plist
->retainCount
--;
688 switch(plist
->type
) {
690 if (plist
->retainCount
< 1) {
691 wfree(plist
->d
.string
);
696 if (plist
->retainCount
< 1) {
697 WMReleaseData(plist
->d
.data
);
702 for (i
=0; i
<WMGetArrayItemCount(plist
->d
.array
); i
++) {
703 WMReleasePropList(WMGetFromArray(plist
->d
.array
, i
));
705 if (plist
->retainCount
< 1) {
706 WMFreeArray(plist
->d
.array
);
711 e
= WMEnumerateHashTable(plist
->d
.dict
);
712 while (WMNextHashEnumeratorItemAndKey(&e
, (void**)&value
, (void**)&key
)) {
713 WMReleasePropList(key
);
714 WMReleasePropList(value
);
716 if (plist
->retainCount
< 1) {
717 WMFreeHashTable(plist
->d
.dict
);
722 wwarning(_("Used proplist functions on non-WMPropLists objects"));
729 WMPropListIsString(WMPropList
*plist
)
731 return (plist
->type
== WPLString
);
736 WMPropListIsData(WMPropList
*plist
)
738 return (plist
->type
== WPLData
);
743 WMPropListIsArray(WMPropList
*plist
)
745 return (plist
->type
== WPLArray
);
750 WMPropListIsDictionary(WMPropList
*plist
)
752 return (plist
->type
== WPLDictionary
);
757 WMPropListIsSimple(WMPropList
*plist
)
759 return (plist
->type
==WPLString
|| plist
->type
==WPLData
);
764 WMPropListIsCompound(WMPropList
*plist
)
766 return (plist
->type
==WPLArray
|| plist
->type
==WPLDictionary
);
771 WMIsPropListEqualToPropList(WMPropList
*plist
, WMPropList
*other
)
773 WMPropList
*key1
, *item1
, *item2
;
774 WMHashEnumerator enumerator
;
777 if (plist
->type
!= other
->type
)
780 switch(plist
->type
) {
782 return (strCmp(plist
->d
.string
, other
->d
.string
) == 0);
784 return WMIsDataEqualToData(plist
->d
.data
, other
->d
.data
);
786 n
= WMGetArrayItemCount(plist
->d
.array
);
787 if (n
!= WMGetArrayItemCount(other
->d
.array
))
789 for (i
=0; i
<n
; i
++) {
790 item1
= WMGetFromArray(plist
->d
.array
, i
);
791 item2
= WMGetFromArray(other
->d
.array
, i
);
792 if (!WMIsPropListEqualToPropList(item1
, item2
))
797 if (WMCountHashTable(plist
->d
.dict
) != WMCountHashTable(other
->d
.dict
))
799 enumerator
= WMEnumerateHashTable(plist
->d
.dict
);
800 while (WMNextHashEnumeratorItemAndKey(&enumerator
, (void**)&item1
,
802 item2
= WMHashGet(other
->d
.dict
, key1
);
803 if (!item2
|| !item1
|| !WMIsPropListEqualToPropList(item1
, item2
))
808 wwarning(_("Used proplist functions on non-WMPropLists objects"));
809 wassertrv(False
, False
);
817 WMGetPropListNumberOfElements(WMPropList
*plist
)
819 switch(plist
->type
) {
822 return 0; /* should this be 1 instead? */
824 return WMGetArrayItemCount(plist
->d
.array
);
826 return (int)WMCountHashTable(plist
->d
.dict
);
828 wwarning(_("Used proplist functions on non-WMPropLists objects"));
835 WMGetPropListString(WMPropList
*plist
)
837 wassertrv(plist
->type
==WPLString
, NULL
);
839 return plist
->d
.string
;
844 WMGetPropListData(WMPropList
*plist
)
846 wassertrv(plist
->type
==WPLData
, NULL
);
848 return plist
->d
.data
;
853 WMGetPropListDataBytes(WMPropList
*plist
)
855 wassertrv(plist
->type
==WPLData
, NULL
);
857 return WMDataBytes(plist
->d
.data
);
862 WMGetPropListDataLength(WMPropList
*plist
)
864 wassertrv(plist
->type
==WPLData
, 0);
866 return WMGetDataLength(plist
->d
.data
);
871 WMGetPropListArrayElement(WMPropList
*plist
, int index
)
873 wassertrv(plist
->type
==WPLArray
, NULL
);
875 return WMGetFromArray(plist
->d
.array
, index
);
880 WMGetPropListDictionaryEntry(WMPropList
*plist
, WMPropList
*key
)
882 wassertrv(plist
->type
==WPLDictionary
, NULL
);
884 return WMHashGet(plist
->d
.dict
, key
);
889 WMGetPropListAllDictionaryKeys(WMPropList
*plist
)
891 WMPropList
*array
, *key
;
892 WMHashEnumerator enumerator
;
894 wassertrv(plist
->type
==WPLDictionary
, NULL
);
896 array
= (WMPropList
*)wmalloc(sizeof(W_PropList
));
897 array
->type
= WPLArray
;
898 array
->d
.array
= WMCreateArray(WMCountHashTable(plist
->d
.dict
));
899 array
->retainCount
= 1;
901 enumerator
= WMEnumerateHashTable(plist
->d
.dict
);
902 while ((key
= WMNextHashEnumeratorKey(&enumerator
))) {
903 WMAddToArray(array
->d
.array
, WMRetainPropList(key
));
911 WMGetPropListDescription(WMPropList
*plist
, Bool indented
)
913 return (indented
? indentedDescription(plist
, 0) : description(plist
));
918 /* TODO: review this function's code */
921 WMSavePropListToFile(WMPropList
*plist
, char *path
, Bool atomically
)
932 /* Use the path name of the destination file as a prefix for the
933 * mkstemp() call so that we can be sure that both files are on
934 * the same filesystem and the subsequent rename() will work. */
935 thePath
= wstrconcat(path
, ".XXXXXX");
938 if ((fd
= mkstemp(thePath
)) < 0) {
939 wsyserror(_("mkstemp (%s) failed"), thePath
);
944 fchmod(fd
, 0644 & ~mask
);
945 if ((theFile
= fdopen(fd
, "w")) == NULL
) {
949 if (mktemp(thePath
) == NULL
) {
950 wsyserror(_("mktemp (%s) failed"), thePath
);
953 theFile
= fopen(thePath
, "wb");
956 thePath
= wstrdup(path
);
957 theFile
= fopen(thePath
, "wb");
960 if (theFile
== NULL
) {
961 wsyserror(_("open (%s) failed"), thePath
);
965 description
= indentedDescription(plist
, 0);
967 if (fprintf(theFile
, "%s\n", description
) != strlen(description
)+1) {
968 wsyserror(_("writing to file: %s failed"), thePath
);
975 if (fclose(theFile
) != 0) {
976 wsyserror(_("fclose (%s) failed"), thePath
);
980 /* If we used a temporary file, we still need to rename() it be the
981 * real file. Also, we need to try to retain the file attributes of
982 * the original file we are overwriting (if we are) */
984 if (rename(thePath
, path
) != 0) {
985 wsyserror(_("rename ('%s' to '%s') failed"), thePath
, path
);
1004 WMShallowCopyPropList(WMPropList
*plist
)
1006 WMPropList
*ret
, *key
, *item
;
1010 switch(plist
->type
) {
1013 return WMDeepCopyPropList(plist
);
1015 ret
= (WMPropList
*)wmalloc(sizeof(W_PropList
));
1016 ret
->type
= WPLArray
;
1017 ret
->d
.array
= WMCreateArrayWithArray(plist
->d
.array
);
1018 ret
->retainCount
= 1;
1020 for(i
=0; i
<WMGetArrayItemCount(ret
->d
.array
); i
++)
1021 WMRetainPropList(WMGetFromArray(ret
->d
.array
, i
));
1025 ret
= WMCreatePropListDictionaryFromEntries(NULL
, NULL
);
1026 e
= WMEnumerateHashTable(plist
->d
.dict
);
1027 while (WMNextHashEnumeratorItemAndKey(&e
, (void**)&item
, (void**)&key
)) {
1028 WMInsertPropListDictionaryEntry(ret
, key
, item
);
1032 wwarning(_("Used proplist functions on non-WMPropLists objects"));
1033 wassertrv(False
, NULL
);
1039 WMDeepCopyPropList(WMPropList
*plist
)
1041 WMPropList
*ret
, *key
, *item
;
1046 switch(plist
->type
) {
1048 return WMCreatePropListString(plist
->d
.string
);
1050 data
= WMCreateDataWithData(plist
->d
.data
);
1051 ret
= WMCreatePropListDataWithData(data
);
1052 WMReleaseData(data
);
1055 ret
= WMCreatePropListArrayFromElements(NULL
);
1056 for(i
=0; i
<WMGetArrayItemCount(plist
->d
.array
); i
++) {
1057 item
= WMDeepCopyPropList(WMGetFromArray(plist
->d
.array
, i
));
1058 WMAddToArray(ret
->d
.array
, item
);
1062 ret
= WMCreatePropListDictionaryFromEntries(NULL
, NULL
);
1063 e
= WMEnumerateHashTable(plist
->d
.dict
);
1064 /* While we copy an existing dictionary there is no way that we can
1065 * have duplicate keys, so we don't need to first remove a key/value
1066 * pair before inserting the new key/value.
1068 while (WMNextHashEnumeratorItemAndKey(&e
, (void**)&item
, (void**)&key
)) {
1069 WMHashInsert(ret
->d
.dict
, WMDeepCopyPropList(key
),
1070 WMDeepCopyPropList(item
));
1074 wwarning(_("Used proplist functions on non-WMPropLists objects"));
1075 wassertrv(False
, NULL
);