亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? history.c

?? Linux下的MUD客戶端程序
?? C
?? 第 1 頁 / 共 4 頁
字號:
read_history (filename)     char *filename;{  return (read_history_range (filename, 0, -1));}/* Read a range of lines from FILENAME, adding them to the history list.   Start reading at the FROM'th line and end at the TO'th.  If FROM   is zero, start at the beginning.  If TO is less than FROM, read   until the end of the file.  If FILENAME is NULL, then read from   ~/.history.  Returns 0 if successful, or errno if not. */intread_history_range (filename, from, to)     char *filename;     int from, to;{  register int line_start, line_end;  char *input, *buffer = (char *)NULL;  int file, current_line;  struct stat finfo;  input = history_filename (filename);  file = open (input, O_RDONLY, 0666);  if ((file < 0) || (fstat (file, &finfo) == -1))    goto error_and_exit;  buffer = xmalloc ((int)finfo.st_size + 1);  if (read (file, buffer, finfo.st_size) != finfo.st_size)    {  error_and_exit:      if (file >= 0)	close (file);      if (input)	free (input);      if (buffer)	free (buffer);      return (errno);    }  close (file);  /* Set TO to larger than end of file if negative. */  if (to < 0)    to = finfo.st_size;  /* Start at beginning of file, work to end. */  line_start = line_end = current_line = 0;  /* Skip lines until we are at FROM. */  while (line_start < finfo.st_size && current_line < from)    {      for (line_end = line_start; line_end < finfo.st_size; line_end++)	if (buffer[line_end] == '\n')	  {	    current_line++;	    line_start = line_end + 1;	    if (current_line == from)	      break;	  }    }  /* If there are lines left to gobble, then gobble them now. */  for (line_end = line_start; line_end < finfo.st_size; line_end++)    if (buffer[line_end] == '\n')      {	buffer[line_end] = '\0';	if (buffer[line_start])	  add_history (buffer + line_start);	current_line++;	if (current_line >= to)	  break;	line_start = line_end + 1;      }  if (input)    free (input);  if (buffer)    free (buffer);  return (0);}/* Truncate the history file FNAME, leaving only LINES trailing lines.   If FNAME is NULL, then use ~/.history. */inthistory_truncate_file (fname, lines)     char *fname;     register int lines;{  register int i;  int file, chars_read;  char *buffer = (char *)NULL, *filename;  struct stat finfo;  filename = history_filename (fname);  file = open (filename, O_RDONLY, 0666);  if (file == -1 || fstat (file, &finfo) == -1)    goto truncate_exit;  buffer = xmalloc ((int)finfo.st_size + 1);  chars_read = read (file, buffer, finfo.st_size);  close (file);  if (chars_read <= 0)    goto truncate_exit;  /* Count backwards from the end of buffer until we have passed     LINES lines. */  for (i = chars_read - 1; lines && i; i--)    {      if (buffer[i] == '\n')	lines--;    }  /* If this is the first line, then the file contains exactly the     number of lines we want to truncate to, so we don't need to do     anything.  It's the first line if we don't find a newline between     the current value of i and 0.  Otherwise, write from the start of     this line until the end of the buffer. */  for ( ; i; i--)    if (buffer[i] == '\n')      {	i++;	break;      }  /* Write only if there are more lines in the file than we want to     truncate to. */  if (i && ((file = open (filename, O_WRONLY|O_TRUNC, 0666)) != -1))    {      write (file, buffer + i, finfo.st_size - i);      close (file);    } truncate_exit:  if (buffer)    free (buffer);  free (filename);  return 0;}#define HISTORY_APPEND 0#define HISTORY_OVERWRITE 1/* Workhorse function for writing history.  Writes NELEMENT entries   from the history list to FILENAME.  OVERWRITE is non-zero if you   wish to replace FILENAME with the entries. */static inthistory_do_write (filename, nelements, overwrite)     char *filename;     int nelements, overwrite;{  register int i;  char *output = history_filename (filename);  int file, mode;  mode = overwrite ? O_WRONLY | O_CREAT | O_TRUNC : O_WRONLY | O_APPEND;  if ((file = open (output, mode, 0666)) == -1)    {      if (output)	free (output);      return (errno);    }  if (nelements > history_length)    nelements = history_length;  /* Build a buffer of all the lines to write, and write them in one syscall.     Suggested by Peter Ho (peter@robosts.oxford.ac.uk). */  {    register int j = 0;    int buffer_size = 0;    char *buffer;    /* Calculate the total number of bytes to write. */    for (i = history_length - nelements; i < history_length; i++)      buffer_size += 1 + strlen (the_history[i]->line);    /* Allocate the buffer, and fill it. */    buffer = xmalloc (buffer_size);    for (i = history_length - nelements; i < history_length; i++)      {	strcpy (buffer + j, the_history[i]->line);	j += strlen (the_history[i]->line);	buffer[j++] = '\n';      }    write (file, buffer, buffer_size);    free (buffer);  }  close (file);  if (output)    free (output);  return (0);}/* Append NELEMENT entries to FILENAME.  The entries appended are from   the end of the list minus NELEMENTs up to the end of the list. */intappend_history (nelements, filename)     int nelements;     char *filename;{  return (history_do_write (filename, nelements, HISTORY_APPEND));}/* Overwrite FILENAME with the current history.  If FILENAME is NULL,   then write the history list to ~/.history.  Values returned   are as in read_history ().*/intwrite_history (filename)     char *filename;{  return (history_do_write (filename, history_length, HISTORY_OVERWRITE));}/* Return the history entry at the current position, as determined by   history_offset.  If there is no entry there, return a NULL pointer. */HIST_ENTRY *current_history (){  if ((history_offset == history_length) || !the_history)    return ((HIST_ENTRY *)NULL);  else    return (the_history[history_offset]);}/* Back up history_offset to the previous history entry, and return   a pointer to that entry.  If there is no previous entry then return   a NULL pointer. */HIST_ENTRY *previous_history (){  if (!history_offset)    return ((HIST_ENTRY *)NULL);  else    return (the_history[--history_offset]);}/* Move history_offset forward to the next history entry, and return   a pointer to that entry.  If there is no next entry then return a   NULL pointer. */HIST_ENTRY *next_history (){  if (history_offset == history_length)    return ((HIST_ENTRY *)NULL);  else    return (the_history[++history_offset]);}/* Return the current history array.  The caller has to be carefull, since this   is the actual array of data, and could be bashed or made corrupt easily.   The array is terminated with a NULL pointer. */HIST_ENTRY **history_list (){  return (the_history);}/* Return the history entry which is logically at OFFSET in the history array.   OFFSET is relative to history_base. */HIST_ENTRY *history_get (offset)     int offset;{  int local_index = offset - history_base;  if (local_index >= history_length ||      local_index < 0 ||      !the_history)    return ((HIST_ENTRY *)NULL);  return (the_history[local_index]);}/* Search for STRING in the history list.  DIR is < 0 for searching   backwards.  POS is an absolute index into the history list at   which point to begin searching. */inthistory_search_pos (string, dir, pos)     char *string;     int dir, pos;{  int ret, old = where_history ();  history_set_pos (pos);  if (history_search (string, dir) == -1)    {      history_set_pos (old);      return (-1);    }  ret = where_history ();  history_set_pos (old);  return ret;}/* Make the current history item be the one at POS, an absolute index.   Returns zero if POS is out of range, else non-zero. */inthistory_set_pos (pos)     int pos;{  if (pos > history_length || pos < 0 || !the_history)    return (0);  history_offset = pos;  return (1);} /* **************************************************************** *//*								    *//*			History Expansion			    *//*								    *//* **************************************************************** *//* Hairy history expansion on text, not tokens.  This is of general   use, and thus belongs in this library. *//* The last string searched for in a !?string? search. */static char *search_string = (char *)NULL;/* Return the event specified at TEXT + OFFSET modifying OFFSET to   point to after the event specifier.  Just a pointer to the history   line is returned; NULL is returned in the event of a bad specifier.   You pass STRING with *INDEX equal to the history_expansion_char that   begins this specification.   DELIMITING_QUOTE is a character that is allowed to end the string   specification for what to search for in addition to the normal   characters `:', ` ', `\t', `\n', and sometimes `?'.   So you might call this function like:   line = get_history_event ("!echo:p", &index, 0);  */char *get_history_event (string, caller_index, delimiting_quote)     char *string;     int *caller_index;     int delimiting_quote;{  register int i = *caller_index;  register char c;  HIST_ENTRY *entry;  int which, sign = 1;  int local_index, search_mode, substring_okay = 0;  char *temp;  /* The event can be specified in a number of ways.     !!   the previous command     !n   command line N     !-n  current command-line minus N     !str the most recent command starting with STR     !?str[?]	  the most recent command containing STR     All values N are determined via HISTORY_BASE. */  if (string[i] != history_expansion_char)    return ((char *)NULL);  /* Move on to the specification. */  i++;#define RETURN_ENTRY(e, w) \	return ((e = history_get (w)) ? e->line : (char *)NULL)  /* Handle !! case. */  if (string[i] == history_expansion_char)    {      i++;      which = history_base + (history_length - 1);      *caller_index = i;      RETURN_ENTRY (entry, which);    }  /* Hack case of numeric line specification. */  if (string[i] == '-')    {      sign = -1;      i++;    }  if (digit_p (string[i]))    {      /* Get the extent of the digits and compute the value. */      for (which = 0; digit_p (string[i]); i++)	which = (which * 10) + digit_value (string[i]);      *caller_index = i;      if (sign < 0)	which = (history_length + history_base) - which;      RETURN_ENTRY (entry, which);    }  /* This must be something to search for.  If the spec begins with     a '?', then the string may be anywhere on the line.  Otherwise,     the string must be found at the start of a line. */  if (string[i] == '?')    {      substring_okay++;      i++;    }  /* Only a closing `?' or a newline delimit a substring search string. */  for (local_index = i; c = string[i]; i++)    if ((!substring_okay && (whitespace (c) || c == ':' ||#if defined (SHELL)	  member (c, ";&()|<>") ||#endif /* SHELL */	  string[i] == delimiting_quote)) ||	string[i] == '\n' ||	(substring_okay && string[i] == '?'))      break;  temp = xmalloc (1 + (i - local_index));  strncpy (temp, &string[local_index], (i - local_index));  temp[i - local_index] = '\0';  if (substring_okay && string[i] == '?')    i++;  *caller_index = i;#define FAIL_SEARCH() \  do { history_offset = history_length; free (temp) ; return (char *)NULL; } while (0)  search_mode = substring_okay ? NON_ANCHORED_SEARCH : ANCHORED_SEARCH;  while (1)    {      local_index = history_search_internal (temp, -1, search_mode);      if (local_index < 0)	FAIL_SEARCH ();      if (local_index == 0 || substring_okay)	{	  entry = current_history ();	  history_offset = history_length;		  /* If this was a substring search, then remember the	     string that we matched for word substitution. */	  if (substring_okay)	    {	      if (search_string)		free (search_string);	      search_string = temp;	    }	  else	    free (temp);	  return (entry->line);	}      if (history_offset)	history_offset--;      else	FAIL_SEARCH ();    }#undef FAIL_SEARCH#undef RETURN_ENTRY}#if defined (SHELL)/* Function for extracting single-quoted strings.  Used for inhibiting   history expansion within single quotes. *//* Extract the contents of STRING as if it is enclosed in single quotes.   SINDEX, when passed in, is the offset of the character immediately   following the opening single quote; on exit, SINDEX is left pointing   to the closing single quote. */static voidrl_string_extract_single_quoted (string, sindex)     char *string;     int *sindex;{  register int i = *sindex;  while (string[i] && string[i] != '\'')    i++;  *sindex = i;}static char *quote_breaks (s)     char *s;{  register char *p, *r;  char *ret;  int len = 3;  for (p = s; p && *p; p++, len++)    {      if (*p == '\'')	len += 3;      else if (whitespace (*p) || *p == '\n')	len += 2;    }  r = ret = xmalloc (len);  *r++ = '\'';  for (p = s; p && *p; )    {      if (*p == '\'')	{	  *r++ = '\'';	  *r++ = '\\';	  *r++ = '\'';	  *r++ = '\'';	  p++;	}      else if (whitespace (*p) || *p == '\n')	{	  *r++ = '\'';	  *r++ = *p++;	  *r++ = '\'';	}      else	*r++ = *p++;    }  *r++ = '\'';  *r = '\0';  return ret;}#endif /* SHELL */static char *hist_error(s, start, current, errtype)

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲精品一二三| 国产精品美女久久久久久2018| 欧美日韩国产免费| 日韩精品一区二区三区在线播放| 久久久久成人黄色影片| 亚洲精品乱码久久久久久日本蜜臀| 国产电影精品久久禁18| 欧美午夜精品久久久久久孕妇| 日韩女同互慰一区二区| 奇米色一区二区三区四区| 91小视频在线免费看| 欧美一级日韩一级| 亚洲人成电影网站色mp4| 老司机午夜精品99久久| 色哟哟国产精品| 欧美精品一区二区三区很污很色的 | 欧美日韩一区 二区 三区 久久精品| 精品精品欲导航| 亚洲乱码国产乱码精品精可以看| 成人午夜在线免费| 欧美成人女星排行榜| 麻豆久久久久久| 欧美日韩国产免费一区二区| 日韩 欧美一区二区三区| 色av成人天堂桃色av| 日本一区二区高清| 麻豆精品久久久| 久久精品一区四区| 国内一区二区在线| 欧美一级一区二区| 国产aⅴ精品一区二区三区色成熟| 日韩精品一区二区在线观看| 国产做a爰片久久毛片| 中文字幕av一区二区三区| 色一情一乱一乱一91av| 日本欧美一区二区在线观看| 久久久久久久久久电影| 97se狠狠狠综合亚洲狠狠| 国产精品人成在线观看免费| 91麻豆福利精品推荐| 免费在线看成人av| 国产欧美日韩在线观看| 丰满白嫩尤物一区二区| 亚洲黄色小说网站| 欧美大片一区二区三区| 成人av资源站| 亚洲色图欧洲色图婷婷| 色综合久久中文综合久久97| 日本怡春院一区二区| 国产精品不卡视频| 色悠悠亚洲一区二区| 日本伊人午夜精品| 亚洲人成网站精品片在线观看| 69成人精品免费视频| 日韩精品欧美成人高清一区二区| 欧美亚洲一区二区三区四区| 久久精品国产999大香线蕉| 国产精品国产成人国产三级| 91精品国产综合久久福利| 国产九色sp调教91| 亚洲欧美在线视频观看| 欧美在线视频不卡| 日韩av在线播放中文字幕| 中文字幕在线观看一区| 欧美一区二区三区人| 日本韩国一区二区三区视频| 国产乱人伦偷精品视频不卡| 亚洲成在人线在线播放| 日韩一二在线观看| 国产a久久麻豆| 日韩成人伦理电影在线观看| 18涩涩午夜精品.www| 国产亚洲一本大道中文在线| 欧美裸体bbwbbwbbw| 国产精品一区一区| 蜜臀av在线播放一区二区三区| 一区二区成人在线观看| 精品盗摄一区二区三区| 欧美另类一区二区三区| 欧美在线|欧美| 波多野结衣中文字幕一区二区三区| 麻豆成人免费电影| 日日夜夜一区二区| 午夜精品福利视频网站| 久久精品视频免费观看| 精品久久久久久久人人人人传媒 | 久久精品国产免费| 偷拍一区二区三区| 亚洲妇女屁股眼交7| 国产女主播一区| 久久女同互慰一区二区三区| 日韩三级.com| 欧美一级日韩免费不卡| 欧美一级日韩不卡播放免费| 日韩一区二区在线看片| 91精品婷婷国产综合久久竹菊| 精品视频一区二区不卡| 欧美三级电影在线看| 欧美日韩亚洲综合一区| 欧美高清激情brazzers| 欧美日本一道本| 在线播放国产精品二区一二区四区 | 色综合久久久久| 一本色道久久综合亚洲精品按摩 | 国产精品不卡一区二区三区| 国产精品每日更新| 亚洲天堂成人在线观看| 亚洲男人电影天堂| 亚洲一区二区三区小说| 国产日韩欧美精品综合| 中文字幕电影一区| 亚洲免费资源在线播放| 亚洲在线中文字幕| 日本va欧美va精品| 韩国精品在线观看| 豆国产96在线|亚洲| 91麻豆精品一区二区三区| 欧美色图天堂网| 日韩一区二区三区精品视频| 久久久久久久一区| 专区另类欧美日韩| 五月婷婷久久丁香| 精品一区二区在线免费观看| 日韩av午夜在线观看| 国产一区二区三区在线观看精品| 视频一区免费在线观看| 久久99国产精品久久99果冻传媒| 国产成人午夜99999| 色哟哟国产精品免费观看| 日韩一区二区电影| 国产精品国产三级国产aⅴ入口| 亚洲综合丁香婷婷六月香| 美国av一区二区| 成人激情黄色小说| 5566中文字幕一区二区电影| 久久久精品2019中文字幕之3| 亚洲人成亚洲人成在线观看图片| 日韩主播视频在线| 丁香婷婷综合色啪| 欧美剧情电影在线观看完整版免费励志电影 | 亚洲免费视频成人| 国产精品一区二区久久不卡| 色综合久久久久久久| 欧美一区二区三区电影| 亚洲欧洲99久久| 久久aⅴ国产欧美74aaa| 色狠狠色狠狠综合| 久久久不卡网国产精品二区| 亚洲高清三级视频| jlzzjlzz欧美大全| 色哟哟在线观看一区二区三区| 日韩亚洲欧美一区| 一区二区三区中文字幕| 国产91丝袜在线播放0| 精品视频在线看| 综合久久久久久| 韩国视频一区二区| 欧美肥大bbwbbw高潮| 亚洲男人电影天堂| 成人一区二区三区视频在线观看| 日韩视频免费观看高清完整版 | 久久精品国产99国产精品| 91福利社在线观看| 日本一区二区三区在线观看| 日韩av在线播放中文字幕| 色狠狠综合天天综合综合| 欧美韩国一区二区| 国产一区二区在线影院| 91精品国产综合久久精品| 亚洲最大成人综合| 91亚洲精品久久久蜜桃| 亚洲国产精品激情在线观看| 久久精品国产澳门| 日韩欧美国产一区在线观看| 亚洲福利一区二区三区| 91传媒视频在线播放| 国产精品大尺度| 国产盗摄一区二区三区| 26uuu精品一区二区在线观看| 国产精品国产三级国产| 懂色av一区二区在线播放| 亚洲成人一二三| 欧美三级电影在线观看| 亚洲成人动漫在线免费观看| 在线观看免费成人| 一区二区三区免费网站| 一本在线高清不卡dvd| 亚洲欧美色图小说| 色婷婷久久综合| 亚洲色图制服丝袜| 色av综合在线| 亚洲国产欧美日韩另类综合| 91成人在线精品| 亚洲二区在线观看| 欧美美女一区二区在线观看| 视频一区二区三区中文字幕| 欧美久久免费观看| 麻豆一区二区三区| 久久综合九色综合欧美98| 国产一区二区网址|