18 WPLString
= 0x57504c01,
20 WPLArray
= 0x57504c03,
21 WPLDictionary
= 0x57504c04
25 typedef struct W_PropList
{
41 static unsigned hashPropList(WMPropList
*plist
);
45 typedef unsigned (*hashFunc
)(const void*);
46 typedef Bool (*isEqualFunc
)(const void*, const void*);
47 typedef void* (*retainFunc
)(const void*);
48 typedef void (*releaseFunc
)(const void*);
50 static const WMHashTableCallbacks WMPropListHashCallbacks
= {
51 (hashFunc
)hashPropList
,
52 (isEqualFunc
)WMPLIsEqualToPL
,
59 static Bool caseSensitive
= True
;
63 #define MaxHashLength 64
66 hashPropList(WMPropList
*plist
)
73 switch (plist
->type
) {
75 key
= plist
->d
.string
;
76 len
= WMIN(strlen(key
), MaxHashLength
);
77 for (i
=0; i
<len
; i
++) {
78 ret
^= tolower(key
[i
]) << ctr
;
79 ctr
= (ctr
+ 1) % sizeof (char *);
82 ret ^= tolower(*key++) << ctr;
83 ctr = (ctr + 1) % sizeof (char *);
88 key
= WMDataBytes(plist
->d
.data
);
89 len
= WMIN(WMGetDataLength(plist
->d
.data
), MaxHashLength
);
90 for (i
=0; i
<len
; i
++) {
92 ctr
= (ctr
+ 1) % sizeof (char *);
97 wwarning(_("Only string or data is supported for a proplist dictionary key"));
106 retainPropListByCount(WMPropList
*plist
, int count
)
108 WMPropList
*key
, *value
;
112 plist
->retainCount
+= count
;
114 switch(plist
->type
) {
119 for (i
=0; i
<WMGetArrayItemCount(plist
->d
.array
); i
++) {
120 retainPropListByCount(WMGetFromArray(plist
->d
.array
, i
), count
);
124 e
= WMEnumerateHashTable(plist
->d
.dict
);
125 while (WMNextHashEnumeratorItemAndKey(&e
, (void**)&value
, (void**)&key
)) {
126 retainPropListByCount(key
, count
);
127 retainPropListByCount(value
, count
);
131 wwarning(_("Used proplist functions on non-WMPropLists objects"));
132 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"));
190 #define num2char(num) ((num) < 0xa ? ((num)+'0') : ((num)+0x57))
193 dataDescription(WMPropList
*plist
)
195 const unsigned char *data
;
199 data
= WMDataBytes(plist
->d
.data
);
200 length
= WMGetDataLength(plist
->d
.data
);
202 retVal
= (char*)wmalloc(2*length
+length
/4+3);
205 for (i
=0, j
=1; i
<length
; i
++) {
206 retVal
[j
++] = num2char((data
[i
]>>4) & 0x0f);
207 retVal
[j
++] = num2char(data
[i
] & 0x0f);
208 if ((i
& 0x03)==3 && i
!=length
-1) {
209 /* if we've just finished a 32-bit int, add a space */
221 stringDescription(WMPropList
*plist
)
224 char *retVal
, *sPtr
, *dPtr
;
228 str
= plist
->d
.string
;
230 if (strlen(str
) == 0) {
231 return wstrdup("\"\"");
234 /* FIXME: make this work with unichars. */
236 #define inrange(ch, min, max) ((ch)>=(min) && (ch)<=(max))
237 #define noquote(ch) (inrange(ch, 'a', 'z') || inrange(ch, 'A', 'Z') || inrange(ch, '0', '9') || ((ch)=='_') || ((ch)=='.') || ((ch)=='$'))
238 #define charesc(ch) (inrange(ch, 0x07, 0x0c) || ((ch)=='"') || ((ch)=='\\'))
239 #define numesc(ch) (((ch)<=0x06) || inrange(ch, 0x0d, 0x1f) || ((ch)>0x7e))
244 while ((ch
= *sPtr
)) {
259 retVal
= (char*)wmalloc(len
+1);
267 while ((ch
= *sPtr
)) {
271 case '\a': *dPtr
= 'a'; break;
272 case '\b': *dPtr
= 'b'; break;
273 case '\t': *dPtr
= 't'; break;
274 case '\n': *dPtr
= 'n'; break;
275 case '\v': *dPtr
= 'v'; break;
276 case '\f': *dPtr
= 'f'; break;
277 default: *dPtr
= ch
; /* " or \ */
279 } else if (numesc(ch
)) {
281 *(dPtr
++) = '0' + ((ch
>>6)&07);
282 *(dPtr
++) = '0' + ((ch
>>3)&07);
283 *dPtr
= '0' + (ch
&07);
301 description(WMPropList
*plist
)
303 WMPropList
*key
, *val
;
305 char *str
, *tmp
, *skey
, *sval
;
309 switch (plist
->type
) {
311 retstr
= stringDescription(plist
);
314 retstr
= dataDescription(plist
);
317 retstr
= wstrdup("(");
318 for (i
=0; i
<WMGetArrayItemCount(plist
->d
.array
); i
++) {
319 str
= description(WMGetFromArray(plist
->d
.array
, i
));
321 retstr
= wstrappend(retstr
, str
);
323 tmp
= (char *)wmalloc(strlen(retstr
)+strlen(str
)+3);
324 sprintf(tmp
, "%s, %s", retstr
, str
);
330 retstr
= wstrappend(retstr
, ")");
333 retstr
= wstrdup("{");
334 e
= WMEnumerateHashTable(plist
->d
.dict
);
335 while (WMNextHashEnumeratorItemAndKey(&e
, (void**)&val
, (void**)&key
)) {
336 skey
= description(key
);
337 sval
= description(val
);
338 tmp
= (char*)wmalloc(strlen(retstr
)+strlen(skey
)+strlen(sval
)+5);
339 sprintf(tmp
, "%s%s = %s;", retstr
, skey
, sval
);
345 retstr
= wstrappend(retstr
, "}");
348 wwarning(_("Used proplist functions on non-WMPropLists objects"));
349 wassertrv(False
, NULL
);
358 indentedDescription(WMPropList
*plist
, int level
)
360 WMPropList
*key
, *val
;
362 char *str
, *tmp
, *skey
, *sval
;
366 switch (plist
->type
) {
368 retstr
= stringDescription(plist
);
371 retstr
= dataDescription(plist
);
374 retstr
= wstrdup("(\n");
375 for (i
=0; i
<WMGetArrayItemCount(plist
->d
.array
); i
++) {
376 str
= indentedDescription(WMGetFromArray(plist
->d
.array
, i
),
379 tmp
= (char*)wmalloc(2*(level
+1)+strlen(retstr
)+strlen(str
)+1);
380 sprintf(tmp
, "%s%*s%s", retstr
, 2*(level
+1), "", str
);
384 tmp
= (char*)wmalloc(2*(level
+1)+strlen(retstr
)+strlen(str
)+3);
385 sprintf(tmp
, "%s,\n%*s%s", retstr
, 2*(level
+1), "", str
);
391 tmp
= (char*)wmalloc(strlen(retstr
) + 2*level
+ 3);
392 sprintf(tmp
, "%s\n%*s)", retstr
, 2*level
, "");
397 retstr
= wstrdup("{\n");
398 e
= WMEnumerateHashTable(plist
->d
.dict
);
399 while (WMNextHashEnumeratorItemAndKey(&e
, (void**)&val
, (void**)&key
)) {
400 skey
= indentedDescription(key
, level
+1);
401 sval
= indentedDescription(val
, level
+1);
402 tmp
= (char*)wmalloc(2*(level
+1) + strlen(retstr
) + strlen(skey
)
404 sprintf(tmp
, "%s%*s%s = %s;\n", retstr
, 2*(level
+1), "",
411 tmp
= (char*)wmalloc(strlen(retstr
) + 2*level
+ 2);
412 sprintf(tmp
, "%s%*s}", retstr
, 2*level
, "");
417 wwarning(_("Used proplist functions on non-WMPropLists objects"));
418 wassertrv(False
, NULL
);
427 WMPLSetCaseSensitive(Bool useCase
)
429 caseSensitive
= useCase
;
434 WMPLCreateString(char *str
)
438 wassertrv(str
!=NULL
, NULL
);
440 plist
= (WMPropList
*)wmalloc(sizeof(W_PropList
));
442 plist
->type
= WPLString
;
443 plist
->d
.string
= wstrdup(str
);
444 plist
->retainCount
= 1;
451 WMPLCreateData(WMData
*data
)
455 wassertrv(data
!=NULL
, NULL
);
457 plist
= (WMPropList
*)wmalloc(sizeof(W_PropList
));
459 plist
->type
= WPLData
;
460 plist
->d
.data
= WMRetainData(data
);
461 plist
->retainCount
= 1;
468 WMPLCreateDataWithBytes(unsigned char *bytes
, unsigned int length
)
472 wassertrv(bytes
!=NULL
, NULL
);
474 plist
= (WMPropList
*)wmalloc(sizeof(W_PropList
));
476 plist
->type
= WPLData
;
477 plist
->d
.data
= WMCreateDataWithBytes(bytes
, length
);
478 plist
->retainCount
= 1;
485 WMPLCreateDataWithBytesNoCopy(unsigned char *bytes
, unsigned int length
,
486 WMFreeDataProc
*destructor
)
490 wassertrv(bytes
!=NULL
, NULL
);
492 plist
= (WMPropList
*)wmalloc(sizeof(W_PropList
));
494 plist
->type
= WPLData
;
495 plist
->d
.data
= WMCreateDataWithBytesNoCopy(bytes
, length
, destructor
);
496 plist
->retainCount
= 1;
503 WMPLCreateArray(WMPropList
*elem
, ...)
505 WMPropList
*plist
, *nelem
;
508 plist
= (WMPropList
*)wmalloc(sizeof(W_PropList
));
509 plist
->type
= WPLArray
;
510 plist
->d
.array
= WMCreateArray(4);
511 plist
->retainCount
= 1;
516 WMAddToArray(plist
->d
.array
, WMPLRetain(elem
));
521 nelem
= va_arg(ap
, WMPropList
*);
526 WMAddToArray(plist
->d
.array
, WMPLRetain(nelem
));
532 WMPLCreateDictionary(WMPropList
*key
, WMPropList
*value
, ...)
534 WMPropList
*plist
, *nkey
, *nvalue
, *k
, *v
;
537 plist
= (WMPropList
*)wmalloc(sizeof(W_PropList
));
538 plist
->type
= WPLDictionary
;
539 plist
->d
.dict
= WMCreateHashTable(WMPropListHashCallbacks
);
540 plist
->retainCount
= 1;
545 WMHashInsert(plist
->d
.dict
, WMPLRetain(key
), WMPLRetain(value
));
550 nkey
= va_arg(ap
, WMPropList
*);
555 nvalue
= va_arg(ap
, WMPropList
*);
560 if (WMHashGetItemAndKey(plist
->d
.dict
, nkey
, (void**)&v
, (void**)&k
)) {
561 WMHashRemove(plist
->d
.dict
, k
);
565 WMHashInsert(plist
->d
.dict
, WMPLRetain(nkey
), WMPLRetain(nvalue
));
571 WMPLInsertInArray(WMPropList
*plist
, int index
, WMPropList
*item
)
573 wassertr(plist
->type
==WPLArray
);
575 retainPropListByCount(item
, plist
->retainCount
);
576 WMInsertInArray(plist
->d
.array
, index
, item
);
581 WMPLAddToArray(WMPropList
*plist
, WMPropList
*item
)
583 wassertr(plist
->type
==WPLArray
);
585 retainPropListByCount(item
, plist
->retainCount
);
586 WMAddToArray(plist
->d
.array
, item
);
591 WMPLDeleteFromArray(WMPropList
*plist
, int index
)
595 wassertr(plist
->type
==WPLArray
);
597 item
= WMGetFromArray(plist
->d
.array
, index
);
599 WMDeleteFromArray(plist
->d
.array
, index
);
600 releasePropListByCount(item
, plist
->retainCount
);
606 WMPLRemoveFromArray(WMPropList
*plist
, WMPropList
*item
)
611 wassertr(plist
->type
==WPLArray
);
613 for (i
=0; i
<WMGetArrayItemCount(plist
->d
.array
); i
++) {
614 iPtr
= WMGetFromArray(plist
->d
.array
, i
);
615 if (WMPLIsEqualToPL(item
, iPtr
)) {
616 WMDeleteFromArray(plist
->d
.array
, i
);
617 releasePropListByCount(iPtr
, plist
->retainCount
);
625 WMPLPutInDictionary(WMPropList
*plist
, WMPropList
*key
, WMPropList
*value
)
627 wassertr(plist
->type
==WPLDictionary
);
629 WMPLRemoveFromDictionary(plist
, key
);
630 retainPropListByCount(key
, plist
->retainCount
);
631 retainPropListByCount(value
, plist
->retainCount
);
632 WMHashInsert(plist
->d
.dict
, key
, value
);
637 WMPLRemoveFromDictionary(WMPropList
*plist
, WMPropList
*key
)
641 wassertr(plist
->type
==WPLDictionary
);
643 if (WMHashGetItemAndKey(plist
->d
.dict
, key
, (void**)&v
, (void**)&k
)) {
644 WMHashRemove(plist
->d
.dict
, k
);
645 releasePropListByCount(k
, plist
->retainCount
);
646 releasePropListByCount(v
, plist
->retainCount
);
652 WMPLMergeDictionaries(WMPropList
*dest
, WMPropList
*source
)
654 WMPropList
*key
, *value
;
657 wassertr(source
->type
==WPLDictionary
&& dest
->type
==WPLDictionary
);
659 e
= WMEnumerateHashTable(source
->d
.dict
);
660 while (WMNextHashEnumeratorItemAndKey(&e
, (void**)&value
, (void**)&key
)) {
661 WMPLPutInDictionary(dest
, key
, value
);
669 WMPLRetain(WMPropList
*plist
)
671 WMPropList
*key
, *value
;
675 plist
->retainCount
++;
677 switch(plist
->type
) {
682 for (i
=0; i
<WMGetArrayItemCount(plist
->d
.array
); i
++) {
683 WMPLRetain(WMGetFromArray(plist
->d
.array
, i
));
687 e
= WMEnumerateHashTable(plist
->d
.dict
);
688 while (WMNextHashEnumeratorItemAndKey(&e
, (void**)&value
, (void**)&key
)) {
694 wwarning(_("Used proplist functions on non-WMPropLists objects"));
695 wassertrv(False
, NULL
);
704 WMPLRelease(WMPropList
*plist
)
706 WMPropList
*key
, *value
;
710 plist
->retainCount
--;
712 switch(plist
->type
) {
714 if (plist
->retainCount
< 1) {
715 wfree(plist
->d
.string
);
720 if (plist
->retainCount
< 1) {
721 WMReleaseData(plist
->d
.data
);
726 for (i
=0; i
<WMGetArrayItemCount(plist
->d
.array
); i
++) {
727 WMPLRelease(WMGetFromArray(plist
->d
.array
, i
));
729 if (plist
->retainCount
< 1) {
730 WMFreeArray(plist
->d
.array
);
735 e
= WMEnumerateHashTable(plist
->d
.dict
);
736 while (WMNextHashEnumeratorItemAndKey(&e
, (void**)&value
, (void**)&key
)) {
740 if (plist
->retainCount
< 1) {
741 WMFreeHashTable(plist
->d
.dict
);
746 wwarning(_("Used proplist functions on non-WMPropLists objects"));
754 WMPLIsString(WMPropList
*plist
)
756 return (plist
->type
== WPLString
);
761 WMPLIsData(WMPropList
*plist
)
763 return (plist
->type
== WPLData
);
768 WMPLIsArray(WMPropList
*plist
)
770 return (plist
->type
== WPLArray
);
775 WMPLIsDictionary(WMPropList
*plist
)
777 return (plist
->type
== WPLDictionary
);
782 WMPLIsEqualToPL(WMPropList
*plist
, WMPropList
*other
)
784 WMPropList
*key1
, *item1
, *item2
;
785 WMHashEnumerator enumerator
;
788 if (plist
->type
!= other
->type
)
791 switch(plist
->type
) {
794 return (strcmp(plist
->d
.string
, other
->d
.string
) == 0);
796 return (strcasecmp(plist
->d
.string
, other
->d
.string
) == 0);
799 return WMIsDataEqualToData(plist
->d
.data
, other
->d
.data
);
801 n
= WMGetArrayItemCount(plist
->d
.array
);
802 if (n
!= WMGetArrayItemCount(other
->d
.array
))
804 for (i
=0; i
<n
; i
++) {
805 item1
= WMGetFromArray(plist
->d
.array
, i
);
806 item2
= WMGetFromArray(other
->d
.array
, i
);
807 if (!WMPLIsEqualToPL(item1
, item2
))
812 if (WMCountHashTable(plist
->d
.dict
) != WMCountHashTable(other
->d
.dict
))
814 enumerator
= WMEnumerateHashTable(plist
->d
.dict
);
815 while (WMNextHashEnumeratorItemAndKey(&enumerator
, (void**)&item1
,
817 item2
= WMHashGet(other
->d
.dict
, key1
);
818 if (!item2
|| !item1
|| !WMPLIsEqualToPL(item1
, item2
))
823 wwarning(_("Used proplist functions on non-WMPropLists objects"));
824 wassertrv(False
, False
);
833 WMPLGetItemCount(WMPropList
*plist
)
835 switch(plist
->type
) {
838 return 0; /* should this be 1 instead? */
840 return WMGetArrayItemCount(plist
->d
.array
);
842 return (int)WMCountHashTable(plist
->d
.dict
);
844 wwarning(_("Used proplist functions on non-WMPropLists objects"));
854 WMPLGetString(WMPropList
*plist
)
856 wassertrv(plist
->type
==WPLString
, NULL
);
858 return plist
->d
.string
;
863 WMPLGetData(WMPropList
*plist
)
865 wassertrv(plist
->type
==WPLData
, NULL
);
867 return plist
->d
.data
;
872 WMPLGetDataBytes(WMPropList
*plist
)
874 wassertrv(plist
->type
==WPLData
, NULL
);
876 return WMDataBytes(plist
->d
.data
);
881 WMPLGetDataLength(WMPropList
*plist
)
883 wassertrv(plist
->type
==WPLData
, 0);
885 return WMGetDataLength(plist
->d
.data
);
890 WMPLGetFromArray(WMPropList
*plist
, int index
)
892 wassertrv(plist
->type
==WPLArray
, NULL
);
894 return WMGetFromArray(plist
->d
.array
, index
);
899 WMPLGetFromDictionary(WMPropList
*plist
, WMPropList
*key
)
901 wassertrv(plist
->type
==WPLDictionary
, NULL
);
903 return WMHashGet(plist
->d
.dict
, key
);
908 WMPLGetDictionaryKeys(WMPropList
*plist
)
910 WMPropList
*array
, *key
;
911 WMHashEnumerator enumerator
;
913 wassertrv(plist
->type
==WPLDictionary
, NULL
);
915 array
= (WMPropList
*)wmalloc(sizeof(W_PropList
));
916 array
->type
= WPLArray
;
917 array
->d
.array
= WMCreateArray(WMCountHashTable(plist
->d
.dict
));
918 array
->retainCount
= 1;
920 enumerator
= WMEnumerateHashTable(plist
->d
.dict
);
921 while ((key
= WMNextHashEnumeratorKey(&enumerator
))) {
922 WMAddToArray(array
->d
.array
, WMPLRetain(key
));
930 WMPLGetDescription(WMPropList
*plist
, Bool indented
)
932 return (indented
? indentedDescription(plist
, 0) : description(plist
));
937 /* TODO: review this function's code */
940 WMPLWriteToFile(WMPropList
*plist
, char *path
, Bool atomically
)
951 /* Use the path name of the destination file as a prefix for the
952 * mkstemp() call so that we can be sure that both files are on
953 * the same filesystem and the subsequent rename() will work. */
954 thePath
= wstrconcat(path
, ".XXXXXX");
957 if ((fd
= mkstemp(thePath
)) < 0) {
958 wsyserror(_("mkstemp (%s) failed"), thePath
);
963 fchmod(fd
, 0644 & ~mask
);
964 if ((theFile
= fdopen(fd
, "w")) == NULL
) {
968 if (mktemp(thePath
) == NULL
) {
969 wsyserror(_("mktemp (%s) failed"), thePath
);
972 theFile
= fopen(thePath
, "wb");
975 thePath
= wstrdup(path
);
976 theFile
= fopen(thePath
, "wb");
979 if (theFile
== NULL
) {
980 wsyserror(_("open (%s) failed"), thePath
);
984 description
= indentedDescription(plist
, 0);
986 if (fprintf(theFile
, "%s\n", description
) != strlen(description
)+1) {
987 wsyserror(_("writing to file: %s failed"), thePath
);
994 if (fclose(theFile
) != 0) {
995 wsyserror(_("fclose (%s) failed"), thePath
);
999 /* If we used a temporary file, we still need to rename() it be the
1000 * real file. Also, we need to try to retain the file attributes of
1001 * the original file we are overwriting (if we are) */
1003 if (rename(thePath
, path
) != 0) {
1004 wsyserror(_("rename ('%s' to '%s') failed"), thePath
, path
);
1023 WMPLShallowCopy(WMPropList
*plist
)
1025 WMPropList
*ret
= NULL
;
1026 WMPropList
*key
, *item
;
1031 switch(plist
->type
) {
1033 ret
= WMPLCreateString(plist
->d
.string
);
1036 data
= WMCreateDataWithData(plist
->d
.data
);
1037 ret
= WMPLCreateData(data
);
1038 WMReleaseData(data
);
1041 ret
= (WMPropList
*)wmalloc(sizeof(W_PropList
));
1042 ret
->type
= WPLArray
;
1043 ret
->d
.array
= WMCreateArrayWithArray(plist
->d
.array
);
1044 ret
->retainCount
= 1;
1046 for(i
=0; i
<WMGetArrayItemCount(ret
->d
.array
); i
++)
1047 WMPLRetain(WMGetFromArray(ret
->d
.array
, i
));
1051 ret
= WMPLCreateDictionary(NULL
, NULL
);
1052 e
= WMEnumerateHashTable(plist
->d
.dict
);
1053 while (WMNextHashEnumeratorItemAndKey(&e
, (void**)&item
, (void**)&key
)) {
1054 WMPLPutInDictionary(ret
, key
, item
);
1058 wwarning(_("Used proplist functions on non-WMPropLists objects"));
1059 wassertrv(False
, NULL
);
1068 WMPLDuplicate(WMPropList
*plist
)
1070 WMPropList
*ret
= NULL
;
1071 WMPropList
*key
, *item
;
1076 switch(plist
->type
) {
1078 ret
= WMPLCreateString(plist
->d
.string
);
1081 data
= WMCreateDataWithData(plist
->d
.data
);
1082 ret
= WMPLCreateData(data
);
1083 WMReleaseData(data
);
1086 ret
= WMPLCreateArray(NULL
);
1087 for(i
=0; i
<WMGetArrayItemCount(plist
->d
.array
); i
++) {
1088 item
= WMPLDuplicate(WMGetFromArray(plist
->d
.array
, i
));
1089 WMAddToArray(ret
->d
.array
, item
);
1093 ret
= WMPLCreateDictionary(NULL
, NULL
);
1094 e
= WMEnumerateHashTable(plist
->d
.dict
);
1095 /* While we copy an existing dictionary there is no way that we can
1096 * have duplicate keys, so we don't need to first remove a key/value
1097 * pair before inserting the new key/value.
1099 while (WMNextHashEnumeratorItemAndKey(&e
, (void**)&item
, (void**)&key
)) {
1100 WMHashInsert(ret
->d
.dict
, WMPLDuplicate(key
), WMPLDuplicate(item
));
1104 wwarning(_("Used proplist functions on non-WMPropLists objects"));
1105 wassertrv(False
, NULL
);