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

📄 protoize.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
      else if (inp[0] == '/' && outp[-1] == '/')        {          inp++;          continue;        }      else if (inp[0] == '.' && outp[-1] == '/')        {          if (!inp[1])                  break;          else if (inp[1] == '/')            {                    inp += 2;                    continue;            }          else if ((inp[1] == '.') && (inp[2] == 0 || inp[2] == '/'))            {                    inp += (inp[2] == '/') ? 3 : 2;                    outp -= 2;                    while (outp >= abs_buffer && *outp != '/')              	outp--;                    if (outp < abs_buffer)                {                  /* Catch cases like /.. where we try to backup to a                     point above the absolute root of the logical file                     system.  */              	  fprintf (stderr, "%s: invalid file name: %s\n",			   pname, rel_filename);              	  exit (1);              	}                    *++outp = '\0';                    continue;            }        }      *outp++ = *inp++;    }  /* On exit, make sure that there is a trailing null, and make sure that     the last character of the returned string is *not* a slash.  */  *outp = '\0';  if (outp[-1] == '/')    *--outp  = '\0';  /* Make a copy (in the heap) of the stuff left in the absolutization     buffer and return a pointer to the copy.  */  return savestring (abs_buffer, outp - abs_buffer);}/* Given a filename (and possibly a directory name from which the filename   is relative) return a string which is the shortest possible   equivalent for the corresponding full (absolutized) filename.  The   shortest possible equivalent may be constructed by converting the   absolutized filename to be a relative filename (i.e. relative to   the actual current working directory).  However if a relative filename   is longer, then the full absolute filename is returned.   KNOWN BUG:   Note that "simple-minded" conversion of any given type of filename (either   relative or absolute) may not result in a valid equivalent filename if any   subpart of the original filename is actually a symbolic link.  */static const char *shortpath (cwd, filename)     const char *cwd;     const char *filename;{  char *rel_buffer;  char *rel_buf_p;  char *cwd_p = cwd_buffer;  char *path_p;  int unmatched_slash_count = 0;  size_t filename_len = strlen (filename);  path_p = abspath (cwd, filename);  rel_buf_p = rel_buffer = (char *) xmalloc (filename_len);  while (*cwd_p && (*cwd_p == *path_p))    {      cwd_p++;      path_p++;    }  if (!*cwd_p && (!*path_p || *path_p == '/'))	/* whole pwd matched */    {      if (!*path_p)        	/* input *is* the current path! */        return ".";      else        return ++path_p;    }  else    {      if (*path_p)        {          --cwd_p;          --path_p;          while (*cwd_p != '/')        	/* backup to last slash */            {              --cwd_p;              --path_p;            }          cwd_p++;          path_p++;          unmatched_slash_count++;        }      /* Find out how many directory levels in cwd were *not* matched.  */      while (*cwd_p)        if (*cwd_p++ == '/')	  unmatched_slash_count++;      /* Now we know how long the "short name" will be.	 Reject it if longer than the input.  */      if (unmatched_slash_count * 3 + strlen (path_p) >= filename_len)	return filename;      /* For each of them, put a `../' at the beginning of the short name.  */      while (unmatched_slash_count--)        {	  /* Give up if the result gets to be longer	     than the absolute path name.  */	  if (rel_buffer + filename_len <= rel_buf_p + 3)	    return filename;          *rel_buf_p++ = '.';          *rel_buf_p++ = '.';          *rel_buf_p++ = '/';        }      /* Then tack on the unmatched part of the desired file's name.  */      do	{	  if (rel_buffer + filename_len <= rel_buf_p)	    return filename;	}      while (*rel_buf_p++ = *path_p++);      --rel_buf_p;      if (*(rel_buf_p-1) == '/')        *--rel_buf_p = '\0';      return rel_buffer;    }}/* Lookup the given filename in the hash table for filenames.  If it is a   new one, then the hash table info pointer will be null.  In this case,   we create a new file_info record to go with the filename, and we initialize   that record with some reasonable values.  *//* FILENAME was const, but that causes a warning on AIX when calling stat.   That is probably a bug in AIX, but might as well avoid the warning.  */static file_info *find_file (filename, do_not_stat)     char *filename;     int do_not_stat;{  hash_table_entry *hash_entry_p;  hash_entry_p = lookup (filename_primary, filename);  if (hash_entry_p->fip)    return hash_entry_p->fip;  else    {      struct stat stat_buf;      file_info *file_p = (file_info *) xmalloc (sizeof (file_info));      /* If we cannot get status on any given source file, give a warning         and then just set its time of last modification to infinity.  */      if (do_not_stat)        stat_buf.st_mtime = (time_t) 0;      else        {          if (my_stat (filename, &stat_buf) == -1)            {              fprintf (stderr, "%s: %s: can't get status: %s\n",		       pname, shortpath (NULL, filename), my_strerror(errno));              stat_buf.st_mtime = (time_t) -1;            }        }      hash_entry_p->fip = file_p;      file_p->hash_entry = hash_entry_p;      file_p->defs_decs = NULL;      file_p->mtime = stat_buf.st_mtime;      return file_p;    }}/* Generate a fatal error because some part of the aux_info file is   messed up.  */static voidaux_info_corrupted (){  fprintf (stderr, "\n%s: fatal error: aux info file corrupted at line %d\n",	   pname, current_aux_info_lineno);  exit (1);}/* ??? This comment is vague.  Say what the condition is for.  *//* Check to see that a condition is true.  This is kind of like an assert.  */static voidcheck_aux_info (cond)     int cond;{  if (! cond)    aux_info_corrupted ();}/* Given a pointer to the closing right parenthesis for a particular formals   list (in an aux_info file) find the corresponding left parenthesis and   return a pointer to it.  */static const char *find_corresponding_lparen (p)     const char *p;{  const char *q;  int paren_depth;  for (paren_depth = 1, q = p-1; paren_depth; q--)    {      switch (*q)        {          case ')':            paren_depth++;            break;          case '(':            paren_depth--;            break;        }    }  return ++q;}/* Given a line from  an aux info file, and a time at which the aux info   file it came from was created, check to see if the item described in   the line comes from a file which has been modified since the aux info   file was created.  If so, return non-zero, else return zero.  */static intreferenced_file_is_newer (l, aux_info_mtime)     const char *l;     time_t aux_info_mtime;{  const char *p;  file_info *fi_p;  char *filename;  check_aux_info (l[0] == '/');  check_aux_info (l[1] == '*');  check_aux_info (l[2] == ' ');  {    const char *filename_start = p = l + 3;    while (*p != ':')      p++;    filename = (char *) alloca ((size_t) (p - filename_start) + 1);    strncpy (filename, filename_start, (size_t) (p - filename_start));    filename[p-filename_start] = '\0';  }  /* Call find_file to find the file_info record associated with the file     which contained this particular def or dec item.  Note that this call     may cause a new file_info record to be created if this is the first time     that we have ever known about this particular file.  */  fi_p = find_file (abspath (invocation_filename, filename), 0);  return (fi_p->mtime > aux_info_mtime);}/* Given a line of info from the aux_info file, create a new   def_dec_info record to remember all of the important information about   a function definition or declaration.   Link this record onto the list of such records for the particular file in   which it occurred in proper (descending) line number order (for now).   If there is an identical record already on the list for the file, throw   this one away.  Doing so takes care of the (useless and troublesome)   duplicates which are bound to crop up due to multiple inclusions of any   given individual header file.   Finally, link the new def_dec record onto the list of such records   pertaining to this particular function name.  */static voidsave_def_or_dec (l, is_syscalls)     const char *l;     int is_syscalls;{  const char *p;  const char *semicolon_p;  def_dec_info *def_dec_p = (def_dec_info *) xmalloc (sizeof (def_dec_info));#ifndef UNPROTOIZE  def_dec_p->written = 0;#endif /* !defined (UNPROTOIZE) */  /* Start processing the line by picking off 5 pieces of information from     the left hand end of the line.  These are filename, line number,     new/old/implicit flag (new = ANSI prototype format), definition or     declaration flag, and extern/static flag).  */  check_aux_info (l[0] == '/');  check_aux_info (l[1] == '*');  check_aux_info (l[2] == ' ');  {    const char *filename_start = p = l + 3;    char *filename;    while (*p != ':')      p++;    filename = (char *) alloca ((size_t) (p - filename_start) + 1);    strncpy (filename, filename_start, (size_t) (p - filename_start));    filename[p-filename_start] = '\0';    /* Call find_file to find the file_info record associated with the file       which contained this particular def or dec item.  Note that this call       may cause a new file_info record to be created if this is the first time       that we have ever known about this particular file.         Note that we started out by forcing all of the base source file names       (i.e. the names of the aux_info files with the .X stripped off) into the       filenames hash table, and we simultaneously setup file_info records for       all of these base file names (even if they may be useless later).       The file_info records for all of these "base" file names (properly)       act as file_info records for the "original" (i.e. un-included) files       which were submitted to gcc for compilation (when the -aux-info       option was used).  */      def_dec_p->file = find_file (abspath (invocation_filename, filename), is_syscalls);  }  {    const char *line_number_start = ++p;    char line_number[10];    while (*p != ':')      p++;    strncpy (line_number, line_number_start, (size_t) (p - line_number_start));    line_number[p-line_number_start] = '\0';    def_dec_p->line = atoi (line_number);  }  /* Check that this record describes a new-style, old-style, or implicit     definition or declaration.  */  p++;	/* Skip over the `:'. */  check_aux_info ((*p == 'N') || (*p == 'O') || (*p == 'I'));  /* Is this a new style (ANSI prototyped) definition or declaration? */  def_dec_p->prototyped = (*p == 'N');#ifndef UNPROTOIZE  /* Is this an implicit declaration? */  def_dec_p->is_implicit = (*p == 'I');#endif /* !defined (UNPROTOIZE) */  p++;  check_aux_info ((*p == 'C') || (*p == 'F'));  /* Is this item a function definition (F) or a declaration (C).  Note that     we treat item taken from the syscalls file as though they were function     definitions regardless of what the stuff in the file says.  */  def_dec_p->is_func_def = ((*p++ == 'F') || is_syscalls);#ifndef UNPROTOIZE  def_dec_p->definition = 0;	/* Fill this in later if protoizing.  */#endif /* !defined (UNPROTOIZE) */  check_aux_info (*p++ == ' ');  check_aux_info (*p++ == '*');  check_aux_info (*p++ == '/');  check_aux_info (*p++ == ' ');#ifdef UNPROTOIZE  check_aux_info ((!strncmp (p, "static", 6)) || (!strncmp (p, "extern", 6)));#else /* !defined (UNPROTOIZE) */  if (!strncmp (p, "static", 6))    def_dec_p->is_static = -1;  else if (!strncmp (p, "extern", 6))    def_dec_p->is_static = 0;  else    check_aux_info (0);	/* Didn't find either `extern' or `static'.  */#endif /* !defined (UNPROTOIZE) */  {    const char *ansi_start = p;    p += 6;	/* Pass over the "static" or "extern".  */    /* We are now past the initial stuff.  Search forward from here to find       the terminating semicolon that should immediately follow the entire       ANSI format function declaration.  */    while (*++p != ';')      continue;    semicolon_p = p;    /* Make a copy of the ansi declaration part of the line from the aux_info       file.  */    def_dec_p->ansi_decl      = dupnstr (ansi_start, (size_t) ((semicolon_p+1) - ansi_start));    /* Backup and point at the final right paren of the final argument list.  */    p--;#ifndef UNPROTOIZE    def_dec_p->f_list_chain = NULL;#endif /* !defined (UNPROTOIZE) */    while (p != ansi_start && (p[-1] == ' ' || p[-1] == '\t')) p--;    if (*p != ')')      {	free_def_dec (def_dec_p);	return;      }  }  /* Now isolate a whole set of formal argument lists, one-by-one.  Normally,     there will only be one list to isolate, but there could be more.  */  def_dec_p->f_list_count = 0;  for (;;)    {      const char *left_paren_p = find_corresponding_lparen (p);#ifndef UNPROTOIZE      {        f_list_chain_item *cip =

⌨️ 快捷键说明

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