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

📄 file.c

📁 DSP网络驱动开发_TMS3206
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Target file hash table management for GNU Make.Copyright (C) 1988,89,90,91,92,93,94,95,96,97 Free Software Foundation, Inc.This file is part of GNU Make.GNU Make is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU Make is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Make; see the file COPYING.  If not, write tothe Free Software Foundation, Inc., 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA.  */#include <assert.h>#include "make.h"#include "dep.h"#include "filedef.h"#include "job.h"#include "commands.h"#include "variable.h"/* Hash table of files the makefile knows how to make.  */#ifndef	FILE_BUCKETS#define FILE_BUCKETS	1007#endifstatic struct file *files[FILE_BUCKETS];/* Number of files with the `intermediate' flag set.  */unsigned int num_intermediates = 0;/* Current value for pruning the scan of the goal chain (toggle 0/1).  */unsigned int considered = 0;/* Access the hash table of all file records.   lookup_file  given a name, return the struct file * for that name,           or nil if there is none.   enter_file   similar, but create one if there is none.  */struct file *lookup_file (name)     char *name;{  register struct file *f;  register char *n;  register unsigned int hashval;#ifdef VMS  register char *lname, *ln;#endif  if (*name == '\0')    abort ();  /* This is also done in parse_file_seq, so this is redundant     for names read from makefiles.  It is here for names passed     on the command line.  */#ifdef VMS  lname = (char *)malloc(strlen(name) + 1);  for (n=name, ln=lname; *n != '\0'; ++n, ++ln)    *ln = isupper(*n) ? tolower(*n) : *n;  *ln = '\0';  name = lname;  while (name[0] == '[' && name[1] == ']' && name[2] != '\0')      name += 2;#endif  while (name[0] == '.' && name[1] == '/' && name[2] != '\0')    {      name += 2;      while (*name == '/')	/* Skip following slashes: ".//foo" is "foo", not "/foo".  */	++name;    }  if (*name == '\0')    /* It was all slashes after a dot.  */#ifdef VMS    name = "[]";#else#ifdef _AMIGA    name = "";#else    name = "./";#endif /* AMIGA */#endif /* VMS */  hashval = 0;  for (n = name; *n != '\0'; ++n)    HASHI (hashval, *n);  hashval %= FILE_BUCKETS;  for (f = files[hashval]; f != 0; f = f->next)    {      if (strieq (f->hname, name))	{#ifdef VMS	  free (lname);#endif	  return f;	}    }#ifdef VMS  free (lname);#endif  return 0;}struct file *enter_file (name)     char *name;{  register struct file *f, *new;  register char *n;  register unsigned int hashval;#ifdef VMS  char *lname, *ln;#endif  if (*name == '\0')    abort ();#ifdef VMS  lname = (char *)malloc (strlen (name) + 1);  for (n = name, ln = lname; *n != '\0'; ++n, ++ln)    {      if (isupper(*n))	*ln = tolower(*n);      else	*ln = *n;    }  *ln = 0;  name = lname;#endif  hashval = 0;  for (n = name; *n != '\0'; ++n)    HASHI (hashval, *n);  hashval %= FILE_BUCKETS;  for (f = files[hashval]; f != 0; f = f->next)    if (strieq (f->hname, name))      break;  if (f != 0 && !f->double_colon)    {#ifdef VMS      free(lname);#endif      return f;    }  new = (struct file *) xmalloc (sizeof (struct file));  bzero ((char *) new, sizeof (struct file));  new->name = new->hname = name;  new->update_status = -1;  if (f == 0)    {      /* This is a completely new file.  */      new->next = files[hashval];      files[hashval] = new;    }  else    {      /* There is already a double-colon entry for this file.  */      new->double_colon = f;      while (f->prev != 0)	f = f->prev;      f->prev = new;    }  return new;}/* Rehash FILE to NAME.  This is not as simple as resetting   the `hname' member, since it must be put in a new hash bucket,   and possibly merged with an existing file called NAME.  */voidrehash_file (file, name)     register struct file *file;     char *name;{  char *oldname = file->hname;  register unsigned int oldhash;  register char *n;  while (file->renamed != 0)    file = file->renamed;  /* Find the hash values of the old and new names.  */  oldhash = 0;  for (n = oldname; *n != '\0'; ++n)    HASHI (oldhash, *n);  file_hash_enter (file, name, oldhash, file->name);}/* Rename FILE to NAME.  This is not as simple as resetting   the `name' member, since it must be put in a new hash bucket,   and possibly merged with an existing file called NAME.  */voidrename_file (file, name)     register struct file *file;     char *name;{  rehash_file(file, name);  while (file)    {      file->name = file->hname;      file = file->prev;    }}voidfile_hash_enter (file, name, oldhash, oldname)     register struct file *file;     char *name;     unsigned int oldhash;     char *oldname;{  unsigned int oldbucket = oldhash % FILE_BUCKETS;  register unsigned int newhash, newbucket;  struct file *oldfile;  register char *n;  register struct file *f;  newhash = 0;  for (n = name; *n != '\0'; ++n)    HASHI (newhash, *n);  newbucket = newhash % FILE_BUCKETS;  /* Look for an existing file under the new name.  */  for (oldfile = files[newbucket]; oldfile != 0; oldfile = oldfile->next)    if (strieq (oldfile->hname, name))      break;  /* If the old file is the same as the new file, something's wrong.  */  assert (oldfile != file);  if (oldhash != 0 && (newbucket != oldbucket || oldfile != 0))    {      /* Remove FILE from its hash bucket.  */      struct file *lastf = 0;      for (f = files[oldbucket]; f != file; f = f->next)	lastf = f;      if (lastf == 0)	files[oldbucket] = f->next;      else	lastf->next = f->next;    }  /* Give FILE its new name.  */  file->hname = name;  for (f = file->double_colon; f != 0; f = f->prev)    f->hname = name;  if (oldfile == 0)    {      /* There is no existing file with the new name.  */      if (newbucket != oldbucket)	{	  /* Put FILE in its new hash bucket.  */	  file->next = files[newbucket];	  files[newbucket] = file;	}    }  else    {      /* There is an existing file with the new name.	 We must merge FILE into the existing file.  */      register struct dep *d;      if (file->cmds != 0)	{	  if (oldfile->cmds == 0)	    oldfile->cmds = file->cmds;	  else if (file->cmds != oldfile->cmds)	    {	      /* We have two sets of commands.  We will go with the		 one given in the rule explicitly mentioning this name,		 but give a message to let the user know what's going on.  */	      if (oldfile->cmds->fileinfo.filenm != 0)                error (&file->cmds->fileinfo,                                _("Commands were specified for \file `%s' at %s:%lu,"),                                oldname, oldfile->cmds->fileinfo.filenm,                                oldfile->cmds->fileinfo.lineno);	      else		error (&file->cmds->fileinfo,				_("Commands for file `%s' were found by \implicit rule search,"),				oldname);	      error (&file->cmds->fileinfo,			      _("but `%s' is now considered the same file \as `%s'."),			      oldname, name);	      error (&file->cmds->fileinfo,			      _("Commands for `%s' will be ignored \in favor of those for `%s'."),			      name, oldname);	    }	}      /* Merge the dependencies of the two files.  */      d = oldfile->deps;      if (d == 0)	oldfile->deps = file->deps;      else	{	  while (d->next != 0)	    d = d->next;	  d->next = file->deps;	}      merge_variable_set_lists (&oldfile->variables, file->variables);      if (oldfile->double_colon && file->is_target && !file->double_colon)	fatal (NILF, _("can't rename single-colon `%s' to double-colon `%s'"),	       oldname, name);      if (!oldfile->double_colon  && file->double_colon)	{	  if (oldfile->is_target)	    fatal (NILF, _("can't rename double-colon `%s' to single-colon `%s'"),		   oldname, name);	  else	    oldfile->double_colon = file->double_colon;	}      if (file->last_mtime > oldfile->last_mtime)	/* %%% Kludge so -W wins on a file that gets vpathized.  */	oldfile->last_mtime = file->last_mtime;      oldfile->mtime_before_update = file->mtime_before_update;#define MERGE(field) oldfile->field |= file->field      MERGE (precious);      MERGE (tried_implicit);      MERGE (updating);      MERGE (updated);      MERGE (is_target);      MERGE (cmd_target);      MERGE (phony);      MERGE (ignore_vpath);#undef MERGE      file->renamed = oldfile;    }}/* Remove all nonprecious intermediate files.

⌨️ 快捷键说明

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