📄 xrm.c
字号:
* doall - whether to do all lines or just one *//* * This function is highly optimized to inline as much as possible. * Be very careful with modifications, or simplifications, as they * may adversely affect the performance. * * Chris Peterson, MIT X Consortium 5/17/90. */#define LIST_SIZE 101#define BUFFER_SIZE 100static void GetIncludeFile();static void GetDatabase(db, str, filename, doall) XrmDatabase db; register char *str; char *filename; Bool doall;{ register char *ptr; register XrmBits bits = 0; register char c; int len; register Signature sig; register char *ptr_max; register XrmQuarkList t_quarks; register XrmBindingList t_bindings; int alloc_chars = BUFSIZ; char buffer[BUFSIZ], *value_str; XrmQuark quarks[LIST_SIZE]; XrmBinding bindings[LIST_SIZE]; XrmValue value; Bool only_pcs; Bool dolines; if (!db) return; if (!(value_str = Xmalloc(sizeof(char) * alloc_chars))) return; (*db->methods->mbinit)(db->mbstate); str--; dolines = True; while (!is_EOF(bits) && dolines) { dolines = doall; /* * First: Remove extra whitespace. */ do { bits = next_char(c, str); } while is_space(bits); /* * Ignore empty lines. */ if (is_EOL(bits)) continue; /* start a new line. */ /* * Second: check the first character in a line to see if it is * "!" signifying a comment, or "#" signifying a directive. */ if (c == '!') { /* Comment, spin to next newline */ while (is_simple(bits = next_char(c, str))) {} if (is_EOL(bits)) continue; while (!is_EOL(bits = next_mbchar(c, len, str))) {} str--; continue; /* start a new line. */ } if (c == '#') { /* Directive */ /* remove extra whitespace */ only_pcs = True; while (is_space(bits = next_char(c, str))) {}; /* only "include" directive is currently defined */ if (!strncmp(str, "include", 7)) { str += (7-1); /* remove extra whitespace */ while (is_space(bits = next_char(c, str))) {}; /* must have a starting " */ if (c == '"') { char *fname = str+1; len = 0; do { if (only_pcs) { bits = next_char(c, str); if (is_nonpcs(bits)) only_pcs = False; } if (!only_pcs) bits = next_mbchar(c, len, str); } while (c != '"' && !is_EOL(bits)); /* must have an ending " */ if (c == '"') GetIncludeFile(db, filename, fname, str - len - fname); } } /* spin to next newline */ if (only_pcs) { while (is_simple(bits)) bits = next_char(c, str); if (is_EOL(bits)) continue; } while (!is_EOL(bits)) bits = next_mbchar(c, len, str); str--; continue; /* start a new line. */ } /* * Third: loop through the LHS of the resource specification * storing characters and converting this to a Quark. * * If the number of quarks is greater than LIST_SIZE - 1. This * function will trash your memory. * * If the length of any quark is larger than BUFSIZ this function * will also trash memory. */ t_bindings = bindings; t_quarks = quarks; sig = 0; ptr = buffer; *t_bindings = XrmBindTightly; for(;;) { if (!is_binding(bits)) { while (!is_EOQ(bits)) { *ptr++ = c; sig = (sig << 1) + c; /* Compute the signature. */ bits = next_char(c, str); } *t_quarks++ = _XrmInternalStringToQuark(buffer, ptr - buffer, sig, False); if (is_separator(bits)) { if (!is_space(bits)) break; /* Remove white space */ do { *ptr++ = c; sig = (sig << 1) + c; /* Compute the signature. */ } while (is_space(bits = next_char(c, str))); /* * The spec doesn't permit it, but support spaces * internal to resource name/class */ if (is_separator(bits)) break; t_quarks--; continue; } if (c == '.') *(++t_bindings) = XrmBindTightly; else *(++t_bindings) = XrmBindLoosely; sig = 0; ptr = buffer; } else { /* * Magic unspecified feature #254. * * If two separators appear with no Text between them then * ignore them. * * If anyone of those separators is a '*' then the binding * will be loose, otherwise it will be tight. */ if (c == '*') *t_bindings = XrmBindLoosely; } bits = next_char(c, str); } *t_quarks = NULLQUARK; /* * Make sure that there is a ':' in this line. */ if (c != ':') { char oldc; /* * A parsing error has occured, toss everything on the line * a new_line can still be escaped with a '\'. */ while (is_normal(bits)) bits = next_char(c, str); if (is_EOL(bits)) continue; bits = next_mbchar(c, len, str); do { oldc = c; bits = next_mbchar(c, len, str); } while (c && (c != '\n' || oldc == '\\')); str--; continue; } /* * I now have a quark and binding list for the entire left hand * side. "c" currently points to the ":" separating the left hand * side for the right hand side. It is time to begin processing * the right hand side. */ /* * Fourth: Remove more whitespace */ for(;;) { if (is_space(bits = next_char(c, str))) continue; if (c != '\\') break; bits = next_char(c, str); if (c == '\n') continue; str--; bits = BSLASH; c = '\\'; break; } /* * Fifth: Process the right hand side. */ ptr = value_str; ptr_max = ptr + alloc_chars - 4; only_pcs = True; len = 1; for(;;) { /* * Tight loop for the normal case: Non backslash, non-end of value * character that will fit into the allocated buffer. */ if (only_pcs) { while (is_normal(bits) && ptr < ptr_max) { *ptr++ = c; bits = next_char(c, str); } if (is_EOL(bits)) break; if (is_nonpcs(bits)) { only_pcs = False; bits = next_mbchar(c, len, str); } } while (!is_special(bits) && ptr + len <= ptr_max) { len = -len; while (len) *ptr++ = str[len++]; bits = next_mbchar(c, len, str); } if (is_EOL(bits)) { str--; break; } if (c == '\\') { /* * We need to do some magic after a backslash. */ if (only_pcs) { bits = next_char(c, str); if (is_nonpcs(bits)) only_pcs = False; } if (!only_pcs) bits = next_mbchar(c, len, str); if (is_EOL(bits)) { if (is_EOF(bits)) continue; } else if (c == 'n') { /* * "\n" means insert a newline. */ *ptr++ = '\n'; } else if (c == '\\') { /* * "\\" completes to just one backslash. */ *ptr++ = '\\'; } else { /* * pick up to three octal digits after the '\'. */ char temp[3]; int count = 0; while (is_odigit(bits) && count < 3) { temp[count++] = c; if (only_pcs) { bits = next_char(c, str); if (is_nonpcs(bits)) only_pcs = False; } if (!only_pcs) bits = next_mbchar(c, len, str); } /* * If we found three digits then insert that octal code * into the value string as a character. */ if (count == 3) { *ptr++ = (unsigned char) ((temp[0] - '0') * 0100 + (temp[1] - '0') * 010 + (temp[2] - '0')); } else { int tcount; /* * Otherwise just insert those characters into the * string, since no special processing is needed on * numerics we can skip the special processing. */ for (tcount = 0; tcount < count; tcount++) { *ptr++ = temp[tcount]; /* print them in the correct order */ } } continue; } if (only_pcs) { bits = next_char(c, str); if (is_nonpcs(bits)) only_pcs = False; } if (!only_pcs) bits = next_mbchar(c, len, str); } /* * It is important to make sure that there is room for at least * four more characters in the buffer, since I can add that * many characters into the buffer after a backslash has occured. */ if (ptr + len > ptr_max) { char * temp_str; alloc_chars += BUFSIZ/10; temp_str = Xrealloc(value_str, sizeof(char) * alloc_chars); if (!temp_str) { Xfree(value_str); (*db->methods->mbfinish)(db->mbstate); return; } ptr = temp_str + (ptr - value_str); /* reset pointer. */ value_str = temp_str; ptr_max = value_str + alloc_chars - 4; } } /* * Lastly: Terminate the value string, and store this entry * into the database. */ *ptr++ = '\0'; /* Store it in database */ value.size = ptr - value_str; value.addr = (XPointer) value_str; PutEntry(db, bindings, quarks, XrmQString, &value); } Xfree(value_str); (*db->methods->mbfinish)(db->mbstate);}#if NeedFunctionPrototypesvoid XrmPutStringResource( XrmDatabase *pdb, _Xconst char*specifier, _Xconst char*str)#elsevoid XrmPutStringResource(pdb, specifier, str) XrmDatabase *pdb; char *specifier; char *str;#endif{ XrmValue value; XrmBinding bindings[MAXDBDEPTH+1]; XrmQuark quarks[MAXDBDEPTH+1]; if (!*pdb) *pdb = NewDatabase(); XrmStringToBindingQuarkList(specifier, bindings, quarks); value.addr = (XPointer) str; value.size = strlen(str)+1; PutEntry(*pdb, bindings, quarks, XrmQString, &value);}#if NeedFunctionPrototypesvoid XrmPutLineResource( XrmDatabase *pdb, _Xconst char*line)#elsevoid XrmPutLineResource(pdb, line) XrmDatabase *pdb; char *line;#endif{ if (!*pdb) *pdb = NewDatabase(); GetDatabase(*pdb, line, (char *)NULL, False);}#if NeedFunctionPrototypesXrmDatabase XrmGetStringDatabase( _Xconst char *data)#elseXrmDatabase XrmGetStringDatabase(data) char *data;#endif{ XrmDatabase db; db = NewDatabase(); GetDatabase(db, data, (char *)NULL, True); return db;}/* Function Name: ReadInFile * Description: Reads the file into a buffer. * Arguments: filename - the name of the file. * Returns: An allocated string containing the contents of the file. */static char *ReadInFile(filename)char * filename;{ register int fd, size; char * filebuf; if ( (fd = OpenFile(filename)) == -1 ) return (char *)NULL; GetSizeOfFile(filename, size); if (!(filebuf = Xmalloc(size + 1))) { /* leave room for '\0' */ close(fd); return (char *)NULL; } if (ReadFile(fd, filebuf, size) != size) { /* If we didn't read the correct number of bytes. */ CloseFile(fd); Xfree(filebuf); return (char *)NULL; } CloseFile(fd); filebuf[size] = '\0'; /* NULL terminate it. */ return filebuf;}static voidGetIncludeFile(db, base, fname, fnamelen) XrmDatabase db; char *base; char *fname; int fnamelen;{ int len;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -