📄 xrm.c
字号:
_XCreateMutex(&db->linfo); db->table = (NTable)NULL; db->mbstate = (XPointer)NULL; // FIXME db->methods = _XrmInitParseInfo(&db->mbstate); if (!db->methods) db->methods = &mb_methods; } return db;}/* move all values from ftable to ttable, and free ftable's buckets. * ttable is quaranteed empty to start with. */static void MoveValues(ftable, ttable) LTable ftable; register LTable ttable;{ register VEntry fentry, nfentry; register VEntry *prev; register VEntry *bucket; register VEntry tentry; register int i; for (i = ftable->table.mask, bucket = ftable->buckets; i >= 0; i--) { for (fentry = *bucket++; fentry; fentry = nfentry) { prev = &LeafHash(ttable, fentry->name); tentry = *prev; *prev = fentry; /* chain on all with same name, to preserve invariant order */ while ((nfentry = fentry->next) && nfentry->name == fentry->name) fentry = nfentry; fentry->next = tentry; } } Xfree((char *)ftable->buckets);}/* move all tables from ftable to ttable, and free ftable. * ttable is quaranteed empty to start with. */static void MoveTables(ftable, ttable) NTable ftable; register NTable ttable;{ register NTable fentry, nfentry; register NTable *prev; register NTable *bucket; register NTable tentry; register int i; for (i = ftable->mask, bucket = NodeBuckets(ftable); i >= 0; i--) { for (fentry = *bucket++; fentry; fentry = nfentry) { prev = &NodeHash(ttable, fentry->name); tentry = *prev; *prev = fentry; /* chain on all with same name, to preserve invariant order */ while ((nfentry = fentry->next) && nfentry->name == fentry->name) fentry = nfentry; fentry->next = tentry; } } Xfree((char *)ftable);}/* grow the table, based on current number of entries */static void GrowTable(prev) NTable *prev;{ register NTable table; register int i; table = *prev; i = table->mask; if (i == 255) /* biggest it gets */ return; while (i < 255 && GrowthPred(table->entries, i)) i = (i << 1) + 1; i++; /* i is now the new size */ if (table->leaf) { register LTable ltable; LTableRec otable; ltable = (LTable)table; /* cons up a copy to make MoveValues look symmetric */ otable = *ltable; ltable->buckets = (VEntry *)Xmalloc(i * sizeof(VEntry)); if (!ltable->buckets) { ltable->buckets = otable.buckets; return; } ltable->table.mask = i - 1; bzero((char *)ltable->buckets, i * sizeof(VEntry)); MoveValues(&otable, ltable); } else { register NTable ntable; ntable = (NTable)Xmalloc(sizeof(NTableRec) + i * sizeof(NTable)); if (!ntable) return; *ntable = *table; ntable->mask = i - 1; bzero((char *)NodeBuckets(ntable), i * sizeof(NTable)); *prev = ntable; MoveTables(table, ntable); }}/* merge values from ftable into *pprev, destroy ftable in the process */static void MergeValues(ftable, pprev, override) LTable ftable; NTable *pprev; Bool override;{ register VEntry fentry, tentry; register VEntry *prev; register LTable ttable; VEntry *bucket; int i; register XrmQuark q; ttable = (LTable)*pprev; if (ftable->table.hasloose) ttable->table.hasloose = 1; for (i = ftable->table.mask, bucket = ftable->buckets; i >= 0; i--, bucket++) { for (fentry = *bucket; fentry; ) { q = fentry->name; prev = &LeafHash(ttable, q); tentry = *prev; while (tentry && tentry->name != q) tentry = *(prev = &tentry->next); /* note: test intentionally uses fentry->name instead of q */ /* permits serendipitous inserts */ while (tentry && tentry->name == fentry->name) { /* if tentry is earlier, skip it */ if (!fentry->tight && tentry->tight) { tentry = *(prev = &tentry->next); continue; } if (fentry->tight != tentry->tight) { /* no match, chain in fentry */ *prev = fentry; prev = &fentry->next; fentry = *prev; *prev = tentry; ttable->table.entries++; } else if (override) { /* match, chain in fentry, splice out and free tentry */ *prev = fentry; prev = &fentry->next; fentry = *prev; *prev = tentry->next; /* free the overridden entry */ Xfree((char *)tentry); /* get next tentry */ tentry = *prev; } else { /* match, discard fentry */ prev = &tentry->next; tentry = fentry; /* use as a temp var */ fentry = fentry->next; /* free the overpowered entry */ Xfree((char *)tentry); /* get next tentry */ tentry = *prev; } if (!fentry) break; } /* at this point, tentry cannot match any fentry named q */ /* chain in all bindings together, preserve invariant order */ while (fentry && fentry->name == q) { *prev = fentry; prev = &fentry->next; fentry = *prev; *prev = tentry; ttable->table.entries++; } } } Xfree((char *)ftable->buckets); Xfree((char *)ftable); /* resize if necessary, now that we're all done */ GROW(pprev);}/* merge tables from ftable into *pprev, destroy ftable in the process */static void MergeTables(ftable, pprev, override) NTable ftable; NTable *pprev; Bool override;{ register NTable fentry, tentry; NTable nfentry; register NTable *prev; register NTable ttable; NTable *bucket; int i; register XrmQuark q; ttable = *pprev; if (ftable->hasloose) ttable->hasloose = 1; if (ftable->hasany) ttable->hasany = 1; for (i = ftable->mask, bucket = NodeBuckets(ftable); i >= 0; i--, bucket++) { for (fentry = *bucket; fentry; ) { q = fentry->name; prev = &NodeHash(ttable, q); tentry = *prev; while (tentry && tentry->name != q) tentry = *(prev = &tentry->next); /* note: test intentionally uses fentry->name instead of q */ /* permits serendipitous inserts */ while (tentry && tentry->name == fentry->name) { /* if tentry is earlier, skip it */ if ((fentry->leaf && !tentry->leaf) || (!fentry->tight && tentry->tight && (fentry->leaf || !tentry->leaf))) { tentry = *(prev = &tentry->next); continue; } nfentry = fentry->next; if (fentry->leaf != tentry->leaf || fentry->tight != tentry->tight) { /* no match, just chain in */ *prev = fentry; *(prev = &fentry->next) = tentry; ttable->entries++; } else { if (fentry->leaf) MergeValues((LTable)fentry, prev, override); else MergeTables(fentry, prev, override); /* bump to next tentry */ tentry = *(prev = &(*prev)->next); } /* bump to next fentry */ fentry = nfentry; if (!fentry) break; } /* at this point, tentry cannot match any fentry named q */ /* chain in all bindings together, preserve invariant order */ while (fentry && fentry->name == q) { *prev = fentry; prev = &fentry->next; fentry = *prev; *prev = tentry; ttable->entries++; } } } Xfree((char *)ftable); /* resize if necessary, now that we're all done */ GROW(pprev);}void XrmCombineDatabase(from, into, override) XrmDatabase from, *into; Bool override;{ register NTable *prev; register NTable ftable, ttable, nftable; if (!*into) { *into = from; } else if (from) { _XLockMutex(&from->linfo); _XLockMutex(&(*into)->linfo); if ((ftable = from->table)) { prev = &(*into)->table; ttable = *prev; if (!ftable->leaf) { nftable = ftable->next; if (ttable && !ttable->leaf) { /* both have node tables, merge them */ MergeTables(ftable, prev, override); /* bump to into's leaf table, if any */ ttable = *(prev = &(*prev)->next); } else { /* into has no node table, link from's in */ *prev = ftable; *(prev = &ftable->next) = ttable; } /* bump to from's leaf table, if any */ ftable = nftable; } else { /* bump to into's leaf table, if any */ if (ttable && !ttable->leaf) ttable = *(prev = &ttable->next); } if (ftable) { /* if into has a leaf, merge, else insert */ if (ttable) MergeValues((LTable)ftable, prev, override); else *prev = ftable; } } (from->methods->destroy)(from->mbstate); _XFreeMutex(&from->linfo); Xfree((char *)from); _XUnlockMutex(&(*into)->linfo); }}void XrmMergeDatabases(from, into) XrmDatabase from, *into;{ XrmCombineDatabase(from, into, True);}/* store a value in the database, overriding any existing entry */static void PutEntry(db, bindings, quarks, type, value) XrmDatabase db; XrmBindingList bindings; XrmQuarkList quarks; XrmRepresentation type; XrmValuePtr value;{ register NTable *pprev, *prev; register NTable table; register XrmQuark q; register VEntry *vprev; register VEntry entry; NTable *nprev, *firstpprev;#define NEWTABLE(q,i) \ table = (NTable)Xmalloc(sizeof(LTableRec)); \ if (!table) \ return; \ table->name = q; \ table->hasloose = 0; \ table->hasany = 0; \ table->mask = 0; \ table->entries = 0; \ if (quarks[i]) { \ table->leaf = 0; \ nprev = NodeBuckets(table); \ } else { \ table->leaf = 1; \ if (!(nprev = (NTable *)Xmalloc(sizeof(VEntry *)))) \ return; \ ((LTable)table)->buckets = (VEntry *)nprev; \ } \ *nprev = (NTable)NULL; \ table->next = *prev; \ *prev = table if (!db || !*quarks) return; table = *(prev = &db->table); /* if already at leaf, bump to the leaf table */ if (!quarks[1] && table && !table->leaf) table = *(prev = &table->next); pprev = prev; if (!table || (quarks[1] && table->leaf)) { /* no top-level node table, create one and chain it in */ NEWTABLE(NULLQUARK,1); table->tight = 1; /* arbitrary */ prev = nprev; } else { /* search along until we need a value */ while (quarks[1]) { q = *quarks; table = *(prev = &NodeHash(table, q)); while (table && table->name != q) table = *(prev = &table->next); if (!table) break; /* not found */ if (quarks[2]) { if (table->leaf) break; /* not found */ } else { if (!table->leaf) { /* bump to leaf table, if any */ table = *(prev = &table->next); if (!table || table->name != q) break; /* not found */ if (!table->leaf) { /* bump to leaf table, if any */ table = *(prev = &table->next); if (!table || table->name != q) break; /* not found */ } } } if (*bindings == XrmBindTightly) { if (!table->tight) break; /* not found */ } else { if (table->tight) { /* bump to loose table, if any */ table = *(prev = &table->next); if (!table || table->name != q || !quarks[2] != table->leaf) break; /* not found */ } } /* found that one, bump to next quark */ pprev = prev; quarks++; bindings++; } if (!quarks[1]) { /* found all the way to a leaf */ q = *quarks; entry = *(vprev = &LeafHash((LTable)table, q)); while (entry && entry->name != q) entry = *(vprev = &entry->next); /* if want loose and have tight, bump to next entry */ if (entry && *bindings == XrmBindLoosely && entry->tight) entry = *(vprev = &entry->next); if (entry && entry->name == q && (*bindings == XrmBindTightly) == entry->tight) { /* match, need to override */ if ((type == XrmQString) == entry->string && entry->size == value->size) { /* update type if not String, can be different */ if (!entry->string) RepType(entry) = type; /* identical size, just overwrite value */ memcpy(RawValue(entry), (char *)value->addr, value->size); return; } /* splice out and free old entry */ *vprev = entry->next; Xfree((char *)entry); (*pprev)->entries--; } /* this is where to insert */ prev = (NTable *)vprev; } } /* keep the top table, because we may have to grow it */ firstpprev = pprev; /* iterate until we get to the leaf */ while (quarks[1]) { /* build a new table and chain it in */ NEWTABLE(*quarks,2); if (*quarks++ == XrmQANY) (*pprev)->hasany = 1; if (*bindings++ == XrmBindTightly) { table->tight = 1; } else { table->tight = 0; (*pprev)->hasloose = 1; } (*pprev)->entries++; pprev = prev; prev = nprev; } /* now allocate the value entry */ entry = (VEntry)Xmalloc(((type == XrmQString) ? sizeof(VEntryRec) : sizeof(DEntryRec)) + value->size); if (!entry) return; entry->name = q = *quarks; if (*bindings == XrmBindTightly) { entry->tight = 1; } else { entry->tight = 0; (*pprev)->hasloose = 1; } /* chain it in, with a bit of type cast ugliness */ entry->next = *((VEntry *)prev); *((VEntry *)prev) = entry; entry->size = value->size; if (type == XrmQString) { entry->string = 1; } else { entry->string = 0; RepType(entry) = type; } /* save a copy of the value */ memcpy(RawValue(entry), (char *)value->addr, value->size); (*pprev)->entries++; /* this is a new leaf, need to remember it for search lists */ if (q > maxResourceQuark) { unsigned oldsize = (maxResourceQuark + 1) >> 3; unsigned size = ((q | 0x7f) + 1) >> 3; /* reallocate in chunks */ if (resourceQuarks) { unsigned char *prevQuarks = resourceQuarks; resourceQuarks = (unsigned char *)Xrealloc((char *)resourceQuarks, size); if (!resourceQuarks) { Xfree(prevQuarks); } } else resourceQuarks = (unsigned char *)Xmalloc(size); if (resourceQuarks) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -