zlaski      02/11/12 16:18:45

  Modified:    live/gcc3/gcc Tag: pre-import-2002-10-21 cppfiles.c
  Log:
  Bring over snaroff's header cache fix.
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.52.2.1  +370 -2    src/live/gcc3/gcc/cppfiles.c
  
  Index: cppfiles.c
  ===================================================================
  RCS file: /cvs/Darwin/src/live/gcc3/gcc/cppfiles.c,v
  retrieving revision 1.52
  retrieving revision 1.52.2.1
  diff -u -r1.52 -r1.52.2.1
  --- cppfiles.c        2002/08/26 05:39:31     1.52
  +++ cppfiles.c        2002/11/13 00:18:45     1.52.2.1
  @@ -155,6 +155,12 @@
                                   enum include_type));
   #endif /* FRAMEWORK_HEADERS  */
   
  +/* APPLE LOCAL begin header search */
  +static struct include_file * 
  +        find_include_file_in_hashtable PARAMS ((cpp_reader *, const char *, char *, 
  +                                                enum include_type, struct 
search_path *));
  +/* APPLE LOCAL end header search */
  +
   static struct include_file *
        find_include_file PARAMS ((cpp_reader *, const cpp_token *,
                                   enum include_type));
  @@ -426,7 +432,7 @@
     fp->inc = inc;
     fp->inc->refcnt++;
   
  -  /* Initialise controlling macro state.  */
  +  /* Initialize controlling macro state.  */
     pfile->mi_valid = true;
     pfile->mi_cmacro = 0;
   
  @@ -721,6 +727,17 @@
     /* Search directory path for the file.  */
     /* APPLE LOCAL -header-mapfile bandaid for buffer overflows */
     name = (char *) alloca (strlen (fname) + pfile->max_include_len + 2 + 500);
  +
  +/* APPLE LOCAL begin header search */
  +  if ((type != IT_INCLUDE_NEXT) && 
  +      (CPP_OPTION (pfile, bracket_include) == CPP_OPTION (pfile, quote_include)))
  +    {
  +    /* handle everything but gcc's include_next and -I- extensions */
  +    if ((file = find_include_file_in_hashtable (pfile, fname, name, header->type, 
path)))
  +      return file;
  +    }
  +/* APPLE LOCAL end header search */
  +
     for (; path; path = path->next)
       {
         /* APPLE LOCAL begin -header-mapfile */
  @@ -1024,7 +1041,7 @@
   }
   
   /* Create a dependency for file FNAME, or issue an error message as
  -   appropriate.  ANGLE_BRACKETS is non-zero if the file was bracketed
  +   appropriate.  ANGLE_BRACKETS is nonzero if the file was bracketed
      like <..>.  */
   static void
   handle_missing_header (pfile, fname, angle_brackets)
  @@ -1572,3 +1589,354 @@
     return path;
   #endif /* !VMS  */
   }
  +
  +/* APPLE LOCAL begin header search */
  +#include <dirent.h>
  +#include "hashtab.h"
  +
  +static htab_t header_htab = 0;
  +
  +struct hashed_attribute
  +{
  +  struct search_path *include_directory;
  +  struct hashed_attribute *next;
  +};
  +struct hashed_entry
  +{
  +  char file_name[MAXNAMLEN + 1];
  +  struct search_path *include_directory;
  +  struct hashed_attribute *list;
  +};
  +
  +static hashval_t hashed_entry_hash    PARAMS ((const void *x));
  +static int hashed_entry_eq            PARAMS ((const void *x, const void *y));
  +static void hash_enter PARAMS ((struct hashed_entry **, const char *, struct 
search_path *));
  +static void hash_add_attr PARAMS ((struct hashed_entry *, struct search_path *));
  +static void _load_include_headers PARAMS ((cpp_reader *, htab_t, char *));
  +static void _load_framework_directories PARAMS ((cpp_reader *, htab_t, char *));
  +
  +static hashval_t
  +hashed_entry_hash (p)
  +     const PTR p;
  +{
  +  const struct hashed_entry *old = p;
  +  return htab_hash_string (old->file_name);
  +}
  +
  +static int
  +hashed_entry_eq (p1, p2)
  +     const PTR p1;
  +     const PTR p2;   
  +{
  +  const struct hashed_entry *old = p1;
  +  const char *new = p2;  
  +
  +  return strcmp (old->file_name, new) == 0;
  +}
  +
  +static void
  +hash_enter (slot, file_name, include_directory)
  +     struct hashed_entry **slot;
  +     const char *file_name;
  +     struct search_path *include_directory;
  +{
  +  struct hashed_entry *obj = (struct hashed_entry *) xmalloc (sizeof (struct 
hashed_entry));
  +  *slot = obj;
  +  obj->list = 0;
  +  strcpy(obj->file_name, file_name);
  +  obj->include_directory = include_directory;
  +}
  +
  +static void
  +hash_add_attr (entry, value)
  +     struct hashed_entry * entry;
  +     struct search_path *value;
  +{
  +  struct hashed_attribute *obj = (struct hashed_attribute *) xmalloc (sizeof 
(struct hashed_attribute));
  +  struct hashed_attribute *list = entry->list;
  +
  +  obj->include_directory = value;
  +  obj->next = 0;
  +  if (list)
  +    { /* append to read */
  +      while (list->next) list = list->next;
  +      list->next = obj;
  +    }
  +  else
  +    entry->list = obj;               
  +}
  +
  +static void
  +_load_include_headers (pfile, includehash, name)
  +     cpp_reader *pfile;
  +     htab_t includehash;
  +     char *name;
  +{
  +  struct search_path *path = CPP_OPTION (pfile, bracket_include);
  +  for (; path; path = path->next)
  +    {
  +    DIR    *directory;
  +    struct dirent *directory_entry;
  +
  +    /* cannot depend on path->name being null terminated (weird) */
  +    memcpy (name, path->name, path->len);
  +    name[path->len] = 0;
  +    
  +    /* no need to check for existence...already done by append_include_chain() */
  +    directory = opendir(name);
  +    while ((directory_entry = readdir(directory)) != NULL) 
  +      {
  +      if (directory_entry->d_name[0] == '.') // for now, assume headers cannot 
begin with "."
  +        continue;
  +      else if (directory_entry->d_type == DT_REG || directory_entry->d_type == 
DT_DIR)
  +        {
  +        struct hashed_entry **slot, *entry;
  +        slot = (struct hashed_entry **)htab_find_slot_with_hash (includehash, 
directory_entry->d_name,
  +                                                 htab_hash_string 
(directory_entry->d_name), INSERT);
  +        entry = *slot;
  +        if (!entry)
  +          hash_enter (slot, directory_entry->d_name, path);
  +        else 
  +          hash_add_attr (entry, path);
  +        }
  +      }
  +    closedir(directory);
  +    }
  +}
  +
  +static void
  +_load_framework_directories (pfile, frameworkhash, name)
  +     cpp_reader *pfile;
  +     htab_t frameworkhash;
  +     char *name;
  +{
  +  struct search_path *path;
  +  
  +  path = CPP_OPTION (pfile, framework_include);
  +  if (path)
  +    {
  +    for (; path; path = path->next)
  +      {
  +      DIR    *directory;
  +      struct dirent *directory_entry;
  +
  +      /* cannot depend on path->name being null terminated (weird) */
  +      memcpy (name, path->name, path->len);
  +      name[path->len] = 0;
  +      /* no need to check for existence...already done by append_include_chain() */
  +      directory = opendir(name);
  +      while ((directory_entry = readdir(directory)) != NULL) 
  +        {
  +        if (directory_entry->d_name[0] == '.') // for now, assume headers cannot 
begin with "."
  +          continue;
  +        else if (directory_entry->d_type == DT_DIR) // just add directories, *not* 
all the headers
  +          {
  +          struct hashed_entry **slot, *entry;
  +          slot = (struct hashed_entry **)htab_find_slot_with_hash (frameworkhash, 
directory_entry->d_name,
  +                                                 htab_hash_string 
(directory_entry->d_name), INSERT);
  +          entry = *slot;
  +          if (!entry)
  +            hash_enter (slot, directory_entry->d_name, path);
  +          else
  +            hash_add_attr (entry, path);
  +          }
  +        }
  +      closedir(directory);
  +      } // for
  +    }
  +}
  +
  +static void
  +_init_include_hash(pfile, name)
  +     cpp_reader *pfile;
  +     char *name;
  +{
  +  header_htab = htab_create (2039, hashed_entry_hash, hashed_entry_eq, NULL);
  +  
  +  _load_include_headers(pfile, header_htab, name);
  +  _load_framework_directories(pfile, header_htab, name);      
  +}
  +
  +static void 
  +synthesize_name_from_path(name, path, fname)
  +     char *name;
  +     struct search_path *path;
  +     const char *fname;
  +{
  +  int len = path->len;
  +  memcpy(name, path->name, len);
  +  /* Don't turn / into // or // into ///; // may be a namespace escape.  */
  +  if (name[len-1] == '/')
  +    len--;
  +  name[len] = '/';
  +  strcpy (&name[len + 1], fname);
  +}
  +
  +static struct include_file *
  +find_include_file_in_hashtable (pfile, fname, name, type, path)
  +     cpp_reader *pfile;
  +     const char *fname;
  +     char *name;
  +     enum include_type type;
  +     struct search_path *path;
  +{
  +    char *slash_in_fname = strrchr(fname, '/');
  +    struct hashed_entry *entry;
  +    struct include_file *file;
  +
  +    /* should be called from _cpp_init_includes ()...unfortunately, 
_cpp_init_includes()
  +       it is called before the -I/-F flags are processed. Would be nice to find a
  +       better place to do this. Checking on every call is obviously silly */
  +    if (!header_htab)
  +      _init_include_hash(pfile, name);
  +    
  +    if ((type == CPP_STRING) && (path != CPP_OPTION (pfile, bracket_include)))
  +      {
  +      synthesize_name_from_path(name, path, fname);
  +      if ((file = open_file (pfile, name)))
  +        {
  +        file->foundhere = path;
  +        return file;
  +        }
  +      }
  +    if (CPP_OPTION (pfile, header_map))
  +      {
  +      struct search_path *hmap_path = hmap_lookup_path (pfile, &fname);
  +      
  +      if (hmap_path != CPP_OPTION (pfile, bracket_include))
  +        {
  +        synthesize_name_from_path(name, hmap_path, fname);
  +        if ((file = open_file (pfile, name)))
  +          {
  +          file->foundhere = hmap_path;
  +          return file;
  +          }
  +        }
  +      }
  +    if (!slash_in_fname)
  +      {
  +      if ((entry = htab_find(header_htab, fname))) 
  +        {
  +        synthesize_name_from_path(name, entry->include_directory, fname);
  +        if ((file = open_file (pfile, name)))
  +          {
  +          file->foundhere = entry->include_directory;
  +          return file;
  +          }
  +        }
  +      }
  +    else /* we have a slash... */
  +      {
  +      char *basename = strchr(fname, '/');
  +
  +      /* first, look for a directory */
  +      memcpy(name, fname, basename-fname);
  +      name[basename-fname] = 0;
  +
  +      if ((entry = htab_find(header_htab, name)))
  +        {
  +        synthesize_name_from_path(name, entry->include_directory, fname);
  +        if ((file = open_file (pfile, name)))
  +          {
  +          file->foundhere = entry->include_directory;
  +          return file;
  +          }
  +        else if (entry->list) // ambiguous...look in multiple places...
  +          { 
  +          struct hashed_attribute *hattr = entry->list;
  +          do 
  +            { 
  +            synthesize_name_from_path(name, hattr->include_directory, fname);
  +            if ((file = open_file (pfile, name)))
  +              {
  +              file->foundhere = hattr->include_directory;
  +              return file;
  +              }   
  +            } 
  +          while ((hattr = hattr->next));
  +          }
  +        }
  +      /* now, look for a framework */
  +      memcpy(name, fname, basename-fname);
  +      name[basename-fname] = 0;
  +      strcat(name, ".framework");
  +      if ((entry = htab_find(header_htab, name)))
  +        {
  +        int len = entry->include_directory->len;
  +        memcpy(name, entry->include_directory->name, entry->include_directory->len);
  +        name[len] = '/';
  +        strcpy (&name[len + 1], entry->file_name);
  +        strcat (name, "/Headers");
  +        strcat (name, basename); // add the base name
  +        if ((file = open_file (pfile, name)))
  +          {
  +            file->foundhere = entry->include_directory;
  +            return file;
  +          }
  +        memcpy(name, entry->include_directory->name, entry->include_directory->len);
  +        name[len] = '/';
  +        strcpy (&name[len + 1], entry->file_name);
  +        strcat (name, "/PrivateHeaders");
  +        strcat (name, basename); // add the base name
  +        if ((file = open_file (pfile, name)))
  +          {
  +            file->foundhere = entry->include_directory;
  +            return file;
  +          }
  +        }
  +    }
  +  return 0;
  +}
  +
  +#ifdef DEBUG
  +
  +extern cpp_reader *parse_in;
  +
  +static int found = 0, not_found = 0;
  +static int total_size = 0;
  +
  +static int
  +splay_func (n, b)
  +     splay_tree_node n;
  +     void *b;
  +{
  +  struct include_file *f = (struct include_file *) n->value;
  +  int *bannerp = (int *)b;
  +  ssize_t size = f->st.st_size;
  +  
  +  if (f->st.st_ino)
  +    {
  +    if (parse_in->buffer->inc == f)
  +      {
  +      ; //printf("module %s %d\n",f->name, size);
  +      }
  +    else
  +      {
  +      total_size += size;
  +      //printf("header %s %d %d\n",f->name, size, total_size);
  +      }
  +    found++;
  +    }
  +  else
  +    {
  +    not_found++;
  +    }
  +  return 0;
  +}
  +
  +/* include call to cpp_log() in toplev.c:compile_file() if you want diagnostics */
  +
  +void
  +cpp_log (pfile)
  +{
  +  int banner = 0;
  +  struct include_file *f = parse_in->buffer->inc;
  +  ssize_t size = f->st.st_size;
  +  
  +  found = 0; not_found = 0;
  +  splay_tree_foreach (parse_in->all_include_files, splay_func, (PTR) &banner);
  +  fprintf(stderr, "=> module %s %d header %d found %d nfound %d\n", f->name, size, 
total_size,
  +                found, not_found);
  +}
  +#endif
  +/* APPLE LOCAL end header search */
  
  
  


Reply via email to