📄 defaults.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)defaults.c 1.1 92/07/30";#endif#endif/* * Copyright (c) 1985, 1988 by Sun Microsystems, Inc. *//* * This file contains routines for reading in and accessing a defaults * database. Any errors are printed on the console as warning messeges. *//* * Overview of data structures: * * All of the relevent data structures are stored in a defaults object. * The defaults object contains two hash tables. The symbols hash table * is used to cannoncalize (sp?) strings. Every time a string (symbol) * is encountered, it is looked up in the symbols hash table to get a * unique pointer to a string. This means that two symbols can be tested * for equality by simply comparing their pointers. The second hash table * is the nodes hash table. The nodes hash table is indexed by a name, * where a name is a null-terminated list of symbol pointers * (i.e. ["CShell", "Path", "Help", NULL]). The nodes are threaded together * so that each node knows its parent, eldest child, and next youngest * sibling. In addition, each node has a name (i.e. the null-terminated * list of string pointers) and a string value. */#include <stdio.h> /* Standard I/O library */#include <pwd.h> /* Password file stuff */#include <sys/types.h> /* Get u_long defined for dir.h */#include <sys/dir.h> /* Directory access routines */#include <sys/stat.h> /* File status information */#include <sunwindow/sun.h> /* Define True, False, etc... */#include <sunwindow/hash.h> /* Hash table definitions */#include <sunwindow/parse.h> /* Parsing routine */#include <strings.h>#include <sunwindow/defaults.h>#include <sunwindow/defaults_impl.h>#define HUGE_STRING 10000 /* Huge strings for Warren Teitelman */#define getchr(fp) ((int)getc(fp)) /* Simplify character at a time debugging */#define ungetchr ungetc /* Simplify character at a time debugging *//* Use following instead of standard strdup to localize VM accesses */#define defaults_strdup(str) (strcpy(hash_get_memory((unsigned) strlen(str) + 1), str))typedef int (*INT_FUNC)();typedef char (*CHAR_FUNC)();/* Global variables: */Defaults defaults; /* = NULL; Global defaults object *//* Exported routine definitions. */#include <sunwindow/defaults.h> /* Defaults routines *//* * chr_digit(chr) returns True if CHr is a valid digit. */#define chr_digit(chr) ((Bool)(('0' <= chr) && (chr <= '9')))/* * chr_letter(chr) returns True if Chr is a valid letter. */#define chr_letter(chr) ((Bool)((' ' < chr) && (chr <= '~') && (chr != '/')))/* Internally used routines: */void clear_status();void defaults_create();long *get_data();char *getlogindir();void name_cat();Name name_copy();Bool name_equal();int name_hash();int name_parse();void name_quick_parse();char *name_unparse();Node node_create();void node_delete();void node_delete_private();Node node_find_name();Node node_lookup_name();Node node_lookup_path();Node path_lookup();Bool read();void read_lazy();void read_master();void read_master_database();void read_master_database1();void read_private_database();char *slash_append();Symbol symbol_copy();Bool symbol_equal();int symbol_hash();Symbol symbol_lookup();void warn();/* Externally used routines: */extern char *hash_get_memory();extern char *getlogin();extern char *getenv();extern struct passwd *getpwnam();extern struct passwd *getpwuid();extern char *malloc();/*****************************************************************//* Exported routines: *//*****************************************************************//* * NOTE: Any returned string pointers should be considered temporary at best. * If you want to hang onto the data, make your own private copy of the string! *//* * defaults_exists(path_name, status) will return TRUE if Path_Name exists * in the database. */Booldefaults_exists(path_name, status) char *path_name; /* Node name to test for existence */ int *status; /* Status flag */{ clear_status(status); return (Bool)(node_lookup_path(path_name, False, status) != NULL);}/* * defaults_get_boolean(path_name, default, status) will lookup Path_Name * in the defaults database and return TRUE if the value is "True", "Yes", * "On", "Enabled", "Set", "Activated", or "1". FALSE will be returned if * the value is "False", "No", "Off", "Disabled", "Reset", "Cleared", * "Deactivated", or "0". If the value is none of the above, a warning * message will be displayed and Default will be returned. */Booldefaults_get_boolean(path_name, default_bool, status) char *path_name; /* Path name */ Bool default_bool; /* Default value */ int *status; /* Status flag */{ static Defaults_pairs bools[] = { "True", (int)True, "False", (int)False, "Yes", (int)True, "No", (int)False, "On", (int)True, "Off", (int)False, "Enabled", (int)True, "Disabled", (int)False, "Set", (int)True, "Reset", (int)False, "Cleared", (int)False, "Activated", (int)True, "Deactivated", (int)False, "1", (int)True, "0", (int)False, NULL, -1, }; char *string_value; /* String value */ register Bool value; /* Value to return */ clear_status(status); string_value = defaults_get_string(path_name, (char *)NULL, status); if (string_value == NULL){ return default_bool; } value = (Bool)defaults_lookup(string_value, bools); if ((int)value == -1){ warn("%s is '%s'; which is an unrecognized boolean value", path_name, string_value); value = default_bool; }#ifdef TESTDEFAULTS if (defaults->database_dir && value != default_bool) { defaults->errors = 0; warn("%s: .d=%d .c=%d", path_name, value, default_bool); }#endif return value;}/* * defaults_get_character(path_name, default, status) will lookup Path_Name in * the defaults database and return the resulting character value. * Default will be returned if any error occurs. */intdefaults_get_character(path_name, default_character, status) char *path_name; /* Full database node path name */ char default_character; /* Default return value */ int *status; /* Status flag */{ Node node; /* Resulting node */ clear_status(status); node = path_lookup(path_name, status); if (node == NULL) return default_character; if (strlen(node->value) != 1){ warn("%s -- More than one character in character constant", path_name); return default_character; }#ifdef TESTDEFAULTS if (defaults->database_dir && node->value[0] != default_character) { defaults->errors = 0; warn("%s: .d=%c .c=%c", path_name, node->value[0], default_character); }#endif return node->value[0];}/* * defaults_get_child(path_name, status) will return a pointer to the simple * name assoicated with the first child of Path_Name. NULL will be returned, * if Path_Name does not exist or if Path_Name does not have a first child. */char *defaults_get_child(path_name, status) char *path_name; /* Full name of parent node */ int *status; /* Status flag */{ register Node node; /* Node from database */ clear_status(status); /* Find the node child. */ node = node_lookup_path(path_name, False, status); if (node == NULL) return NULL; node = node->child; while ((node != NULL) && (node->deleted)) node = node->next; return (node == NULL) ? NULL : node->name[name_length(node->name) - 1];}/* * defaults_get_default(path_name, default, status) will return the value * associated with Path_Name prior to being overridden by the clients private * database. Default is returned if any error occurs. */char *defaults_get_default(path_name, default_value, status) char *path_name; /* Full name of node */ char *default_value; /* Default node name */ int *status; /* Status flag */{ register Node node; /* Node from database */ clear_status(status); node = path_lookup(path_name, status); if (node == NULL) return default_value; return node->default_value;}/* * defaults_get_enum(path_name, pairs, status) will lookup the value associated * with Path_Name and scan the Pairs table and return the associated value. * If no match, can be found an error will be generated and the value * associated with last entry (i.e. the NULL entry) will be returned. See, * defaults_lookup(). */intdefaults_get_enum(path_name, pairs, status) char *path_name; /* Full database path name */ Defaults_pairs *pairs; /* Pairs table */ int *status; /* Status flag */{ return defaults_lookup(defaults_get_string(path_name, (char *)NULL, status), pairs);}/* * defaults_get_enumeration(path_name, default, status) will lookup * "Path_Name/VALUE(Path_Name)" in the defaults database and return the * resulting string value. Default will be returned if any error occurs. */char *defaults_get_enumeration(path_name, default_enumeration, status) char *path_name; /* Full database node name */ char *default_enumeration; /* Default enumerate name */ int *status; /* Status flag */{ register Node node; /* Resulting node */ char name[MAX_STRING]; /* Temporary name */ register char *name_pointer; /* Name pointer */ register Node temp_node; /* Temporary node */ clear_status(status); node = path_lookup(path_name, status); if (node == NULL) return default_enumeration; name_pointer = name; (void)strcpy(name_pointer, path_name); (void)strcat(name_pointer, SEP_STR); (void)strcat(name_pointer, "$Enumeration"); temp_node = node_lookup_path(name_pointer, True, status); if (temp_node == NULL){ warn("%s is not an enumeration type", path_name); return default_enumeration; } (void)strcpy(name_pointer, path_name); (void)strcat(name_pointer, SEP_STR); (void)strcat(name_pointer, node->value); temp_node = node_lookup_path(name_pointer, True, status); if (temp_node == NULL) { warn("%s is not a valid enumeration value for %s", node->value, path_name); return default_enumeration; }#ifdef TESTDEFAULTS if (defaults->database_dir && temp_node->value && default_enumeration && strcmp(temp_node->value, default_enumeration) != 0) { defaults->errors = 0; warn("%s: .d=%s .c=%s", path_name, temp_node->value, default_enumeration); }#endif return temp_node->value;}/* * defaults_get_integer(path_name, default, status) will lookup Path_Name in * the defaults database and return the resulting integer value. * Default will be returned if any error occurs. */intdefaults_get_integer(path_name, default_integer, status) char *path_name; /* Full database node name */ int default_integer; /* Default return value */ int *status; /* Status flag */{ register char chr; /* Temporary character */ Bool error; /* TRUE => an error has occurred */ Bool negative; /* TRUE => Negative number */ register Node node; /* Resulting node */ register int number; /* Resultant value */ register char *pointer; /* Pointer into value */ /* Lookup the node */ clear_status(status); node = path_lookup(path_name, status); if (node == NULL) return default_integer; /* Convert string into integer (with error chacking) */ error = False; pointer = node->value; negative = False; number = 0; chr = *pointer++; if (chr == '-'){ negative = True; chr = *pointer++; } if (chr == '\0') error = True; while (chr != '\0'){ if ((chr < '0') || (chr > '9')){ error = True; break; } number = number * 10 + chr - '0'; chr = *pointer++; } if (error){ warn("%s contains an incorrect integer", path_name); return default_integer; } if (negative) number = -number;#ifdef TESTDEFAULTS if (defaults->database_dir && number != default_integer) { defaults->errors = 0; warn("%s: .d=%d .c=%d", path_name, number, default_integer); }#endif return number;}/* * defaults_get_integer_check(path_name, default, mininum, maximum, status) * will lookup Path_Name in the defaults database and return the resulting * integer value. If the value in the database is not between Minimum and * Maximum (inclusive), an error message will be printed. Default will be * returned if any error occurs. */intdefaults_get_integer_check(path_name, default_int, minimum, maximum, status) char *path_name; /* Full path name of node */ int default_int; /* Default return value */ int minimum; /* Minimum value */ int maximum; /* Maximum value */ int *status; /* Status flag */{ int value; /* Return value */ clear_status(status); value = defaults_get_integer(path_name, default_int, status); if ((minimum <= value) && (value <= maximum)) return value; else { warn("The value of %s is %d which is not between %d and %d", path_name, value, minimum, maximum); return default_int; }}/* * defaults_get_sibling(path_name, status) will return a pointer to the simple * name assoicated with the next sibling of Path_Name. NULL will be returned, * if Path_Name does not exist or if Path_Name does not have an * next sibling. */char *defaults_get_sibling(path_name, status) char *path_name; /* Full name of parent node */ int *status; /* Status flag */{ register Node node; /* Node from database */ clear_status(status); node = node_lookup_path(path_name, False, status); if (node == NULL){ warn("Could not find '%s'", path_name); return NULL; } do node = node->next; while ((node != NULL) && node->deleted); return (node == NULL) ? NULL : node->name[name_length(node->name) - 1];}/* * defaults_get_string(path_name, default, status) will lookup and return the * string value assocatied with Path_Name in the defaults database. * Default will be returned if any error occurs. */char *defaults_get_string(path_name, default_string, status) char *path_name; /* Full database node name */ char *default_string; /* Default return value */ int *status; /* Status flag */{ register Node node; /* Resulting node */ clear_status(status); node = path_lookup(path_name, status);#ifdef TESTDEFAULTS if (defaults->database_dir && node != NULL && node->value && default_string && strcmp(node->value, default_string) != 0) { defaults->errors = 0; warn("%s: .d=%s .c=%s", path_name, node->value, default_string); }#endif return (node == NULL) ? default_string : node->value;}/* * initializes (reads in) the defaults database. defaults_init() will read in * the user's private database, i.e., .defaults file, and then read in the * master database as well if the value of /Defaults/Read_Defaults_Database * is True. defaults_init(True) will read in the master database regardless. */voiddefaults_init(read_defaults_database) int read_defaults_database;{ if (defaults == NULL){ defaults_create();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -