📄 xrm.c
字号:
char *str; char realfname[BUFSIZ]; if (fnamelen <= 0 || fnamelen >= BUFSIZ) return; if (*fname != '/' && base && (str = rindex(base, '/'))) { len = str - base + 1; if (len + fnamelen >= BUFSIZ) return; strncpy(realfname, base, len); strncpy(realfname + len, fname, fnamelen); realfname[len + fnamelen] = '\0'; } else { strncpy(realfname, fname, fnamelen); realfname[fnamelen] = '\0'; } if (!(str = ReadInFile(realfname))) return; GetDatabase(db, str, realfname, True); Xfree(str);}#if NeedFunctionPrototypesXrmDatabase XrmGetFileDatabase( _Xconst char *filename)#elseXrmDatabase XrmGetFileDatabase(filename) char *filename;#endif{ XrmDatabase db; char *str; if (!(str = ReadInFile(filename))) return (XrmDatabase)NULL; db = NewDatabase(); GetDatabase(db, str, filename, True); Xfree(str); return db;}#if NeedFunctionPrototypesStatus XrmCombineFileDatabase( _Xconst char *filename, XrmDatabase *target, Bool override)#elseStatus XrmCombineFileDatabase(filename, target, override) char *filename; XrmDatabase *target; Bool override;#endif{ XrmDatabase db; char *str; if (!(str = ReadInFile(filename))) return 0; if (override) { db = *target; if (!db) *target = db = NewDatabase(); } else db = NewDatabase(); GetDatabase(db, str, filename, True); Xfree(str); if (!override) XrmCombineDatabase(db, target, False); return 1;}/* call the user proc for every value in the table, arbitrary order. * stop if user proc returns True. level is current depth in database. *//*ARGSUSED*/static Bool EnumLTable(table, names, classes, level, closure) LTable table; XrmNameList names; XrmClassList classes; register int level; register EClosure closure;{ register VEntry *bucket; register int i; register VEntry entry; XrmValue value; XrmRepresentation type; Bool tightOk; closure->bindings[level] = (table->table.tight ? XrmBindTightly : XrmBindLoosely); closure->quarks[level] = table->table.name; level++; tightOk = !*names; closure->quarks[level + 1] = NULLQUARK; for (i = table->table.mask, bucket = table->buckets; i >= 0; i--, bucket++) { for (entry = *bucket; entry; entry = entry->next) { if (entry->tight && !tightOk) continue; closure->bindings[level] = (entry->tight ? XrmBindTightly : XrmBindLoosely); closure->quarks[level] = entry->name; value.size = entry->size; if (entry->string) { type = XrmQString; value.addr = StringValue(entry); } else { type = RepType(entry); value.addr = DataValue(entry); } if ((*closure->proc)(&closure->db, closure->bindings+1, closure->quarks+1, &type, &value, closure->closure)) return True; } } return False;}static Bool EnumAllNTable(table, level, closure) NTable table; register int level; register EClosure closure;{ register NTable *bucket; register int i; register NTable entry; XrmQuark empty = NULLQUARK; if (level >= MAXDBDEPTH) return False; for (i = table->mask, bucket = NodeBuckets(table); i >= 0; i--, bucket++) { for (entry = *bucket; entry; entry = entry->next) { if (entry->leaf) { if (EnumLTable((LTable)entry, &empty, &empty, level, closure)) return True; } else { closure->bindings[level] = (entry->tight ? XrmBindTightly : XrmBindLoosely); closure->quarks[level] = entry->name; if (EnumAllNTable(entry, level+1, closure)) return True; } } } return False;}/* recurse on every table in the table, arbitrary order. * stop if user proc returns True. level is current depth in database. */static Bool EnumNTable(table, names, classes, level, closure) NTable table; XrmNameList names; XrmClassList classes; register int level; register EClosure closure;{ register NTable entry; register XrmQuark q; register unsigned int leaf; Bool (*get)(); Bool bilevel;/* find entries named ename, leafness leaf, tight or loose, and call get */#define ITIGHTLOOSE(ename) \ NFIND(ename); \ if (entry) { \ if (leaf == entry->leaf) { \ if (!leaf && !entry->tight && entry->next && \ entry->next->name == q && entry->next->tight && \ (bilevel || entry->next->hasloose) && \ EnumLTable((LTable)entry->next, names+1, classes+1, \ level, closure)) \ return True; \ if ((*get)(entry, names+1, classes+1, level, closure)) \ return True; \ if (entry->tight && (entry = entry->next) && \ entry->name == q && leaf == entry->leaf && \ (*get)(entry, names+1, classes+1, level, closure)) \ return True; \ } else if (entry->leaf) { \ if ((bilevel || entry->hasloose) && \ EnumLTable((LTable)entry, names+1, classes+1, level, closure))\ return True; \ if (entry->tight && (entry = entry->next) && \ entry->name == q && (bilevel || entry->hasloose) && \ EnumLTable((LTable)entry, names+1, classes+1, level, closure))\ return True; \ } \ }/* find entries named ename, leafness leaf, loose only, and call get */#define ILOOSE(ename) \ NFIND(ename); \ if (entry && entry->tight && (entry = entry->next) && entry->name != q) \ entry = (NTable)NULL; \ if (entry) { \ if (leaf == entry->leaf) { \ if ((*get)(entry, names+1, classes+1, level, closure)) \ return True; \ } else if (entry->leaf && (bilevel || entry->hasloose)) { \ if (EnumLTable((LTable)entry, names+1, classes+1, level, closure))\ return True; \ } \ } if (level >= MAXDBDEPTH) return False; closure->bindings[level] = (table->tight ? XrmBindTightly : XrmBindLoosely); closure->quarks[level] = table->name; level++; if (!*names) { if (EnumAllNTable(table, level, closure)) return True; } else { if (names[1] || closure->mode == XrmEnumAllLevels) { get = EnumNTable; /* recurse */ leaf = 0; bilevel = !names[1]; } else { get = EnumLTable; /* bottom of recursion */ leaf = 1; bilevel = False; } if (table->hasloose && closure->mode == XrmEnumAllLevels) { NTable *bucket; int i; XrmQuark empty = NULLQUARK; for (i = table->mask, bucket = NodeBuckets(table); i >= 0; i--, bucket++) { q = NULLQUARK; for (entry = *bucket; entry; entry = entry->next) { if (!entry->tight && entry->name != q && entry->name != *names && entry->name != *classes) { q = entry->name; if (entry->leaf) { if (EnumLTable((LTable)entry, &empty, &empty, level, closure)) return True; } else { if (EnumNTable(entry, &empty, &empty, level, closure)) return True; } } } } } ITIGHTLOOSE(*names); /* do name, tight and loose */ ITIGHTLOOSE(*classes); /* do class, tight and loose */ if (table->hasany) { ITIGHTLOOSE(XrmQANY); /* do ANY, tight and loose */ } if (table->hasloose) { while (1) { names++; classes++; if (!*names) break; if (!names[1] && closure->mode != XrmEnumAllLevels) { get = EnumLTable; /* bottom of recursion */ leaf = 1; } ILOOSE(*names); /* loose names */ ILOOSE(*classes); /* loose classes */ if (table->hasany) { ILOOSE(XrmQANY); /* loose ANY */ } } names--; classes--; } } /* now look for matching leaf nodes */ entry = table->next; if (!entry) return False; if (entry->leaf) { if (entry->tight && !table->tight) entry = entry->next; } else { entry = entry->next; if (!entry || !entry->tight) return False; } if (!entry || entry->name != table->name) return False; /* found one */ level--; if ((!*names || entry->hasloose) && EnumLTable((LTable)entry, names, classes, level, closure)) return True; if (entry->tight && entry == table->next && (entry = entry->next) && entry->name == table->name && (!*names || entry->hasloose)) return EnumLTable((LTable)entry, names, classes, level, closure); return False;#undef ITIGHTLOOSE#undef ILOOSE}/* call the proc for every value in the database, arbitrary order. * stop if the proc returns True. */Bool XrmEnumerateDatabase(db, names, classes, mode, proc, closure) XrmDatabase db; XrmNameList names; XrmClassList classes; int mode; DBEnumProc proc; XPointer closure;{ XrmBinding bindings[MAXDBDEPTH+2]; XrmQuark quarks[MAXDBDEPTH+2]; register NTable table; EClosureRec eclosure; if (!db) return False; eclosure.db = db; eclosure.proc = proc; eclosure.closure = closure; eclosure.bindings = bindings; eclosure.quarks = quarks; eclosure.mode = mode; table = db->table; if (table && !table->leaf && !*names && mode == XrmEnumOneLevel) table = table->next; if (table) { if (!table->leaf) return EnumNTable(table, names, classes, 0, &eclosure); else return EnumLTable((LTable)table, names, classes, 0, &eclosure); } return False;}static void PrintBindingQuarkList(bindings, quarks, stream) XrmBindingList bindings; XrmQuarkList quarks; FILE *stream;{ Bool firstNameSeen; for (firstNameSeen = False; *quarks; bindings++, quarks++) { if (*bindings == XrmBindLoosely) { (void) fprintf(stream, "*"); } else if (firstNameSeen) { (void) fprintf(stream, "."); } firstNameSeen = True; (void) fputs(XrmQuarkToString(*quarks), stream); }}/* output out the entry in correct file syntax *//*ARGSUSED*/static Bool DumpEntry(db, bindings, quarks, type, value, data) XrmDatabase *db; XrmBindingList bindings; XrmQuarkList quarks; XrmRepresentation *type; XrmValuePtr value; XPointer data;{ FILE *stream = (FILE *)data; register unsigned int i; register char *s; register char c; if (*type != XrmQString) (void) putc('!', stream); PrintBindingQuarkList(bindings, quarks, stream); s = value->addr; i = value->size; if (*type == XrmQString) { (void) fputs(":\t", stream); if (i) i--; } else fprintf(stream, "=%s:\t", XrmRepresentationToString(*type)); if (i && (*s == ' ' || *s == '\t')) (void) putc('\\', stream); /* preserve leading whitespace */ while (i--) { c = *s++; if (c == '\n') { if (i) (void) fputs("\\n\\\n", stream); else (void) fputs("\\n", stream); } else if (c == '\\') (void) fputs("\\\\", stream); else if ((c < ' ' && c != '\t') || ((unsigned char)c >= 0x7f && (unsigned char)c < 0xa0)) (void) fprintf(stream, "\\%03o", (unsigned char)c); else (void) putc(c, stream); } (void) putc('\n', stream); return False;}#ifdef DEBUGvoid PrintTable(table, file) NTable table; FILE *file;{ XrmBinding bindings[MAXDBDEPTH+1]; XrmQuark quarks[MAXDBDEPTH+1]; EClosureRec closure; XrmQuark empty = NULLQUARK; closure.db = (XrmDatabase)NULL; closure.proc = DumpEntry; closure.closure = (XPointer)file; closure.bindings = bindings; closure.quarks = quarks; closure.mode = XrmEnumAllLevels; if (table->leaf) EnumLTable((LTable)table, &empty, &empty, 0, &closure); else EnumNTable(table, &empty, &empty, 0, &closure);}#endif /* DEBUG */#if NeedFunctionPrototypesvoid XrmPutFileDatabase( XrmDatabase db, _Xconst char *fileName)#elsevoid XrmPutFileDatabase(db, fileName) XrmDatabase db; char *fileName;#endif{ FILE *file; XrmQuark empty = NULLQUARK; if (!db) return; if (!(file = fopen(fileName, "w"))) return; (void)XrmEnumerateDatabase(db, &empty, &empty, XrmEnumAllLevels, DumpEntry, (XPointer) file); fclose(file);}/* macros used in get/search functions *//* find entries named ename, leafness leaf, tight or loose, and call get */#define GTIGHTLOOSE(ename,looseleaf) \ NFIND(ename); \ if (entry) { \ if (leaf == entry->leaf) { \ if (!leaf && !entry->tight && entry->next && \ entry->next->name == q && entry->next->tight && \ entry->next->hasloose && \ looseleaf((LTable)entry->next, names+1, classes+1, closure)) \ return True; \ if ((*get)(entry, names+1, classes+1, closure)) \ return True; \ if (entry->tight && (entry = entry->next) && \ entry->name == q && leaf == entry->leaf && \ (*get)(entry, names+1, classes+1, closure)) \ return True; \ } else if (entry->leaf) { \ if (entry->hasloose && \ looseleaf((LTable)entry, names+1, classes+1, closure)) \ return True; \ if (entry->tight && (entry = entry->next) && \ entry->name == q && entry->hasloose && \ looseleaf((LTable)entry, names+1, classes+1, closure)) \ return True; \ } \ }/* find entries named ename, leafness leaf, loose only, and call get */#define GLOOSE(ename,looseleaf) \ NFIND(ename); \ if (entry && entry->tight && (entry = entry->next) && entry->name != q) \ entry = (NTable)NULL; \ if (entry) { \ if (leaf == entry->leaf) { \ if ((*get)(entry, names+1, classes+1, closure)) \ return True; \ } else if (entry->leaf && entry->hasloose) { \ if (looseleaf((LTable)entry, names+1, classes+1, closure)) \ return True; \ } \ }/* add tight/loose entry to the search list, return True if list is full */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -