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

📄 history.c

📁 xorp源码hg
💻 C
📖 第 1 页 / 共 4 页
字号:
 *  dim     size_t    The allocated dimensions of the line buffer. * Output: *  return    char *  The line requested, or NULL if no matching line *                    was found. */char *_glh_find_forwards(GlHistory *glh, char *line, size_t dim){  GlLineNode *node; /* The line location node being checked *//* * Check the arguments. */  if(!glh || !line) {    fprintf(stderr, "_glh_find_forwards: NULL argument(s).\n");    return NULL;  };/* * Is history enabled? */  if(!glh->enable || !glh->buffer || glh->max_lines == 0)    return NULL;/* * Check the line dimensions. */  if(dim < strlen(line) + 1) {    fprintf(stderr,       "_glh_find_forwards: 'dim' inconsistent with strlen(line) contents.\n");    return NULL;  };/* * From where should we start the search? */  if(glh->recall)    node = glh->recall->next;  else    return NULL;/* * If there is no search prefix, the prefix last set by glh_search_prefix() * doesn't exist in the history buffer. */  if(!glh->prefix)    return NULL;/* * Search forwards through the list for the first match with the * prefix string. */  for( ; node &&      (node->group != glh->group ||       strncmp(glh->buffer + node->start, glh->prefix, glh->prefix_len) != 0);      node = node->next)    ;/* * Was a matching line found? */  if(node) {/* * Did we hit the line that was originally being edited when the * current history traversal started? */    if(node == glh->list.tail)      return _glh_restore_line(glh, line, dim);/* * Copy the matching line into the provided line buffer. */    strncpy(line, glh->buffer + node->start, dim);    line[dim-1] = '\0';/* * Record the starting point of the next search. */    glh->recall = node;/* * Return the matching line to the user. */    return line;  };/* * No match was found. */  return NULL;}/*....................................................................... * If a search is in progress, cancel it. * * This involves discarding the line that was temporarily saved by * _glh_find_backwards() when the search was originally started, * and reseting the search iteration pointer to NULL. * * Input: *  glh  GlHistory *  The input-line history maintenance object. * Output: *  return     int    0 - OK. *                    1 - Error. */int _glh_cancel_search(GlHistory *glh){/* * Check the arguments. */  if(!glh) {    fprintf(stderr, "_glh_cancel_search: NULL argument(s).\n");    return 1;  };/* * If there wasn't a search in progress, do nothing. */  if(!glh->recall)    return 0;/* * Delete the node of the preserved line. */  _glh_discard_node(glh, glh->list.tail);/* * Reset the search pointers. */  glh->recall = NULL;  glh->prefix = "";  glh->prefix_len = 0;  return 0;}/*....................................................................... * Set the prefix of subsequent history searches. * * Input: *  glh  GlHistory *  The input-line history maintenance object. *  line      char *  The command line who's prefix is to be used. *  prefix_len int    The length of the prefix. * Output: *  return     int    0 - OK. *                    1 - Error. */int _glh_search_prefix(GlHistory *glh, const char *line, int prefix_len){  GlLineNode *node; /* The line location node being checked *//* * Check the arguments. */  if(!glh) {    fprintf(stderr, "_glh_search_prefix: NULL argument(s).\n");    return 1;  };/* * Is history enabled? */  if(!glh->enable || !glh->buffer || glh->max_lines == 0)    return 0;/* * Record a zero length search prefix? */  if(prefix_len <= 0) {    glh->prefix_len = 0;    glh->prefix = "";    return 0;  };/* * Record the length of the new search prefix. */  glh->prefix_len = prefix_len;/* * If any history line starts with the specified prefix, record a * pointer to it for comparison in subsequent searches. If the prefix * doesn't match any of the lines, then simply record NULL to indicate * that there is no point in searching. Note that _glh_add_history() * clears this pointer by calling _glh_cancel_search(), so there is * no danger of it being used after the buffer has been modified. */  for(node = glh->list.tail ; node &&      (node->group != glh->group ||       strncmp(glh->buffer + node->start, line, prefix_len) != 0);      node = node->prev)    ;/* * If a matching line was found record it for use as the search * prefix. */  glh->prefix = node ? glh->buffer + node->start : NULL;  return 0;}/*....................................................................... * Recall the oldest recorded line. * * Input: *  glh  GlHistory *  The input-line history maintenance object. *  line      char *  The input line buffer. On input this should contain *                    the current input line, and on output, its contents *                    will have been replaced with the oldest line. *  dim     size_t    The allocated dimensions of the line buffer. * Output: *  return    char *  A pointer to line[0], or NULL if not found. */char *_glh_oldest_line(GlHistory *glh, char *line, size_t dim){  GlLineNode *node; /* The line location node being checked */  int first;        /* True if this is the start of a new search *//* * Check the arguments. */  if(!glh || !line) {    fprintf(stderr, "_glh_oldest_line: NULL argument(s).\n");    return NULL;  };/* * Is history enabled? */  if(!glh->enable || !glh->buffer || glh->max_lines == 0)    return NULL;/* * Check the line dimensions. */  if(dim < strlen(line) + 1) {    fprintf(stderr,       "_glh_oldest_line: 'dim' inconsistent with strlen(line) contents.\n");    return NULL;  };/* * Is this the start of a new search? */  first = glh->recall==NULL;/* * If this is the first search backwards, save the current line * for potential recall later, and mark it as the last line * recalled. */  if(first) {    if(_glh_add_history(glh, line, 1))      return NULL;    glh->recall = glh->list.tail;  };/* * Locate the oldest line that belongs to the current group. */  for(node=glh->list.head; node && node->group != glh->group;       node = node->next)    ;/* * No line found? */  if(!node)    return NULL;/* * Record the above node as the starting point for subsequent * searches. */  glh->recall = node;/* * Copy the recalled line into the provided line buffer. */  strncpy(line, glh->buffer + node->start, dim);  line[dim-1] = '\0';  return line;}/*....................................................................... * Recall the line that was being entered when the search started. * * Input: *  glh  GlHistory *  The input-line history maintenance object. *  line      char *  The input line buffer. On input this should contain *                    the current input line, and on output, its contents *                    will have been replaced with the line that was *                    being entered when the search was started. *  dim     size_t    The allocated dimensions of the line buffer. * Output: *  return    char *  A pointer to line[0], or NULL if not found. */char *_glh_current_line(GlHistory *glh, char *line, size_t dim){/* * Check the arguments. */  if(!glh || !line) {    fprintf(stderr, "_glh_current_line: NULL argument(s).\n");    return NULL;  };/* * Is history enabled? */  if(!glh->enable || !glh->buffer || glh->max_lines == 0)    return NULL;/* * Check the line dimensions. */  if(dim < strlen(line) + 1) {    fprintf(stderr,       "_glh_current_line: 'dim' inconsistent with strlen(line) contents.\n");    return NULL;  };/* * Restore the original line. */  return _glh_restore_line(glh, line, dim);}/*....................................................................... * Remove the line that was originally being edited when the history * traversal was started, from its saved position in the history list, * and place it in the provided line buffer. * * Input: *  glh  GlHistory *  The input-line history maintenance object. *  line      char *  The input line buffer. On input this should contain *                    the current input line, and on output, its contents *                    will have been replaced with the saved line. *  dim     size_t    The allocated dimensions of the line buffer. * Output: *  return    char *  A pointer to line[0], or NULL if not found. */static char *_glh_restore_line(GlHistory *glh, char *line, size_t dim){  GlLineNode *tail;   /* The tail node to be discarded *//* * If there wasn't a search in progress, do nothing. */  if(!glh->recall)    return NULL;/* * Get the list node that is to be removed. */  tail = glh->list.tail;/* * If a pointer to the saved line is being used to record the * current search prefix, reestablish the search prefix, to * have it recorded by another history line if possible. */  if(glh->prefix == glh->buffer + tail->start)    (void) _glh_search_prefix(glh, glh->buffer + tail->start, glh->prefix_len);/* * Copy the recalled line into the input-line buffer. */  strncpy(line, glh->buffer + tail->start, dim);  line[dim-1] = '\0';/* * Discard the line-location node. */  _glh_discard_node(glh, tail);/* * Mark the search as ended. */  glh->recall = NULL;  return line;}/*....................................................................... * Query the id of a history line offset by a given number of lines from * the one that is currently being recalled. If a recall session isn't * in progress, or the offset points outside the history list, 0 is * returned. * * Input: *  glh    GlHistory *  The input-line history maintenance object. *  offset       int    The line offset (0 for the current line, < 0 *                      for an older line, > 0 for a newer line. * Output: *  return GlhLineID    The identifier of the line that is currently *                      being recalled, or 0 if no recall session is *                      currently in progress. */GlhLineID _glh_line_id(GlHistory *glh, int offset){  GlLineNode *node; /* The line location node being checked *//* * Is history enabled? */  if(!glh->enable || !glh->buffer || glh->max_lines == 0)    return 0;/* * Search forward 'offset' lines to find the required line. */  if(offset >= 0) {    for(node=glh->recall; node && offset != 0; node=node->next) {      if(node->group == glh->group)	offset--;    };  } else {    for(node=glh->recall; node && offset != 0; node=node->prev) {      if(node->group == glh->group)	offset++;    };  };  return node ? node->id : 0;}/*....................................................................... * Recall a line by its history buffer ID. If the line is no longer * in the buffer, or the id is zero, NULL is returned. * * Input: *  glh  GlHistory *  The input-line history maintenance object. *  id   GlhLineID    The ID of the line to be returned. *  line      char *  The input line buffer. On input this should contain *                    the current input line, and on output, its contents *                    will have been replaced with the saved line. *  dim     size_t    The allocated dimensions of the line buffer. * Output: *  return    char *  A pointer to line[0], or NULL if not found. */char *_glh_recall_line(GlHistory *glh, GlhLineID id, char *line, size_t dim){  GlLineNode *node; /* The line location node being checked *//* * Is history enabled? */  if(!glh->enable || !glh->buffer || glh->max_lines == 0)    return NULL;/* * If we are starting a new recall session, save the current line * for potential recall later. */  if(!glh->recall && _glh_add_history(glh, line, 1))    return NULL;/* * Search for the specified line. */  node = _glh_find_id(glh, id);/* * Not found? */  if(!node || node->group != glh->group)    return NULL;/* * Record the node of the matching line as the starting point * for subsequent searches. */  glh->recall = node;/* * Copy the recalled line into the provided line buffer. */  strncpy(line, glh->buffer + node->start, dim);  line[dim-1] = '\0';  return line;}/*....................................................................... * Save the current history in a specified file. * * Input: *  glh        GlHistory *  The input-line history maintenance object. *  filename  const char *  The name of the new file to record the *                          history in. *  comment   const char *  Extra information such as timestamps will *                          be recorded on a line started with this *                          string, the idea being that the file can *                          double as a command file. Specify "" if *                          you don't care. *  max_lines        int    The maximum number of lines to save, or -1 *                          to save all of the lines in the history *                          list. * Output: *  return           int    0 - OK. *                          1 - Error. */int _glh_save_history(GlHistory *glh, const char *filename, const char *comment,		      int max_lines){  FILE *fp;         /* The output file */  GlLineNode *node; /* The line being saved */  GlLineNode *head; /* The head of the list of lines to be saved *//* * Check the arguments. */  if(!glh || !filename || !comment) {    fprintf(stderr, "_glh_save_history: NULL argument(s).\n");    return 1;  };/* * Attempt to open the specified file. */  fp = fopen(filename, "w");  if(!fp) {    fprintf(stderr, "_glh_save_history: Can't open %s (%s).\n",	    filename, strerror(errno));    return 1;  };/* * If a ceiling on the number of lines to save was specified, count * that number of lines backwards, to find the first line to be saved. */  head = NULL;  if(max_lines >= 0) {    for(head=glh->list.tail; head && --max_lines > 0; head=head->prev)      ;  };  if(!head)    head = glh->list.head;/* * Write the contents of the history buffer to the history file, writing * associated data such as timestamps, to a line starting with the * specified comment string. */  for(node=head; node; node=node->next) {/* * Write peripheral information associated with the line, as a comment. */    if(fprintf(fp, "%s ", comment) < 0 ||       _glh_write_timestamp(fp, node->timestamp) ||       fprintf(fp, " %u\n", node->group) < 0) {      fprintf(stderr, "Error writing %s (%s).\n", filename, strerror(errno));      (void) fclose(fp);      return 1;    };

⌨️ 快捷键说明

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