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

📄 history.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
		    {		      i++;		      substitute_globally = 1;		      goto substitute;		    }		  else		    		case 's':		  substitute:		  {		    char *this, *that, *new_event;		    int delimiter = 0;		    int si, l_this, l_that, l_temp = strlen (temp);		    if (i + 2 < strlen (string))		      delimiter = string[i + 2];		    if (!delimiter)		      break;		    i += 3;		    /* Get THIS. */		    for (si = i; string[si] && string[si] != delimiter; si++);		    l_this = (si - i);		    this = (char *)alloca (1 + l_this);		    strncpy (this, string + i, l_this);		    this[l_this] = '\0';		    i = si;		    if (string[si])		      i++;		    /* Get THAT. */		    for (si = i; string[si] && string[si] != delimiter; si++);		    l_that = (si - i);		    that = (char *)alloca (1 + l_that);		    strncpy (that, string + i, l_that);		    that[l_that] = '\0';		    i = si;		    if (string[si]) i++;		    /* Ignore impossible cases. */		    if (l_this > l_temp)		      goto cant_substitute;		    /* Find the first occurrence of THIS in TEMP. */		    si = 0;		    for (; (si + l_this) <= l_temp; si++)		      if (strncmp (temp + si, this, l_this) == 0)			{			  new_event =			    (char *)alloca (1 + (l_that - l_this) + l_temp);			  strncpy (new_event, temp, si);			  strncpy (new_event + si, that, l_that);			  strncpy (new_event + si + l_that,				   temp + si + l_this,				   l_temp - (si + l_this));			  new_event[(l_that - l_this) + l_temp] = '\0';			  temp = new_event;			  if (substitute_globally)			    {			      si += l_that;			      l_temp = strlen (temp);			      substitute_globally++;			      continue;			    }			  goto hack_specials;			}		  cant_substitute:		    if (substitute_globally > 1)		      {			substitute_globally = 0;			goto hack_specials;		      }		    goto event_not_found;		  }		  /* :# is the line so far.  Note that we have to		     alloca () it since RESULT could be realloc ()'ed		     below in add_string. */		case '#':		hack_pound_sign:		  if (result)		    {		      temp = (char *)alloca (1 + strlen (result));		      strcpy (temp, result);		    }		  else		    temp = "";		next_special:		  i += 2;		  goto hack_specials;		}	    }	  /* Believe it or not, we have to back the pointer up by one. */	  --i;	  goto add_string;	  /* A regular character.  Just add it to the output string. */	default:	add_char:	  tt[0] = string[i];	  temp = tt;	  goto do_add;	add_string:	  modified++;	do_add:	  j += strlen (temp);	  while (j > len)	    result = (char *)xrealloc (result, (len += 255));	  strcpy (result + (j - strlen (temp)), temp);	}    }  *output = result;  if (only_printing)    {      add_history (result);      return (-1);    }  return (modified != 0);}/* Return a consed string which is the word specified in SPEC, and found   in FROM.  NULL is returned if there is no spec.  -1 is returned if   the word specified cannot be found.  CALLER_INDEX is the offset in   SPEC to start looking; it is updated to point to just after the last   character parsed. */char *get_history_word_specifier (spec, from, caller_index)     char *spec, *from;     int *caller_index;{  register int i = *caller_index;  int first, last;  int expecting_word_spec = 0;  char *history_arg_extract ();  /* The range of words to return doesn't exist yet. */  first = last = 0;  /* If we found a colon, then this *must* be a word specification.  If     it isn't, then it is an error. */  if (spec[i] == ':')    i++, expecting_word_spec++;  /* Handle special cases first. */  /* `%' is the word last searched for. */  if (spec[i] == '%')    {      *caller_index = i + 1;      if (search_string)	return (savestring (search_string));      else	return (savestring (""));    }  /* `*' matches all of the arguments, but not the command. */  if (spec[i] == '*')    {      char *star_result;      *caller_index = i + 1;      star_result = history_arg_extract (1, '$', from);      if (!star_result)	star_result = savestring ("");      return (star_result);    }  /* `$' is last arg. */  if (spec[i] == '$')    {      *caller_index = i + 1;      return (history_arg_extract ('$', '$', from));    }  /* Try to get FIRST and LAST figured out. */  if (spec[i] == '-' || spec[i] == '^')    {      first = 1;      goto get_last;    } get_first:  if (digit (spec[i]) && expecting_word_spec)    {      sscanf (spec + i, "%d", &first);      for (; digit (spec[i]); i++);    }  else    return ((char *)NULL); get_last:  if (spec[i] == '^')    {      i++;      last = 1;      goto get_args;    }  if (spec[i] != '-')    {      last = first;      goto get_args;    }  i++;  if (digit (spec[i]))    {      sscanf (spec + i, "%d", &last);      for (; digit (spec[i]); i++);    }  else    if (spec[i] == '$')      {	i++;	last = '$';      } get_args:  {    char *result = (char *)NULL;    *caller_index = i;    if (last >= first)      result = history_arg_extract (first, last, from);    if (result)      return (result);    else      return ((char *)-1);  }}/* Extract the args specified, starting at FIRST, and ending at LAST.   The args are taken from STRING.  If either FIRST or LAST is < 0,   then make that arg count from the right (subtract from the number of   tokens, so that FIRST = -1 means the next to last token on the line). */char *history_arg_extract (first, last, string)     int first, last;     char *string;{  register int i, len;  char *result = (char *)NULL;  int size = 0, offset = 0;  char **history_tokenize (), **list;  if (!(list = history_tokenize (string)))    return ((char *)NULL);  for (len = 0; list[len]; len++);  if (last < 0)    last = len + last - 1;  if (first < 0)    first = len + first - 1;  if (last == '$')    last = len - 1;  if (first == '$')    first = len - 1;  last++;  if (first > len || last > len || first < 0 || last < 0)    result = ((char *)NULL);  else    {      for (i = first; i < last; i++)	{	  int l = strlen (list[i]);	  if (!result)	    result = (char *)xmalloc ((size = (2 + l)));	  else	    result = (char *)xrealloc (result, (size += (2 + l)));	  strcpy (result + offset, list[i]);	  offset += l;	  if (i + 1 < last)	    {	      strcpy (result + offset, " ");	      offset++;	    }	}    }  for (i = 0; i < len; i++)    free (list[i]);  free (list);  return (result);}#define slashify_in_quotes "\\`\"$"/* Return an array of tokens, much as the shell might.  The tokens are   parsed out of STRING. */char **history_tokenize (string)     char *string;{  char **result = (char **)NULL;  register int i, start, result_index, size;  int len;  i = result_index = size = 0;  /* Get a token, and stuff it into RESULT.  The tokens are split     exactly where the shell would split them. */ get_token:  /* Skip leading whitespace. */  for (; string[i] && whitespace(string[i]); i++);  start = i;  if (!string[i] || string[i] == history_comment_char)    return (result);  if (member (string[i], "()\n")) {    i++;    goto got_token;  }  if (member (string[i], "<>;&|")) {    int peek = string[i + 1];    if (peek == string[i]) {      if (peek ==  '<') {	if (string[1 + 2] == '-')	  i++;	i += 2;	goto got_token;      }      if (member (peek, ">:&|")) {	i += 2;	goto got_token;      }    } else {      if ((peek == '&' &&	  (string[i] == '>' || string[i] == '<')) ||	  ((peek == '>') &&	  (string[i] == '&'))) {	i += 2;	goto got_token;      }    }    i++;    goto got_token;  }  /* Get word from string + i; */  {    int delimiter = 0;    if (member (string[i], "\"'`"))      delimiter = string[i++];    for (;string[i]; i++) {      if (string[i] == '\\') {	if (string[i + 1] == '\n') {	  i++;	  continue;	} else {	  if (delimiter != '\'')	    if ((delimiter != '"') ||		(member (string[i], slashify_in_quotes))) {	      i++;	      continue;	    }	}      }      if (delimiter && string[i] == delimiter) {	delimiter = 0;	continue;      }      if (!delimiter && (member (string[i], " \t\n;&()|<>")))	goto got_token;      if (!delimiter && member (string[i], "\"'`")) {	delimiter = string[i];	continue;      }    }    got_token:    len = i - start;    if (result_index + 2 >= size) {      if (!size)	result = (char **)xmalloc ((size = 10) * (sizeof (char *)));      else	result =	  (char **)xrealloc (result, ((size += 10) * (sizeof (char *))));    }    result[result_index] = (char *)xmalloc (1 + len);    strncpy (result[result_index], string + start, len);    result[result_index][len] = '\0';    result_index++;    result[result_index] = (char *)NULL;  }  if (string[i])    goto get_token;  return (result);}#if defined (STATIC_MALLOC)/* **************************************************************** *//*								    *//*			xmalloc and xrealloc ()		     	    *//*								    *//* **************************************************************** */static void memory_error_and_abort ();static char *xmalloc (bytes)     int bytes;{  char *temp = (char *)malloc (bytes);  if (!temp)    memory_error_and_abort ();  return (temp);}static char *xrealloc (pointer, bytes)     char *pointer;     int bytes;{  char *temp;  if (!pointer)    temp = (char *)xmalloc (bytes);  else    temp = (char *)realloc (pointer, bytes);  if (!temp)    memory_error_and_abort ();  return (temp);}static voidmemory_error_and_abort (){  fprintf (stderr, "history: Out of virtual memory!\n");  abort ();}#endif /* STATIC_MALLOC *//* **************************************************************** *//*								    *//*				Test Code			    *//*								    *//* **************************************************************** */#ifdef TESTmain (){  char line[1024], *t;  int done = 0;  line[0] = 0;  while (!done)    {      fprintf (stdout, "history%% ");      t = gets (line);      if (!t)	strcpy (line, "quit");      if (line[0])	{	  char *expansion;	  int result;	  using_history ();	  result = history_expand (line, &expansion);	  strcpy (line, expansion);	  free (expansion);	  if (result)	    fprintf (stderr, "%s\n", line);	  if (result < 0)	    continue;	  add_history (line);	}      if (strcmp (line, "quit") == 0) done = 1;      if (strcmp (line, "save") == 0) write_history (0);      if (strcmp (line, "read") == 0) read_history (0);      if (strcmp (line, "list") == 0)	{	  register HIST_ENTRY **the_list = history_list ();	  register int i;	  if (the_list)	    for (i = 0; the_list[i]; i++)	      fprintf (stdout, "%d: %s\n", i + history_base, the_list[i]->line);	}      if (strncmp (line, "delete", strlen ("delete")) == 0)	{	  int which;	  if ((sscanf (line + strlen ("delete"), "%d", &which)) == 1)	    {	      HIST_ENTRY *entry = remove_history (which);	      if (!entry)		fprintf (stderr, "No such entry %d\n", which);	      else		{		  free (entry->line);		  free (entry);		}	    }	  else	    {	      fprintf (stderr, "non-numeric arg given to `delete'\n");	    }	}    }}#endif				/* TEST *//** Local variables:* compile-command: "gcc -g -DTEST -o history history.c"* end:*/

⌨️ 快捷键说明

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