mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-20 21:08:08 +01:00
more code for proplist handling (almost finished)
This commit is contained in:
@@ -336,6 +336,17 @@ unsigned WMCountHashTable(WMHashTable *table);
|
|||||||
|
|
||||||
void* WMHashGet(WMHashTable *table, const void *key);
|
void* WMHashGet(WMHashTable *table, const void *key);
|
||||||
|
|
||||||
|
/* Returns True if there is a value associated with <key> in the table, in
|
||||||
|
* which case <retKey> and <retItem> will contain the item's internal key
|
||||||
|
* address and the item's value respectively.
|
||||||
|
* If there is no value associated with <key> it will return False and in
|
||||||
|
* this case <retKey> and <retItem> will be undefined.
|
||||||
|
* Use this when you need to perform your own custom retain/release mechanism
|
||||||
|
* which requires access to the keys too.
|
||||||
|
*/
|
||||||
|
Bool WMHashGetItemAndKey(WMHashTable *table, const void *key,
|
||||||
|
void **retItem, void **retKey);
|
||||||
|
|
||||||
/* put data in table, replacing already existing data and returning
|
/* put data in table, replacing already existing data and returning
|
||||||
* the old value */
|
* the old value */
|
||||||
void* WMHashInsert(WMHashTable *table, const void *key, const void *data);
|
void* WMHashInsert(WMHashTable *table, const void *key, const void *data);
|
||||||
@@ -680,17 +691,6 @@ WMTreeNode* WMFindInTree(WMTreeNode *aTree, WMMatchDataProc *match, void *cdata)
|
|||||||
#define WMGetFirstInTree(aTree, cdata) WMFindInTree(atree, NULL, cdata)
|
#define WMGetFirstInTree(aTree, cdata) WMFindInTree(atree, NULL, cdata)
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Dictionaries */
|
|
||||||
/*
|
|
||||||
WMDictionary* WMCreateDictionaryFromElements(void *key, void *value, ...);
|
|
||||||
|
|
||||||
#define WMGetDictionaryEntryForKey(dict, key) WMHashGet(dict, key)
|
|
||||||
|
|
||||||
WMArray* WMGetAllDictionaryKeys(WMDictionary *dPtr);
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
@@ -758,6 +758,19 @@ WMPropList* WMCreatePropListArrayFromElements(WMPropList *elem, ...);
|
|||||||
WMPropList* WMCreatePropListDictionaryFromEntries(WMPropList *key,
|
WMPropList* WMCreatePropListDictionaryFromEntries(WMPropList *key,
|
||||||
WMPropList *value, ...);
|
WMPropList *value, ...);
|
||||||
|
|
||||||
|
void WMInsertPropListArrayElement(WMPropList *plist, WMPropList *item, int index);
|
||||||
|
|
||||||
|
void WMAppendPropListArrayElement(WMPropList *plist, WMPropList *item);
|
||||||
|
|
||||||
|
void WMRemovePropListArrayElement(WMPropList *plist, int index);
|
||||||
|
|
||||||
|
void WMInsertPropListDictionaryEntry(WMPropList *plist, WMPropList *key,
|
||||||
|
WMPropList *value);
|
||||||
|
|
||||||
|
void WMRemovePropListDictionaryEntry(WMPropList *plist, WMPropList *key);
|
||||||
|
|
||||||
|
WMPropList* WMMergePropListDictionaries(WMPropList *dest, WMPropList *source);
|
||||||
|
|
||||||
WMPropList* WMRetainPropList(WMPropList *plist);
|
WMPropList* WMRetainPropList(WMPropList *plist);
|
||||||
|
|
||||||
void WMReleasePropList(WMPropList *plist);
|
void WMReleasePropList(WMPropList *plist);
|
||||||
@@ -774,8 +787,31 @@ Bool WMPropListIsSimple(WMPropList *plist);
|
|||||||
|
|
||||||
Bool WMPropListIsCompound(WMPropList *plist);
|
Bool WMPropListIsCompound(WMPropList *plist);
|
||||||
|
|
||||||
Bool WMArePropListsEqual(WMPropList *plist, WMPropList *other);
|
Bool WMIsPropListEqualToPropList(WMPropList *plist, WMPropList *other);
|
||||||
|
|
||||||
|
int WMGetPropListNumberOfElements(WMPropList *plist);
|
||||||
|
|
||||||
|
char* WMGetPropListString(WMPropList *plist);
|
||||||
|
|
||||||
|
WMData* WMGetPropListData(WMPropList *plist);
|
||||||
|
|
||||||
|
const unsigned char* WMGetPropListDataBytes(WMPropList *plist);
|
||||||
|
|
||||||
|
int WMGetPropListDataLength(WMPropList *plist);
|
||||||
|
|
||||||
|
WMPropList* WMGetPropListArrayElement(WMPropList *plist, int index);
|
||||||
|
|
||||||
|
WMPropList* WMGetPropListDictionaryEntry(WMPropList *plist, WMPropList *key);
|
||||||
|
|
||||||
|
WMPropList* WMGetPropListAllDictionaryKeys(WMPropList *plist);
|
||||||
|
|
||||||
|
char* WMGetPropListDescription(WMPropList *plist, Bool indented);
|
||||||
|
|
||||||
|
Bool WMSavePropListToFile(WMPropList *plist, char *path, Bool atomically);
|
||||||
|
|
||||||
|
WMPropList* WMShallowCopyPropList(WMPropList *plist);
|
||||||
|
|
||||||
|
WMPropList* WMDeepCopyPropList(WMPropList *plist);
|
||||||
|
|
||||||
/*......................................................................*/
|
/*......................................................................*/
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ wmessage(const char *msg, ...)
|
|||||||
vsnprintf(buf, MAXLINE-3, msg, args);
|
vsnprintf(buf, MAXLINE-3, msg, args);
|
||||||
strcat(buf,"\n");
|
strcat(buf,"\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
fputs(_WINGS_progname, stderr);
|
fputs(_WINGS_progname ? _WINGS_progname : "WINGs", stderr);
|
||||||
fputs(": ",stderr);
|
fputs(": ",stderr);
|
||||||
fputs(buf, stderr);
|
fputs(buf, stderr);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
@@ -108,7 +108,7 @@ wwarning(const char *msg, ...)
|
|||||||
vsnprintf(buf, MAXLINE-3, msg, args);
|
vsnprintf(buf, MAXLINE-3, msg, args);
|
||||||
strcat(buf,"\n");
|
strcat(buf,"\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
fputs(_WINGS_progname, stderr);
|
fputs(_WINGS_progname ? _WINGS_progname : "WINGs", stderr);
|
||||||
fputs(_(" warning: "),stderr);
|
fputs(_(" warning: "),stderr);
|
||||||
fputs(buf, stderr);
|
fputs(buf, stderr);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
@@ -135,7 +135,7 @@ wfatal(const char *msg, ...)
|
|||||||
vsnprintf(buf, MAXLINE-3, msg, args);
|
vsnprintf(buf, MAXLINE-3, msg, args);
|
||||||
strcat(buf,"\n");
|
strcat(buf,"\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
fputs(_WINGS_progname, stderr);
|
fputs(_WINGS_progname ? _WINGS_progname : "WINGs", stderr);
|
||||||
fputs(_(" fatal error: "),stderr);
|
fputs(_(" fatal error: "),stderr);
|
||||||
fputs(buf, stderr);
|
fputs(buf, stderr);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
@@ -161,7 +161,7 @@ wsyserror(const char *msg, ...)
|
|||||||
va_start(args, msg);
|
va_start(args, msg);
|
||||||
vsnprintf(buf, MAXLINE-3, msg, args);
|
vsnprintf(buf, MAXLINE-3, msg, args);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
fputs(_WINGS_progname, stderr);
|
fputs(_WINGS_progname ? _WINGS_progname : "WINGs", stderr);
|
||||||
fputs(_(" error: "), stderr);
|
fputs(_(" error: "), stderr);
|
||||||
fputs(buf, stderr);
|
fputs(buf, stderr);
|
||||||
fputs(": ", stderr);
|
fputs(": ", stderr);
|
||||||
@@ -190,7 +190,7 @@ wsyserrorwithcode(int error, const char *msg, ...)
|
|||||||
va_start(args, msg);
|
va_start(args, msg);
|
||||||
vsnprintf(buf, MAXLINE-3, msg, args);
|
vsnprintf(buf, MAXLINE-3, msg, args);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
fputs(_WINGS_progname, stderr);
|
fputs(_WINGS_progname ? _WINGS_progname : "WINGs", stderr);
|
||||||
fputs(_(" error: "), stderr);
|
fputs(_(" error: "), stderr);
|
||||||
fputs(buf, stderr);
|
fputs(buf, stderr);
|
||||||
fputs(": ", stderr);
|
fputs(": ", stderr);
|
||||||
|
|||||||
@@ -223,6 +223,43 @@ WMHashGet(WMHashTable *table, const void *key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Bool
|
||||||
|
WMHashGetItemAndKey(WMHashTable *table, const void *key,
|
||||||
|
void **retItem, void **retKey)
|
||||||
|
{
|
||||||
|
unsigned h;
|
||||||
|
HashItem *item;
|
||||||
|
|
||||||
|
h = HASH(table, key);
|
||||||
|
item = table->table[h];
|
||||||
|
|
||||||
|
if (table->callbacks.keyIsEqual) {
|
||||||
|
while (item) {
|
||||||
|
if ((*table->callbacks.keyIsEqual)(key, item->key)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
item = item->next;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (item) {
|
||||||
|
if (key == item->key) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
item = item->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (item) {
|
||||||
|
if (retKey)
|
||||||
|
*retKey = (void*)item->key;
|
||||||
|
if (retItem)
|
||||||
|
*retItem = (void*)item->data;
|
||||||
|
return True;
|
||||||
|
} else {
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void*
|
void*
|
||||||
WMHashInsert(WMHashTable *table, const void *key, const void *data)
|
WMHashInsert(WMHashTable *table, const void *key, const void *data)
|
||||||
@@ -414,8 +451,10 @@ WMNextHashEnumeratorItemAndKey(WMHashEnumerator *enumerator,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (enumerator->nextItem) {
|
if (enumerator->nextItem) {
|
||||||
*item = (void*)((HashItem*)enumerator->nextItem)->data;
|
if (item)
|
||||||
*key = (void*)((HashItem*)enumerator->nextItem)->key;
|
*item = (void*)((HashItem*)enumerator->nextItem)->data;
|
||||||
|
if (key)
|
||||||
|
*key = (void*)((HashItem*)enumerator->nextItem)->key;
|
||||||
enumerator->nextItem = ((HashItem*)enumerator->nextItem)->next;
|
enumerator->nextItem = ((HashItem*)enumerator->nextItem)->next;
|
||||||
|
|
||||||
return True;
|
return True;
|
||||||
|
|||||||
789
WINGs/proplist.c
789
WINGs/proplist.c
@@ -2,6 +2,12 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "WUtil.h"
|
#include "WUtil.h"
|
||||||
#include "wconfig.h"
|
#include "wconfig.h"
|
||||||
@@ -31,12 +37,10 @@ typedef struct W_PropList {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned hashPropList(WMPropList *plist);
|
static unsigned hashPropList(WMPropList *plist);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef unsigned (*hashFunc)(const void*);
|
typedef unsigned (*hashFunc)(const void*);
|
||||||
typedef Bool (*isEqualFunc)(const void*, const void*);
|
typedef Bool (*isEqualFunc)(const void*, const void*);
|
||||||
typedef void* (*retainFunc)(const void*);
|
typedef void* (*retainFunc)(const void*);
|
||||||
@@ -44,14 +48,17 @@ typedef void (*releaseFunc)(const void*);
|
|||||||
|
|
||||||
static const WMHashTableCallbacks WMPropListHashCallbacks = {
|
static const WMHashTableCallbacks WMPropListHashCallbacks = {
|
||||||
(hashFunc)hashPropList,
|
(hashFunc)hashPropList,
|
||||||
(isEqualFunc)WMArePropListsEqual,
|
(isEqualFunc)WMIsPropListEqualToPropList,
|
||||||
(retainFunc)NULL,
|
(retainFunc)NULL,
|
||||||
(releaseFunc)NULL
|
(releaseFunc)NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static WMCompareDataProc *strCmp = (WMCompareDataProc*) strcmp;
|
static WMCompareDataProc *strCmp = (WMCompareDataProc*) strcmp;
|
||||||
|
|
||||||
|
|
||||||
|
#define MaxHashLength 64
|
||||||
|
|
||||||
|
|
||||||
static unsigned
|
static unsigned
|
||||||
hashPropList(WMPropList *plist)
|
hashPropList(WMPropList *plist)
|
||||||
@@ -59,32 +66,353 @@ hashPropList(WMPropList *plist)
|
|||||||
unsigned ret = 0;
|
unsigned ret = 0;
|
||||||
unsigned ctr = 0;
|
unsigned ctr = 0;
|
||||||
const char *key;
|
const char *key;
|
||||||
int i;
|
int i, len;
|
||||||
|
|
||||||
switch (plist->type) {
|
switch (plist->type) {
|
||||||
case WPLString:
|
case WPLString:
|
||||||
key = plist->d.string;
|
key = plist->d.string;
|
||||||
while (*key) {
|
len = WMIN(strlen(key), MaxHashLength);
|
||||||
ret ^= *key++ << ctr;
|
for (i=0; i<len; i++) {
|
||||||
|
ret ^= tolower(key[i]) << ctr;
|
||||||
ctr = (ctr + 1) % sizeof (char *);
|
ctr = (ctr + 1) % sizeof (char *);
|
||||||
}
|
}
|
||||||
|
/*while (*key) {
|
||||||
|
ret ^= tolower(*key++) << ctr;
|
||||||
|
ctr = (ctr + 1) % sizeof (char *);
|
||||||
|
}*/
|
||||||
return ret;
|
return ret;
|
||||||
|
/*return strlen(plist->d.string);*/
|
||||||
|
|
||||||
case WPLData:
|
case WPLData:
|
||||||
key = WMDataBytes(plist->d.data);
|
key = WMDataBytes(plist->d.data);
|
||||||
for (i=0; i<WMGetDataLength(plist->d.data); i++) {
|
len = WMIN(WMGetDataLength(plist->d.data), MaxHashLength);
|
||||||
|
for (i=0; i<len; i++) {
|
||||||
ret ^= key[i] << ctr;
|
ret ^= key[i] << ctr;
|
||||||
ctr = (ctr + 1) % sizeof (char *);
|
ctr = (ctr + 1) % sizeof (char *);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
/*return WMGetDataLength(plist->d.data);*/
|
||||||
|
|
||||||
default:
|
default:
|
||||||
wwarning(_("Only string or data is supported for a proplist dictionary key"));
|
wwarning(_("Only string or data is supported for a proplist dictionary key"));
|
||||||
wassertrv(False, 0);
|
wassertrv(False, 0);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*WMSetPropListStringComparisonCaseSensitive
|
||||||
|
WMSetPropListStringComparerIsCaseSensitive
|
||||||
|
WMSetPLStringComparisonCaseSensitive*/
|
||||||
|
|
||||||
|
static WMPropList*
|
||||||
|
retainPropListByCount(WMPropList *plist, int count)
|
||||||
|
{
|
||||||
|
WMPropList *key, *value;
|
||||||
|
WMHashEnumerator e;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
plist->retainCount += count;
|
||||||
|
|
||||||
|
switch(plist->type) {
|
||||||
|
case WPLString:
|
||||||
|
case WPLData:
|
||||||
|
break;
|
||||||
|
case WPLArray:
|
||||||
|
for (i=0; i<WMGetArrayItemCount(plist->d.array); i++) {
|
||||||
|
retainPropListByCount(WMGetFromArray(plist->d.array, i), count);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WPLDictionary:
|
||||||
|
e = WMEnumerateHashTable(plist->d.dict);
|
||||||
|
while (WMNextHashEnumeratorItemAndKey(&e, (void**)&value, (void**)&key)) {
|
||||||
|
retainPropListByCount(key, count);
|
||||||
|
retainPropListByCount(value, count);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
wwarning(_("Used proplist functions on non-WMPropLists objects"));
|
||||||
|
wassertrv(False, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return plist;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
releasePropListByCount(WMPropList *plist, int count)
|
||||||
|
{
|
||||||
|
WMPropList *key, *value;
|
||||||
|
WMHashEnumerator e;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
plist->retainCount -= count;
|
||||||
|
|
||||||
|
switch(plist->type) {
|
||||||
|
case WPLString:
|
||||||
|
if (plist->retainCount < 1) {
|
||||||
|
wfree(plist->d.string);
|
||||||
|
wfree(plist);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WPLData:
|
||||||
|
if (plist->retainCount < 1) {
|
||||||
|
WMReleaseData(plist->d.data);
|
||||||
|
wfree(plist);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WPLArray:
|
||||||
|
for (i=0; i<WMGetArrayItemCount(plist->d.array); i++) {
|
||||||
|
releasePropListByCount(WMGetFromArray(plist->d.array, i), count);
|
||||||
|
}
|
||||||
|
if (plist->retainCount < 1) {
|
||||||
|
WMFreeArray(plist->d.array);
|
||||||
|
wfree(plist);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WPLDictionary:
|
||||||
|
e = WMEnumerateHashTable(plist->d.dict);
|
||||||
|
while (WMNextHashEnumeratorItemAndKey(&e, (void**)&value, (void**)&key)) {
|
||||||
|
releasePropListByCount(key, count);
|
||||||
|
releasePropListByCount(value, count);
|
||||||
|
}
|
||||||
|
if (plist->retainCount < 1) {
|
||||||
|
WMFreeHashTable(plist->d.dict);
|
||||||
|
wfree(plist);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
wwarning(_("Used proplist functions on non-WMPropLists objects"));
|
||||||
|
wassertr(False);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define num2char(num) ((num) < 0xa ? ((num)+'0') : ((num)+0x57))
|
||||||
|
|
||||||
|
static char*
|
||||||
|
dataDescription(WMPropList *plist)
|
||||||
|
{
|
||||||
|
const unsigned char *data;
|
||||||
|
char *retVal;
|
||||||
|
int i, j, length;
|
||||||
|
|
||||||
|
data = WMDataBytes(plist->d.data);
|
||||||
|
length = WMGetDataLength(plist->d.data);
|
||||||
|
|
||||||
|
retVal = (char*)wmalloc(2*length+length/4+3);
|
||||||
|
|
||||||
|
retVal[0] = '<';
|
||||||
|
for (i=0, j=1; i<length; i++) {
|
||||||
|
retVal[j++] = num2char((data[i]>>4) & 0x0f);
|
||||||
|
retVal[j++] = num2char(data[i] & 0x0f);
|
||||||
|
if ((i & 0x03)==3 && i!=length-1) {
|
||||||
|
/* if we've just finished a 32-bit int, add a space */
|
||||||
|
retVal[j++] = ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
retVal[j++] = '>';
|
||||||
|
retVal[j] = '\0';
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char*
|
||||||
|
stringDescription(WMPropList *plist)
|
||||||
|
{
|
||||||
|
const char *str;
|
||||||
|
char *retVal, *sPtr, *dPtr;
|
||||||
|
int len, quote;
|
||||||
|
unsigned char ch;
|
||||||
|
|
||||||
|
str = plist->d.string;
|
||||||
|
|
||||||
|
if (strlen(str) == 0) {
|
||||||
|
return wstrdup("\"\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: make this work with unichars. */
|
||||||
|
|
||||||
|
#define inrange(ch, min, max) ((ch)>=(min) && (ch)<=(max))
|
||||||
|
#define noquote(ch) (inrange(ch, 'a', 'z') || inrange(ch, 'A', 'Z') || inrange(ch, '0', '9') || ((ch)=='_') || ((ch)=='.') || ((ch)=='$'))
|
||||||
|
#define charesc(ch) (inrange(ch, 0x07, 0x0c) || ((ch)=='"') || ((ch)=='\\'))
|
||||||
|
#define numesc(ch) (((ch)<=0x06) || inrange(ch, 0x0d, 0x1f) || ((ch)>0x7e))
|
||||||
|
|
||||||
|
quote = 0;
|
||||||
|
sPtr = (char*) str;
|
||||||
|
len = 0;
|
||||||
|
while ((ch = *sPtr)) {
|
||||||
|
if (!noquote(ch)) {
|
||||||
|
quote = 1;
|
||||||
|
if (charesc(ch))
|
||||||
|
len++;
|
||||||
|
else if (numesc(ch))
|
||||||
|
len += 3;
|
||||||
|
}
|
||||||
|
sPtr++;
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (quote)
|
||||||
|
len += 2;
|
||||||
|
|
||||||
|
retVal = (char*)wmalloc(len+1);
|
||||||
|
|
||||||
|
sPtr = (char*) str;
|
||||||
|
dPtr = retVal;
|
||||||
|
|
||||||
|
if (quote)
|
||||||
|
*dPtr++ = '"';
|
||||||
|
|
||||||
|
while ((ch = *sPtr)) {
|
||||||
|
if (charesc(ch)) {
|
||||||
|
*(dPtr++) = '\\';
|
||||||
|
switch (ch) {
|
||||||
|
case '\a': *dPtr = 'a'; break;
|
||||||
|
case '\b': *dPtr = 'b'; break;
|
||||||
|
case '\t': *dPtr = 't'; break;
|
||||||
|
case '\n': *dPtr = 'n'; break;
|
||||||
|
case '\v': *dPtr = 'v'; break;
|
||||||
|
case '\f': *dPtr = 'f'; break;
|
||||||
|
default: *dPtr = ch; /* " or \ */
|
||||||
|
}
|
||||||
|
} else if (numesc(ch)) {
|
||||||
|
*(dPtr++) = '\\';
|
||||||
|
*(dPtr++) = '0' + ((ch>>6)&07);
|
||||||
|
*(dPtr++) = '0' + ((ch>>3)&07);
|
||||||
|
*dPtr = '0' + (ch&07);
|
||||||
|
} else {
|
||||||
|
*dPtr = ch;
|
||||||
|
}
|
||||||
|
sPtr++;
|
||||||
|
dPtr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (quote)
|
||||||
|
*dPtr++ = '"';
|
||||||
|
|
||||||
|
*dPtr = '\0';
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char*
|
||||||
|
description(WMPropList *plist)
|
||||||
|
{
|
||||||
|
WMPropList *key, *val;
|
||||||
|
char *retstr, *str, *tmp, *skey, *sval;
|
||||||
|
WMHashEnumerator e;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
switch (plist->type) {
|
||||||
|
case WPLString:
|
||||||
|
return stringDescription(plist);
|
||||||
|
case WPLData:
|
||||||
|
return dataDescription(plist);
|
||||||
|
case WPLArray:
|
||||||
|
retstr = wstrdup("(");
|
||||||
|
for (i=0; i<WMGetArrayItemCount(plist->d.array); i++) {
|
||||||
|
str = description(WMGetFromArray(plist->d.array, i));
|
||||||
|
if (i==0) {
|
||||||
|
retstr = wstrappend(retstr, str);
|
||||||
|
} else {
|
||||||
|
tmp = (char *)wmalloc(strlen(retstr)+strlen(str)+3);
|
||||||
|
sprintf(tmp, "%s, %s", retstr, str);
|
||||||
|
wfree(retstr);
|
||||||
|
retstr = tmp;
|
||||||
|
}
|
||||||
|
wfree(str);
|
||||||
|
}
|
||||||
|
retstr = wstrappend(retstr, ")");
|
||||||
|
break;
|
||||||
|
case WPLDictionary:
|
||||||
|
retstr = wstrdup("{");
|
||||||
|
e = WMEnumerateHashTable(plist->d.dict);
|
||||||
|
while (WMNextHashEnumeratorItemAndKey(&e, (void**)&val, (void**)&key)) {
|
||||||
|
skey = description(key);
|
||||||
|
sval = description(val);
|
||||||
|
tmp = (char*)wmalloc(strlen(retstr)+strlen(skey)+strlen(sval)+5);
|
||||||
|
sprintf(tmp, "%s%s = %s;", retstr, skey, sval);
|
||||||
|
wfree(skey);
|
||||||
|
wfree(sval);
|
||||||
|
wfree(retstr);
|
||||||
|
retstr = tmp;
|
||||||
|
}
|
||||||
|
retstr = wstrappend(retstr, "}");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
wwarning(_("Used proplist functions on non-WMPropLists objects"));
|
||||||
|
wassertrv(False, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char*
|
||||||
|
indentedDescription(WMPropList *plist, int level)
|
||||||
|
{
|
||||||
|
WMPropList *key, *val;
|
||||||
|
char *retstr, *str, *tmp, *skey, *sval;
|
||||||
|
WMHashEnumerator e;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
switch (plist->type) {
|
||||||
|
case WPLString:
|
||||||
|
return stringDescription(plist);
|
||||||
|
case WPLData:
|
||||||
|
return dataDescription(plist);
|
||||||
|
case WPLArray:
|
||||||
|
retstr = wstrdup("(\n");
|
||||||
|
for (i=0; i<WMGetArrayItemCount(plist->d.array); i++) {
|
||||||
|
str = indentedDescription(WMGetFromArray(plist->d.array, i),
|
||||||
|
level+1);
|
||||||
|
if (i==0) {
|
||||||
|
tmp = (char*)wmalloc(2*(level+1)+strlen(retstr)+strlen(str)+1);
|
||||||
|
sprintf(tmp, "%s%*s%s", retstr, 2*(level+1), "", str);
|
||||||
|
wfree(retstr);
|
||||||
|
retstr = tmp;
|
||||||
|
} else {
|
||||||
|
tmp = (char*)wmalloc(2*(level+1)+strlen(retstr)+strlen(str)+3);
|
||||||
|
sprintf(tmp, "%s,\n%*s%s", retstr, 2*(level+1), "", str);
|
||||||
|
wfree(retstr);
|
||||||
|
retstr = tmp;
|
||||||
|
}
|
||||||
|
wfree(str);
|
||||||
|
}
|
||||||
|
tmp = (char*)wmalloc(strlen(retstr) + 2*level + 3);
|
||||||
|
sprintf(tmp, "%s\n%*s)", retstr, 2*level, "");
|
||||||
|
wfree(retstr);
|
||||||
|
retstr = tmp;
|
||||||
|
break;
|
||||||
|
case WPLDictionary:
|
||||||
|
retstr = wstrdup("{\n");
|
||||||
|
e = WMEnumerateHashTable(plist->d.dict);
|
||||||
|
while (WMNextHashEnumeratorItemAndKey(&e, (void**)&val, (void**)&key)) {
|
||||||
|
skey = indentedDescription(key, level+1);
|
||||||
|
sval = indentedDescription(val, level+1);
|
||||||
|
tmp = (char*)wmalloc(2*(level+1) + strlen(retstr) + strlen(skey)
|
||||||
|
+ strlen(sval) + 6);
|
||||||
|
sprintf(tmp, "%s%*s%s = %s;\n", retstr, 2*(level+1), "",
|
||||||
|
skey, sval);
|
||||||
|
wfree(skey);
|
||||||
|
wfree(sval);
|
||||||
|
wfree(retstr);
|
||||||
|
retstr = tmp;
|
||||||
|
}
|
||||||
|
tmp = (char*)wmalloc(strlen(retstr) + 2*level + 2);
|
||||||
|
sprintf(tmp, "%s%*s}", retstr, 2*level, "");
|
||||||
|
wfree(retstr);
|
||||||
|
retstr = tmp;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
wwarning(_("Used proplist functions on non-WMPropLists objects"));
|
||||||
|
wassertrv(False, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
WMSetPropListStringComparer(WMCompareDataProc *comparer)
|
WMSetPropListStringComparer(WMCompareDataProc *comparer)
|
||||||
@@ -136,7 +464,7 @@ WMCreatePropListDataWithBytesNoCopy(unsigned char *bytes, unsigned int length,
|
|||||||
{
|
{
|
||||||
WMPropList *plist;
|
WMPropList *plist;
|
||||||
|
|
||||||
wassertrv(length!=0 && bytes!=NULL, NULL);
|
wassertrv(bytes!=NULL, NULL);
|
||||||
|
|
||||||
plist = (WMPropList*)wmalloc(sizeof(W_PropList));
|
plist = (WMPropList*)wmalloc(sizeof(W_PropList));
|
||||||
|
|
||||||
@@ -197,6 +525,120 @@ WMCreatePropListArrayFromElements(WMPropList *elem, ...)
|
|||||||
WMPropList*
|
WMPropList*
|
||||||
WMCreatePropListDictionaryFromEntries(WMPropList *key, WMPropList *value, ...)
|
WMCreatePropListDictionaryFromEntries(WMPropList *key, WMPropList *value, ...)
|
||||||
{
|
{
|
||||||
|
WMPropList *plist, *nkey, *nvalue, *k, *v;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
plist = (WMPropList*)wmalloc(sizeof(W_PropList));
|
||||||
|
plist->type = WPLDictionary;
|
||||||
|
plist->d.dict = WMCreateHashTable(WMPropListHashCallbacks);
|
||||||
|
plist->retainCount = 1;
|
||||||
|
|
||||||
|
if (!key || !value)
|
||||||
|
return plist;
|
||||||
|
|
||||||
|
WMHashInsert(plist->d.dict, WMRetainPropList(key), WMRetainPropList(value));
|
||||||
|
|
||||||
|
va_start(ap, value);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
nkey = va_arg(ap, WMPropList*);
|
||||||
|
if (!nkey) {
|
||||||
|
va_end(ap);
|
||||||
|
return plist;
|
||||||
|
}
|
||||||
|
nvalue = va_arg(ap, WMPropList*);
|
||||||
|
if (!nvalue) {
|
||||||
|
va_end(ap);
|
||||||
|
return plist;
|
||||||
|
}
|
||||||
|
if (WMHashGetItemAndKey(plist->d.dict, nkey, (void**)&v, (void**)&k)) {
|
||||||
|
WMHashRemove(plist->d.dict, k);
|
||||||
|
WMReleasePropList(k);
|
||||||
|
WMReleasePropList(v);
|
||||||
|
}
|
||||||
|
WMHashInsert(plist->d.dict, WMRetainPropList(nkey),
|
||||||
|
WMRetainPropList(nvalue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
WMInsertPropListArrayElement(WMPropList *plist, WMPropList *item, int index)
|
||||||
|
{
|
||||||
|
wassertr(plist->type==WPLArray);
|
||||||
|
|
||||||
|
retainPropListByCount(item, plist->retainCount);
|
||||||
|
WMInsertInArray(plist->d.array, index, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
WMAppendPropListArrayElement(WMPropList *plist, WMPropList *item)
|
||||||
|
{
|
||||||
|
wassertr(plist->type==WPLArray);
|
||||||
|
|
||||||
|
retainPropListByCount(item, plist->retainCount);
|
||||||
|
WMAddToArray(plist->d.array, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
WMRemovePropListArrayElement(WMPropList *plist, int index)
|
||||||
|
{
|
||||||
|
WMPropList *item;
|
||||||
|
|
||||||
|
wassertr(plist->type==WPLArray);
|
||||||
|
|
||||||
|
item = WMGetFromArray(plist->d.array, index);
|
||||||
|
if (item != NULL) {
|
||||||
|
WMDeleteFromArray(plist->d.array, index);
|
||||||
|
releasePropListByCount(item, plist->retainCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
WMInsertPropListDictionaryEntry(WMPropList *plist, WMPropList *key,
|
||||||
|
WMPropList *value)
|
||||||
|
{
|
||||||
|
wassertr(plist->type==WPLDictionary);
|
||||||
|
|
||||||
|
WMRemovePropListDictionaryEntry(plist, key);
|
||||||
|
retainPropListByCount(key, plist->retainCount);
|
||||||
|
retainPropListByCount(value, plist->retainCount);
|
||||||
|
WMHashInsert(plist->d.dict, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
WMRemovePropListDictionaryEntry(WMPropList *plist, WMPropList *key)
|
||||||
|
{
|
||||||
|
WMPropList *k, *v;
|
||||||
|
|
||||||
|
wassertr(plist->type==WPLDictionary);
|
||||||
|
|
||||||
|
if (WMHashGetItemAndKey(plist->d.dict, key, (void**)&v, (void**)&k)) {
|
||||||
|
WMHashRemove(plist->d.dict, k);
|
||||||
|
releasePropListByCount(k, plist->retainCount);
|
||||||
|
releasePropListByCount(v, plist->retainCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WMPropList*
|
||||||
|
WMMergePropListDictionaries(WMPropList *dest, WMPropList *source)
|
||||||
|
{
|
||||||
|
WMPropList *key, *value;
|
||||||
|
WMHashEnumerator e;
|
||||||
|
|
||||||
|
wassertr(source->type==WPLDictionary && dest->type==WPLDictionary);
|
||||||
|
|
||||||
|
e = WMEnumerateHashTable(source->d.dict);
|
||||||
|
while (WMNextHashEnumeratorItemAndKey(&e, (void**)&value, (void**)&key)) {
|
||||||
|
WMInsertPropListDictionaryEntry(dest, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -234,7 +676,6 @@ WMRetainPropList(WMPropList *plist)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
void
|
void
|
||||||
WMReleasePropList(WMPropList *plist)
|
WMReleasePropList(WMPropList *plist)
|
||||||
{
|
{
|
||||||
@@ -282,61 +723,6 @@ WMReleasePropList(WMPropList *plist)
|
|||||||
wassertr(False);
|
wassertr(False);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
|
|
||||||
void
|
|
||||||
WMReleasePropList(WMPropList *plist)
|
|
||||||
{
|
|
||||||
WMPropList *key, *value;
|
|
||||||
WMHashEnumerator e;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
plist->retainCount--;
|
|
||||||
|
|
||||||
switch(plist->type) {
|
|
||||||
case WPLString:
|
|
||||||
case WPLData:
|
|
||||||
break;
|
|
||||||
case WPLArray:
|
|
||||||
for (i=0; i<WMGetArrayItemCount(plist->d.array); i++) {
|
|
||||||
WMReleasePropList(WMGetFromArray(plist->d.array, i));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WPLDictionary:
|
|
||||||
e = WMEnumerateHashTable(plist->d.dict);
|
|
||||||
while (WMNextHashEnumeratorItemAndKey(&e, (void**)&value, (void**)&key)) {
|
|
||||||
WMReleasePropList(key);
|
|
||||||
WMReleasePropList(value);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
wwarning(_("Used proplist functions on non-WMPropLists objects"));
|
|
||||||
wassertr(False);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plist->retainCount > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch(plist->type) {
|
|
||||||
case WPLString:
|
|
||||||
wfree(plist->d.string);
|
|
||||||
break;
|
|
||||||
case WPLData:
|
|
||||||
WMReleaseData(plist->d.data);
|
|
||||||
break;
|
|
||||||
case WPLArray:
|
|
||||||
WMFreeArray(plist->d.array);
|
|
||||||
break;
|
|
||||||
case WPLDictionary:
|
|
||||||
WMFreeHashTable(plist->d.dict);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
wwarning(_("Used proplist functions on non-WMPropLists objects"));
|
|
||||||
wassertr(False);
|
|
||||||
}
|
|
||||||
wfree(plist);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
@@ -382,9 +768,9 @@ WMPropListIsCompound(WMPropList *plist)
|
|||||||
|
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
WMArePropListsEqual(WMPropList *plist, WMPropList *other)
|
WMIsPropListEqualToPropList(WMPropList *plist, WMPropList *other)
|
||||||
{
|
{
|
||||||
WMPropList *key1, *key2, *item1, *item2;
|
WMPropList *key1, *item1, *item2;
|
||||||
WMHashEnumerator enumerator;
|
WMHashEnumerator enumerator;
|
||||||
int n, i;
|
int n, i;
|
||||||
|
|
||||||
@@ -393,7 +779,7 @@ WMArePropListsEqual(WMPropList *plist, WMPropList *other)
|
|||||||
|
|
||||||
switch(plist->type) {
|
switch(plist->type) {
|
||||||
case WPLString:
|
case WPLString:
|
||||||
return ((*strCmp)(plist->d.string, other->d.string) == 0);
|
return (strCmp(plist->d.string, other->d.string) == 0);
|
||||||
case WPLData:
|
case WPLData:
|
||||||
return WMIsDataEqualToData(plist->d.data, other->d.data);
|
return WMIsDataEqualToData(plist->d.data, other->d.data);
|
||||||
case WPLArray:
|
case WPLArray:
|
||||||
@@ -403,7 +789,7 @@ WMArePropListsEqual(WMPropList *plist, WMPropList *other)
|
|||||||
for (i=0; i<n; i++) {
|
for (i=0; i<n; i++) {
|
||||||
item1 = WMGetFromArray(plist->d.array, i);
|
item1 = WMGetFromArray(plist->d.array, i);
|
||||||
item2 = WMGetFromArray(other->d.array, i);
|
item2 = WMGetFromArray(other->d.array, i);
|
||||||
if (!WMArePropListsEqual(item1, item2))
|
if (!WMIsPropListEqualToPropList(item1, item2))
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
return True;
|
return True;
|
||||||
@@ -414,7 +800,7 @@ WMArePropListsEqual(WMPropList *plist, WMPropList *other)
|
|||||||
while (WMNextHashEnumeratorItemAndKey(&enumerator, (void**)&item1,
|
while (WMNextHashEnumeratorItemAndKey(&enumerator, (void**)&item1,
|
||||||
(void**)&key1)) {
|
(void**)&key1)) {
|
||||||
item2 = WMHashGet(other->d.dict, key1);
|
item2 = WMHashGet(other->d.dict, key1);
|
||||||
if (!item2 || !item1 || !WMArePropListsEqual(item1, item2))
|
if (!item2 || !item1 || !WMIsPropListEqualToPropList(item1, item2))
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
return True;
|
return True;
|
||||||
@@ -427,6 +813,269 @@ WMArePropListsEqual(WMPropList *plist, WMPropList *other)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
WMGetPropListNumberOfElements(WMPropList *plist)
|
||||||
|
{
|
||||||
|
switch(plist->type) {
|
||||||
|
case WPLString:
|
||||||
|
case WPLData:
|
||||||
|
return 0; /* should this be 1 instead? */
|
||||||
|
case WPLArray:
|
||||||
|
return WMGetArrayItemCount(plist->d.array);
|
||||||
|
case WPLDictionary:
|
||||||
|
return (int)WMCountHashTable(plist->d.dict);
|
||||||
|
default:
|
||||||
|
wwarning(_("Used proplist functions on non-WMPropLists objects"));
|
||||||
|
wassertrv(False, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char*
|
||||||
|
WMGetPropListString(WMPropList *plist)
|
||||||
|
{
|
||||||
|
wassertrv(plist->type==WPLString, NULL);
|
||||||
|
|
||||||
|
return plist->d.string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WMData*
|
||||||
|
WMGetPropListData(WMPropList *plist)
|
||||||
|
{
|
||||||
|
wassertrv(plist->type==WPLData, NULL);
|
||||||
|
|
||||||
|
return plist->d.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const unsigned char*
|
||||||
|
WMGetPropListDataBytes(WMPropList *plist)
|
||||||
|
{
|
||||||
|
wassertrv(plist->type==WPLData, NULL);
|
||||||
|
|
||||||
|
return WMDataBytes(plist->d.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
WMGetPropListDataLength(WMPropList *plist)
|
||||||
|
{
|
||||||
|
wassertrv(plist->type==WPLData, 0);
|
||||||
|
|
||||||
|
return WMGetDataLength(plist->d.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WMPropList*
|
||||||
|
WMGetPropListArrayElement(WMPropList *plist, int index)
|
||||||
|
{
|
||||||
|
wassertrv(plist->type==WPLArray, NULL);
|
||||||
|
|
||||||
|
return WMGetFromArray(plist->d.array, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WMPropList*
|
||||||
|
WMGetPropListDictionaryEntry(WMPropList *plist, WMPropList *key)
|
||||||
|
{
|
||||||
|
wassertrv(plist->type==WPLDictionary, NULL);
|
||||||
|
|
||||||
|
return WMHashGet(plist->d.dict, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WMPropList*
|
||||||
|
WMGetPropListAllDictionaryKeys(WMPropList *plist)
|
||||||
|
{
|
||||||
|
WMPropList *array, *key;
|
||||||
|
WMHashEnumerator enumerator;
|
||||||
|
|
||||||
|
wassertrv(plist->type==WPLDictionary, NULL);
|
||||||
|
|
||||||
|
array = (WMPropList*)wmalloc(sizeof(W_PropList));
|
||||||
|
array->type = WPLArray;
|
||||||
|
array->d.array = WMCreateArray(WMCountHashTable(plist->d.dict));
|
||||||
|
array->retainCount = 1;
|
||||||
|
|
||||||
|
enumerator = WMEnumerateHashTable(plist->d.dict);
|
||||||
|
while ((key = WMNextHashEnumeratorKey(&enumerator))) {
|
||||||
|
WMAddToArray(array->d.array, WMRetainPropList(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char*
|
||||||
|
WMGetPropListDescription(WMPropList *plist, Bool indented)
|
||||||
|
{
|
||||||
|
return (indented ? indentedDescription(plist, 0) : description(plist));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO: review this function's code */
|
||||||
|
|
||||||
|
Bool
|
||||||
|
WMSavePropListToFile(WMPropList *plist, char *path, Bool atomically)
|
||||||
|
{
|
||||||
|
char *thePath=NULL;
|
||||||
|
char *description;
|
||||||
|
FILE *theFile;
|
||||||
|
|
||||||
|
if (atomically) {
|
||||||
|
#ifdef HAVE_MKSTEMP
|
||||||
|
int fd, mask;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Use the path name of the destination file as a prefix for the
|
||||||
|
* mkstemp() call so that we can be sure that both files are on
|
||||||
|
* the same filesystem and the subsequent rename() will work. */
|
||||||
|
thePath = wstrconcat(path, ".XXXXXX");
|
||||||
|
|
||||||
|
#ifdef HAVE_MKSTEMP
|
||||||
|
if ((fd = mkstemp(thePath)) < 0) {
|
||||||
|
wsyserror(_("mkstemp (%s) failed"), thePath);
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
mask = umask(0);
|
||||||
|
umask(mask);
|
||||||
|
fchmod(fd, 0644 & ~mask);
|
||||||
|
if ((theFile = fdopen(fd, "w")) == NULL) {
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (mktemp(thePath) == NULL) {
|
||||||
|
wsyserror(_("mktemp (%s) failed"), thePath);
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
theFile = fopen(thePath, "wb");
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
thePath = wstrdup(path);
|
||||||
|
theFile = fopen(thePath, "wb");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theFile == NULL) {
|
||||||
|
wsyserror(_("open (%s) failed"), thePath);
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
description = indentedDescription(plist, 0);
|
||||||
|
|
||||||
|
if (fprintf(theFile, "%s\n", description) != strlen(description)+1) {
|
||||||
|
wsyserror(_("writing to file: %s failed"), thePath);
|
||||||
|
wfree(description);
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
wfree(description);
|
||||||
|
|
||||||
|
if (fclose(theFile) != 0) {
|
||||||
|
wsyserror(_("fclose (%s) failed"), thePath);
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we used a temporary file, we still need to rename() it be the
|
||||||
|
* real file. Also, we need to try to retain the file attributes of
|
||||||
|
* the original file we are overwriting (if we are) */
|
||||||
|
if (atomically) {
|
||||||
|
if (rename(thePath, path) != 0) {
|
||||||
|
wsyserror(_("rename ('%s' to '%s') failed"), thePath, path);
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wfree(thePath);
|
||||||
|
return True;
|
||||||
|
|
||||||
|
failure:
|
||||||
|
if (atomically) {
|
||||||
|
unlink(thePath);
|
||||||
|
wfree(thePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WMPropList*
|
||||||
|
WMShallowCopyPropList(WMPropList *plist)
|
||||||
|
{
|
||||||
|
WMPropList *ret, *key, *item;
|
||||||
|
WMHashEnumerator e;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
switch(plist->type) {
|
||||||
|
case WPLString:
|
||||||
|
case WPLData:
|
||||||
|
return WMDeepCopyPropList(plist);
|
||||||
|
case WPLArray:
|
||||||
|
ret = (WMPropList*)wmalloc(sizeof(W_PropList));
|
||||||
|
ret->type = WPLArray;
|
||||||
|
ret->d.array = WMCreateArrayWithArray(plist->d.array);
|
||||||
|
ret->retainCount = 1;
|
||||||
|
|
||||||
|
for(i=0; i<WMGetArrayItemCount(ret->d.array); i++)
|
||||||
|
WMRetainPropList(WMGetFromArray(ret->d.array, i));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
case WPLDictionary:
|
||||||
|
ret = WMCreatePropListDictionaryFromEntries(NULL, NULL);
|
||||||
|
e = WMEnumerateHashTable(plist->d.dict);
|
||||||
|
while (WMNextHashEnumeratorItemAndKey(&e, (void**)&item, (void**)&key)) {
|
||||||
|
WMInsertPropListDictionaryEntry(ret, key, item);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
default:
|
||||||
|
wwarning(_("Used proplist functions on non-WMPropLists objects"));
|
||||||
|
wassertrv(False, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WMPropList*
|
||||||
|
WMDeepCopyPropList(WMPropList *plist)
|
||||||
|
{
|
||||||
|
WMPropList *ret, *key, *item;
|
||||||
|
WMHashEnumerator e;
|
||||||
|
WMData *data;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
switch(plist->type) {
|
||||||
|
case WPLString:
|
||||||
|
return WMCreatePropListString(plist->d.string);
|
||||||
|
case WPLData:
|
||||||
|
data = WMCreateDataWithData(plist->d.data);
|
||||||
|
ret = WMCreatePropListDataWithData(data);
|
||||||
|
WMReleaseData(data);
|
||||||
|
return ret;
|
||||||
|
case WPLArray:
|
||||||
|
ret = WMCreatePropListArrayFromElements(NULL);
|
||||||
|
for(i=0; i<WMGetArrayItemCount(plist->d.array); i++) {
|
||||||
|
item = WMDeepCopyPropList(WMGetFromArray(plist->d.array, i));
|
||||||
|
WMAddToArray(ret->d.array, item);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
case WPLDictionary:
|
||||||
|
ret = WMCreatePropListDictionaryFromEntries(NULL, NULL);
|
||||||
|
e = WMEnumerateHashTable(plist->d.dict);
|
||||||
|
/* While we copy an existing dictionary there is no way that we can
|
||||||
|
* have duplicate keys, so we don't need to first remove a key/value
|
||||||
|
* pair before inserting the new key/value.
|
||||||
|
*/
|
||||||
|
while (WMNextHashEnumeratorItemAndKey(&e, (void**)&item, (void**)&key)) {
|
||||||
|
WMHashInsert(ret->d.dict, WMDeepCopyPropList(key),
|
||||||
|
WMDeepCopyPropList(item));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
default:
|
||||||
|
wwarning(_("Used proplist functions on non-WMPropLists objects"));
|
||||||
|
wassertrv(False, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ dnl not used anywhere
|
|||||||
dnl AC_FUNC_MEMCMP
|
dnl AC_FUNC_MEMCMP
|
||||||
AC_FUNC_VPRINTF
|
AC_FUNC_VPRINTF
|
||||||
AC_FUNC_ALLOCA
|
AC_FUNC_ALLOCA
|
||||||
AC_CHECK_FUNCS(gethostname select poll strerror strcasecmp strncasecmp setpgid atexit mallinfo vsnprintf vasprintf)
|
AC_CHECK_FUNCS(gethostname select poll strerror strcasecmp strncasecmp setpgid atexit mallinfo vsnprintf vasprintf mkstemp)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
10
configure.in
10
configure.in
@@ -100,7 +100,7 @@ dnl not used anywhere
|
|||||||
dnl AC_FUNC_MEMCMP
|
dnl AC_FUNC_MEMCMP
|
||||||
AC_FUNC_VPRINTF
|
AC_FUNC_VPRINTF
|
||||||
AC_FUNC_ALLOCA
|
AC_FUNC_ALLOCA
|
||||||
AC_CHECK_FUNCS(gethostname select poll strerror strcasecmp strncasecmp setpgid atexit mallinfo vsnprintf vasprintf)
|
AC_CHECK_FUNCS(gethostname select poll strerror strcasecmp strncasecmp setpgid atexit mallinfo vsnprintf vasprintf mkstemp)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -151,7 +151,7 @@ dnl Checks for header files.
|
|||||||
dnl =======================
|
dnl =======================
|
||||||
AC_HEADER_SYS_WAIT
|
AC_HEADER_SYS_WAIT
|
||||||
AC_HEADER_TIME
|
AC_HEADER_TIME
|
||||||
AC_CHECK_HEADERS(fcntl.h limits.h sys/ioctl.h sys/time.h sys/types.h libintl.h sys/select.h poll.h malloc.h ctype.h stdlib.h)
|
AC_CHECK_HEADERS(fcntl.h limits.h sys/ioctl.h sys/time.h sys/types.h libintl.h sys/select.h poll.h malloc.h ctype.h stdlib.h string.h strings.h)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -436,9 +436,9 @@ fi
|
|||||||
dnl XINERAMA support
|
dnl XINERAMA support
|
||||||
dnl ================
|
dnl ================
|
||||||
xinerama=no
|
xinerama=no
|
||||||
AC_ARG_ENABLE(xinerama,
|
#AC_ARG_ENABLE(xinerama,
|
||||||
[ --disable-xinerama disable XInerama extension support],
|
#[ --disable-xinerama disable XInerama extension support],
|
||||||
xinerama=$enableval, xinerama=yes)
|
# xinerama=$enableval, xinerama=yes)
|
||||||
|
|
||||||
if test "$xinerama" = yes; then
|
if test "$xinerama" = yes; then
|
||||||
AC_CHECK_LIB(Xinerama, XineramaQueryScreens, [XLIBS="-lXinerama $XLIBS"
|
AC_CHECK_LIB(Xinerama, XineramaQueryScreens, [XLIBS="-lXinerama $XLIBS"
|
||||||
|
|||||||
@@ -336,11 +336,6 @@ typedef struct _WScreen {
|
|||||||
typedef struct WWorkspaceState {
|
typedef struct WWorkspaceState {
|
||||||
int flags;
|
int flags;
|
||||||
int workspace;
|
int workspace;
|
||||||
#if 0 /* obsoleted by saving menus position in WMState */
|
|
||||||
int menu_x, menu_y;
|
|
||||||
int smenu_x, smenu_y;
|
|
||||||
int wmenu_x, wmenu_y;
|
|
||||||
#endif
|
|
||||||
} WWorkspaceState;
|
} WWorkspaceState;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -709,12 +709,12 @@ wSessionSendSaveYourself(WScreen *scr)
|
|||||||
* - this state file is not meant to be edited by users
|
* - this state file is not meant to be edited by users
|
||||||
*
|
*
|
||||||
* The old session code will become obsolete. When wmaker is
|
* The old session code will become obsolete. When wmaker is
|
||||||
* compiled with R6 sm support compiled in, itll be better to
|
* compiled with R6 sm support compiled in, it'll be better to
|
||||||
* use a totally rewritten state saving code, but we can keep
|
* use a totally rewritten state saving code, but we can keep
|
||||||
* the current code for when XSMP_ENABLED is not compiled in.
|
* the current code for when XSMP_ENABLED is not compiled in.
|
||||||
*
|
*
|
||||||
* This will be confusing to old users (well get lots of "SAVE_SESSION broke!"
|
* This will be confusing to old users (well get lots of "SAVE_SESSION broke!"
|
||||||
* messages), but itll be better.
|
* messages), but it'll be better.
|
||||||
*
|
*
|
||||||
* -readme
|
* -readme
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Avoid a compiler warning */
|
||||||
|
#undef HAVE_STDLIB_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user