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

📄 nodes.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 3 页
字号:
        free (containing_dir);      }      /* For each node in the file's tags table, remember the starting         position. */      for (tags_index = 0; (entry = file_buffer->tags[tags_index]);           tags_index++)        {          for (i = 0;               subfiles[i] && entry->nodestart >= subfiles[i]->first_byte;               i++);          /* If the Info file containing the indirect tags table is             malformed, then give up. */          if (!i)            {              /* The Info file containing the indirect tags table is                 malformed.  Give up. */              for (i = 0; subfiles[i]; i++)                {                  free (subfiles[i]->filename);                  free (subfiles[i]);                  free (file_buffer->subfiles[i]);                }              file_buffer->subfiles = (char **)NULL;              free_file_buffer_tags (file_buffer);              return;            }          /* SUBFILES[i] is the index of the first subfile whose logical             first byte is greater than the logical offset of this node's             starting position.  This means that the subfile directly             preceding this one is the one containing the node. */          entry->filename = file_buffer->subfiles[i - 1];          entry->nodestart -= subfiles[i -1]->first_byte;          entry->nodestart += header_length;          entry->nodelen = -1;        }      /* We have successfully built the tags table.  Remember that it         was indirect. */      file_buffer->flags |= N_TagsIndirect;    }  /* Free the structures assigned to SUBFILES.  Free the names as well     as the structures themselves, then finally, the array. */  for (i = 0; subfiles[i]; i++)    {      free (subfiles[i]->filename);      free (subfiles[i]);    }  free (subfiles);}/* Return the node from FILE_BUFFER which matches NODENAME by searching   the tags table in FILE_BUFFER.  If the node could not be found, return   a NULL pointer. */static NODE *info_node_of_file_buffer_tags (file_buffer, nodename)     FILE_BUFFER *file_buffer;     char *nodename;{  register int i;  TAG *tag;  for (i = 0; (tag = file_buffer->tags[i]); i++)    if (strcmp (nodename, tag->nodename) == 0)      {        FILE_BUFFER *subfile;        subfile = info_find_file_internal (tag->filename, INFO_NO_TAGS);        if (!subfile)          return ((NODE *)NULL);        if (!subfile->contents)          {            info_reload_file_buffer_contents (subfile);            if (!subfile->contents)              return ((NODE *)NULL);          }        /* If we were able to find this file and load it, then return           the node within it. */        {          NODE *node;          node = (NODE *)xmalloc (sizeof (NODE));          node->filename = (subfile->fullpath);          node->nodename = tag->nodename;          node->contents = subfile->contents + tag->nodestart;          node->flags    = 0;          node->parent   = (char *)NULL;          if (file_buffer->flags & N_HasTagsTable)            {              node->flags |= N_HasTagsTable;              if (file_buffer->flags & N_TagsIndirect)                {                  node->flags |= N_TagsIndirect;                  node->parent = file_buffer->fullpath;                }            }          if (subfile->flags & N_IsCompressed)            node->flags |= N_IsCompressed;          /* If TAG->nodelen hasn't been calculated yet, then we aren't             in a position to trust the entry pointer.  Adjust things so             that ENTRY->nodestart gets the exact address of the start of             the node separator which starts this node, and NODE->contents             gets the address of the line defining this node.  If we cannot             do that, the node isn't really here. */          if (tag->nodelen == -1)            {              int min, max;              char *node_sep;              SEARCH_BINDING node_body;              char *buff_end;              min = max = DEFAULT_INFO_FUDGE;              if (tag->nodestart < DEFAULT_INFO_FUDGE)                min = tag->nodestart;              if (DEFAULT_INFO_FUDGE >                  (subfile->filesize - tag->nodestart))                max = subfile->filesize - tag->nodestart;              /* NODE_SEP gets the address of the separator which defines                 this node, or (char *)NULL if the node wasn't found.                 NODE->contents is side-effected to point to right after                 the separator. */              node_sep = adjust_nodestart (node, min, max);              if (node_sep == (char *)NULL)                {                  free (node);                  return ((NODE *)NULL);                }              /* Readjust tag->nodestart. */              tag->nodestart = node_sep - subfile->contents;              /* Calculate the length of the current node. */              buff_end = subfile->contents + subfile->filesize;              node_body.buffer = node->contents;              node_body.start = 0;              node_body.end = buff_end - node_body.buffer;              node_body.flags = 0;              tag->nodelen = get_node_length (&node_body);            }          else            {              /* Since we know the length of this node, we have already                 adjusted tag->nodestart to point to the exact start of                 it.  Simply skip the node separator. */              node->contents += skip_node_separator (node->contents);            }          node->nodelen = tag->nodelen;          return (node);        }      }  /* There was a tag table for this file, and the node wasn't found.     Return NULL, since this file doesn't contain the desired node. */  return ((NODE *)NULL);}/* **************************************************************** *//*                                                                  *//*              Managing file_buffers, nodes, and tags.             *//*                                                                  *//* **************************************************************** *//* Create a new, empty file buffer. */FILE_BUFFER *make_file_buffer (){  FILE_BUFFER *file_buffer;  file_buffer = (FILE_BUFFER *)xmalloc (sizeof (FILE_BUFFER));  file_buffer->filename = file_buffer->fullpath = (char *)NULL;  file_buffer->contents = (char *)NULL;  file_buffer->tags = (TAG **)NULL;  file_buffer->subfiles = (char **)NULL;  file_buffer->tags_slots = 0;  file_buffer->flags = 0;  return (file_buffer);}/* Add FILE_BUFFER to our list of already loaded info files. */static voidremember_info_file (file_buffer)     FILE_BUFFER *file_buffer;{  int i;  for (i = 0; info_loaded_files && info_loaded_files[i]; i++)    ;  add_pointer_to_array (file_buffer, i, info_loaded_files,                        info_loaded_files_slots, 10, FILE_BUFFER *);}/* Forget the contents, tags table, nodes list, and names of FILENAME. */static voidforget_info_file (filename)     char *filename;{  register int i;  FILE_BUFFER *file_buffer;  if (!info_loaded_files)    return;  for (i = 0; (file_buffer = info_loaded_files[i]); i++)    if ((strcmp (filename, file_buffer->filename) == 0) ||        (strcmp (filename, file_buffer->fullpath) == 0))      {        free (file_buffer->filename);        free (file_buffer->fullpath);        if (file_buffer->contents)          free (file_buffer->contents);                /* Note that free_file_buffer_tags () also kills the subfiles           list, since the subfiles list is only of use in conjunction           with tags. */        free_file_buffer_tags (file_buffer);        while ((info_loaded_files[i] = info_loaded_files[++i]))          ;        break;      }}/* Free the tags (if any) associated with FILE_BUFFER. */static voidfree_file_buffer_tags (file_buffer)     FILE_BUFFER *file_buffer;{  register int i;  if (file_buffer->tags)    {      register TAG *tag;      for (i = 0; (tag = file_buffer->tags[i]); i++)        free_info_tag (tag);      free (file_buffer->tags);      file_buffer->tags = (TAG **)NULL;      file_buffer->tags_slots = 0;    }  if (file_buffer->subfiles)    {      for (i = 0; file_buffer->subfiles[i]; i++)        free (file_buffer->subfiles[i]);      free (file_buffer->subfiles);      file_buffer->subfiles = (char **)NULL;    }}/* Free the data associated with TAG, as well as TAG itself. */static voidfree_info_tag (tag)     TAG *tag;{  free (tag->nodename);  /* We don't free tag->filename, because that filename is part of the     subfiles list for the containing FILE_BUFFER.  free_info_tags ()     will free the subfiles when it is appropriate. */  free (tag);}/* Load the contents of FILE_BUFFER->contents.  This function is called   when a file buffer was loaded, and then in order to conserve memory, the   file buffer's contents were freed and the pointer was zero'ed.  Note that   the file was already loaded at least once successfully, so the tags and/or   nodes members are still correctly filled. */static voidinfo_reload_file_buffer_contents (fb)     FILE_BUFFER *fb;{#if defined (HANDLE_MAN_PAGES)  /* If this is the magic manpage node, don't try to reload, just give up. */  if (fb->flags & N_IsManPage)    return;#endif  fb->flags &= ~N_IsCompressed;  /* Let the filesystem do all the work for us. */  fb->contents =    filesys_read_info_file (fb->fullpath, &(fb->filesize), &(fb->finfo));  if (fb->filesize != (long) (fb->finfo.st_size))    fb->flags |= N_IsCompressed;}/* Return the actual starting memory location of NODE, side-effecting   NODE->contents.  MIN and MAX are bounds for a search if one is necessary.   Because of the way that tags are implemented, the physical nodestart may   not actually be where the tag says it is.  If that is the case, but the   node was found anyway, set N_UpdateTags in NODE->flags.  If the node is   found, return non-zero.  NODE->contents is returned positioned right after   the node separator that precedes this node, while the return value is   position directly on the separator that precedes this node.  If the node   could not be found, return a NULL pointer. */static char *adjust_nodestart (node, min, max)     NODE *node;     int min, max;{  long position;  SEARCH_BINDING node_body;  /* Define the node body. */  node_body.buffer = node->contents;  node_body.start = 0;  node_body.end = max;  node_body.flags = 0;  /* Try the optimal case first.  Who knows?  This file may actually be     formatted (mostly) correctly. */  if (node_body.buffer[0] != INFO_COOKIE && min > 2)    node_body.buffer -= 3;  position = find_node_separator (&node_body);  /* If we found a node start, then check it out. */  if (position != -1)    {      int sep_len;      sep_len = skip_node_separator (node->contents);      /* If we managed to skip a node separator, then check for this node         being the right one. */      if (sep_len != 0)        {          char *nodedef, *nodestart;          int offset;          nodestart = node_body.buffer + position + sep_len;          nodedef = nodestart;          offset = string_in_line (INFO_NODE_LABEL, nodedef);          if (offset != -1)            {              nodedef += offset;              nodedef += skip_whitespace (nodedef);              offset = skip_node_characters (nodedef, DONT_SKIP_NEWLINES);              if ((offset == strlen (node->nodename)) &&                  (strncmp (node->nodename, nodedef, offset) == 0))                {                  node->contents = nodestart;                  return (node_body.buffer + position);                }            }        }    }  /* Oh well, I guess we have to try to find it in a larger area. */  node_body.buffer = node->contents - min;  node_body.start = 0;  node_body.end = min + max;  node_body.flags = 0;  position = find_node_in_binding (node->nodename, &node_body);  /* If the node couldn't be found, we lose big. */  if (position == -1)    return ((char *)NULL);  /* Otherwise, the node was found, but the tags table could need updating     (if we used a tag to get here, that is).  Set the flag in NODE->flags. */  node->contents = node_body.buffer + position;  node->contents += skip_node_separator (node->contents);  if (node->flags & N_HasTagsTable)    node->flags |= N_UpdateTags;  return (node_body.buffer + position);}

⌨️ 快捷键说明

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