⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bind.c

📁 Linux下的MUD客户端程序
💻 C
📖 第 1 页 / 共 3 页
字号:
  buffer = (char *)xmalloc ((int)finfo.st_size + 1);  i = read (file, buffer, finfo.st_size);  close (file);  if (i != finfo.st_size)    return (errno);  /* Loop over the lines in the file.  Lines that start with `#' are     comments; all other lines are commands for readline initialization. */  line = buffer;  end = buffer + finfo.st_size;  while (line < end)    {      /* Find the end of this line. */      for (i = 0; line + i != end && line[i] != '\n'; i++);      /* Mark end of line. */      line[i] = '\0';      /* Skip leading whitespace. */      while (*line && whitespace (*line))        {	  line++;	  i--;        }      /* If the line is not a comment, then parse it. */      if (*line && *line != '#')	rl_parse_and_bind (line);      /* Move to the next line. */      line += i + 1;    }  free (buffer);  return (0);}/* **************************************************************** *//*								    *//*			Parser Directives       		    *//*								    *//* **************************************************************** *//* Conditionals. *//* Calling programs set this to have their argv[0]. */char *rl_readline_name = "other";/* Stack of previous values of parsing_conditionalized_out. */static unsigned char *if_stack = (unsigned char *)NULL;static int if_stack_depth = 0;static int if_stack_size = 0;/* Push _rl_parsing_conditionalized_out, and set parser state based   on ARGS. */static intparser_if (args)     char *args;{  register int i;  /* Push parser state. */  if (if_stack_depth + 1 >= if_stack_size)    {      if (!if_stack)	if_stack = (unsigned char *)xmalloc (if_stack_size = 20);      else	if_stack = (unsigned char *)xrealloc (if_stack, if_stack_size += 20);    }  if_stack[if_stack_depth++] = _rl_parsing_conditionalized_out;  /* If parsing is turned off, then nothing can turn it back on except     for finding the matching endif.  In that case, return right now. */  if (_rl_parsing_conditionalized_out)    return 0;  /* Isolate first argument. */  for (i = 0; args[i] && !whitespace (args[i]); i++);  if (args[i])    args[i++] = '\0';  /* Handle "if term=foo" and "if mode=emacs" constructs.  If this     isn't term=foo, or mode=emacs, then check to see if the first     word in ARGS is the same as the value stored in rl_readline_name. */  if (rl_terminal_name && strnicmp (args, "term=", 5) == 0)    {      char *tem, *tname;      /* Terminals like "aaa-60" are equivalent to "aaa". */      tname = savestring (rl_terminal_name);      tem = strchr (tname, '-');      if (tem)	*tem = '\0';      /* Test the `long' and `short' forms of the terminal name so that	 if someone has a `sun-cmd' and does not want to have bindings	 that will be executed if the terminal is a `sun', they can put	 `$if term=sun-cmd' into their .inputrc. */      if ((stricmp (args + 5, tname) == 0) ||	  (stricmp (args + 5, rl_terminal_name) == 0))	_rl_parsing_conditionalized_out = 0;      else	_rl_parsing_conditionalized_out = 1;      free (tname);    }#if defined (VI_MODE)  else if (strnicmp (args, "mode=", 5) == 0)    {      int mode;      if (stricmp (args + 5, "emacs") == 0)	mode = emacs_mode;      else if (stricmp (args + 5, "vi") == 0)	mode = vi_mode;      else	mode = no_mode;      if (mode == rl_editing_mode)	_rl_parsing_conditionalized_out = 0;      else	_rl_parsing_conditionalized_out = 1;    }#endif /* VI_MODE */  /* Check to see if the first word in ARGS is the same as the     value stored in rl_readline_name. */  else if (stricmp (args, rl_readline_name) == 0)    _rl_parsing_conditionalized_out = 0;  else    _rl_parsing_conditionalized_out = 1;  return 0;}/* Invert the current parser state if there is anything on the stack. */static intparser_else (args)     char *args;{  register int i;  if (!if_stack_depth)    {      /* Error message? */      return 0;    }  /* Check the previous (n - 1) levels of the stack to make sure that     we haven't previously turned off parsing. */  for (i = 0; i < if_stack_depth - 1; i++)    if (if_stack[i] == 1)      return 0;  /* Invert the state of parsing if at top level. */  _rl_parsing_conditionalized_out = !_rl_parsing_conditionalized_out;  return 0;}/* Terminate a conditional, popping the value of   _rl_parsing_conditionalized_out from the stack. */static intparser_endif (args)     char *args;{  if (if_stack_depth)    _rl_parsing_conditionalized_out = if_stack[--if_stack_depth];  else    {      /* *** What, no error message? *** */    }  return 0;}/* Associate textual names with actual functions. */static struct {  char *name;  Function *function;} parser_directives [] = {  { "if", parser_if },  { "endif", parser_endif },  { "else", parser_else },  { (char *)0x0, (Function *)0x0 }};/* Handle a parser directive.  STATEMENT is the line of the directive   without any leading `$'. */static inthandle_parser_directive (statement)     char *statement;{  register int i;  char *directive, *args;  /* Isolate the actual directive. */  /* Skip whitespace. */  for (i = 0; whitespace (statement[i]); i++);  directive = &statement[i];  for (; statement[i] && !whitespace (statement[i]); i++);  if (statement[i])    statement[i++] = '\0';  for (; statement[i] && whitespace (statement[i]); i++);  args = &statement[i];  /* Lookup the command, and act on it. */  for (i = 0; parser_directives[i].name; i++)    if (stricmp (directive, parser_directives[i].name) == 0)      {	(*parser_directives[i].function) (args);	return (0);      }  /* *** Should an error message be output? */  return (1);}static int substring_member_of_array ();/* Read the binding command from STRING and perform it.   A key binding command looks like: Keyname: function-name\0,   a variable binding command looks like: set variable value.   A new-style keybinding looks like "\C-x\C-x": exchange-point-and-mark. */rl_parse_and_bind (string)     char *string;{  char *funname, *kname;  register int c, i;  int key, equivalency;  while (string && whitespace (*string))    string++;  if (!string || !*string || *string == '#')    return 0;  /* If this is a parser directive, act on it. */  if (*string == '$')    {      handle_parser_directive (&string[1]);      return 0;    }  /* If we aren't supposed to be parsing right now, then we're done. */  if (_rl_parsing_conditionalized_out)    return 0;  i = 0;  /* If this keyname is a complex key expression surrounded by quotes,     advance to after the matching close quote.  This code allows the     backslash to quote characters in the key expression. */  if (*string == '"')    {      int passc = 0;      for (i = 1; c = string[i]; i++)	{	  if (passc)	    {	      passc = 0;	      continue;	    }	  if (c == '\\')	    {	      passc++;	      continue;	    }	  if (c == '"')	    break;	}    }  /* Advance to the colon (:) or whitespace which separates the two objects. */  for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ );  equivalency = (c == ':' && string[i + 1] == '=');  /* Mark the end of the command (or keyname). */  if (string[i])    string[i++] = '\0';  /* If doing assignment, skip the '=' sign as well. */  if (equivalency)    string[i++] = '\0';  /* If this is a command to set a variable, then do that. */  if (stricmp (string, "set") == 0)    {      char *var = string + i;      char *value;      /* Make VAR point to start of variable name. */      while (*var && whitespace (*var)) var++;      /* Make value point to start of value string. */      value = var;      while (*value && !whitespace (*value)) value++;      if (*value)	*value++ = '\0';      while (*value && whitespace (*value)) value++;      rl_variable_bind (var, value);      return 0;    }  /* Skip any whitespace between keyname and funname. */  for (; string[i] && whitespace (string[i]); i++);  funname = &string[i];  /* Now isolate funname.     For straight function names just look for whitespace, since     that will signify the end of the string.  But this could be a     macro definition.  In that case, the string is quoted, so skip     to the matching delimiter.  We allow the backslash to quote the     delimiter characters in the macro body. */  /* This code exists to allow whitespace in macro expansions, which     would otherwise be gobbled up by the next `for' loop.*/  /* XXX - it may be desirable to allow backslash quoting only if " is     the quoted string delimiter, like the shell. */  if (*funname == '\'' || *funname == '"')    {      int delimiter = string[i++];      int passc = 0;      for (; c = string[i]; i++)	{	  if (passc)	    {	      passc = 0;	      continue;	    }	  if (c == '\\')	    {	      passc = 1;	      continue;	    }	  if (c == delimiter)	    break;	}      if (c)	i++;    }  /* Advance to the end of the string.  */  for (; string[i] && !whitespace (string[i]); i++);  /* No extra whitespace at the end of the string. */  string[i] = '\0';  /* Handle equivalency bindings here.  Make the left-hand side be exactly     whatever the right-hand evaluates to, including keymaps. */  if (equivalency)    {      return 0;    }  /* If this is a new-style key-binding, then do the binding with     rl_set_key ().  Otherwise, let the older code deal with it. */  if (*string == '"')    {      char *seq = xmalloc (1 + strlen (string));      register int j, k = 0;      int passc = 0;      for (j = 1; string[j]; j++)	{	  /* Allow backslash to quote characters, but leave them in place.	     This allows a string to end with a backslash quoting another	     backslash, or with a backslash quoting a double quote.  The	     backslashes are left in place for rl_translate_keyseq (). */	  if (passc || (string[j] == '\\'))	    {	      seq[k++] = string[j];	      passc = !passc;	      continue;	    }	  if (string[j] == '"')	    break;	  seq[k++] = string[j];	}      seq[k] = '\0';      /* Binding macro? */      if (*funname == '\'' || *funname == '"')	{	  j = strlen (funname);	  /* Remove the delimiting quotes from each end of FUNNAME. */	  if (j && funname[j - 1] == *funname)	    funname[j - 1] = '\0';	  rl_macro_bind (seq, &funname[1], _rl_keymap);	}      else	rl_set_key (seq, rl_named_function (funname), _rl_keymap);      free (seq);      return 0;    }  /* Get the actual character we want to deal with. */  kname = strrchr (string, '-');  if (!kname)    kname = string;  else    kname++;  key = glean_key_from_name (kname);  /* Add in control and meta bits. */  if (substring_member_of_array (string, possible_control_prefixes))    key = CTRL (to_upper (key));  if (substring_member_of_array (string, possible_meta_prefixes))    key = META (key);  /* Temporary.  Handle old-style keyname with macro-binding. */  if (*funname == '\'' || *funname == '"')    {      char seq[2];      int fl = strlen (funname);      seq[0] = key; seq[1] = '\0';      if (fl && funname[fl - 1] == *funname)	funname[fl - 1] = '\0';      rl_macro_bind (seq, &funname[1], _rl_keymap);    }#if defined (PREFIX_META_HACK)  /* Ugly, but working hack to keep prefix-meta around. */  else if (stricmp (funname, "prefix-meta") == 0)    {      char seq[2];      seq[0] = key;      seq[1] = '\0';      rl_generic_bind (ISKMAP, seq, (char *)emacs_meta_keymap, _rl_keymap);    }#endif /* PREFIX_META_HACK */  else    rl_bind_key (key, rl_named_function (funname));  return 0;}/* Simple structure for boolean readline variables (i.e., those that can   have one of two values; either "On" or 1 for truth, or "Off" or 0 for   false. */static struct {  char *name;  int *value;} boolean_varlist [] = {  { "horizontal-scroll-mode",	&_rl_horizontal_scroll_mode },  { "mark-modified-lines",	&_rl_mark_modified_lines },  { "meta-flag",		&_rl_meta_flag },#if defined (PAREN_MATCHING)  { "blink-matching-paren",	&rl_blink_matching_paren },#endif  { "convert-meta",		&_rl_convert_meta_chars_to_ascii },  { "show-all-if-ambiguous",	&_rl_complete_show_all },  { "output-meta",		&_rl_output_meta_chars },#if defined (VISIBLE_STATS)  { "visible-stats",		&rl_visible_stats },#endif /* VISIBLE_STATS */  { "expand-tilde",		&rl_complete_with_tilde_expansion },  { (char *)NULL, (int *)NULL }};rl_variable_bind (name, value)     char *name, *value;{  register int i;  /* Check for simple variables first. */  for (i = 0; boolean_varlist[i].name; i++)    {      if (stricmp (name, boolean_varlist[i].name) == 0)	{	  /* A variable is TRUE if the "value" is "on", "1" or "". */	  if ((!*value) ||	      (stricmp (value, "On") == 0) ||	      (value[0] == '1' && value[1] == '\0'))	    *boolean_varlist[i].value = 1;	  else	    *boolean_varlist[i].value = 0;	  return 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -