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

📄 protoize.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
            {              --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), sys_errlist[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--;  /* 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;#ifndef UNPROTOIZE  def_dec_p->f_list_chain = NULL;#endif /* !defined (UNPROTOIZE) */  for (;;)    {      const char *left_paren_p = find_corresponding_lparen (p);#ifndef UNPROTOIZE      {        f_list_chain_item *cip =          (f_list_chain_item *) xmalloc (sizeof (f_list_chain_item));        cip->formals_list	  = dupnstr (left_paren_p + 1, (size_t) (p - (left_paren_p+1)));              /* Add the new chain item at the head of the current list.  */        cip->chain_next = def_dec_p->f_list_chain;        def_dec_p->f_list_chain = cip;      }#endif /* !defined (UNPROTOIZE) */      def_dec_p->f_list_count++;      p = left_paren_p - 2;      /* p must now point either to another right paren, or to the last         character of the name of the function that was declared/defined.         If p points to another right paren, then this indicates that we         are dealing with multiple formals lists.  In that case, there         really should be another right paren preceding this right paren.  */      if (*p != ')')        break;      else        check_aux_info (*--p == ')');    }  {    const char *past_fn = p + 1;    check_aux_info (*past_fn == ' ');    /* Scan leftwards over the identifier that names the function.  */    while (is_id_char (*p))      p--;    p++;    /* p now points to the leftmost character of the function name.  */    {      char *fn_string = (char *) alloca (past_fn - p + 1);      strncpy (fn_string, p, (size_t) (past_fn - p));      fn_string[past_fn-p] = '\0';      def_dec_p->hash_entry = lookup (function_name_primary, fn_string);    }  }  /* Look at all of the defs and decs for this function name that we have     collected so far.  If there is already one which is at the same     line number in the same file, then we can discard this new def_dec_info     record.     As an extra assurance that any such pair of (nominally) identical     function declarations are in fact identical, we also compare the     ansi_decl parts of the lines from the aux_info files just to be on     the safe side.     This comparison will fail if (for instance) the user was playing     messy games with the preprocessor which ultimately causes one     function declaration in one header file to look differently when     that file is included by two (or more) other files.  */  {    const def_dec_info *other;    for (other = def_dec_p->hash_entry->ddip; other; other = other->next_for_func)      {        if (def_dec_p->line == other->line && def_dec_p->file == other->file)          {            if (strcmp (def_dec_p->ansi_decl, other->ansi_decl))              {                fprintf (stderr, "%s:%d: declaration of function `%s' takes different forms\n",			 def_dec_p->file->hash_entry->symbol,			 def_dec_p->line,			 def_dec_p->hash_entry->symbol);                exit (1);              }            free_def_dec (def_dec_p);            return;          }      }  }#ifdef UNPROTOIZE  /* If we are doing unprotoizing, we must now setup the pointers that will     point to the K&R name list and to the K&R argument declarations list.     Note that if this is only a function declaration, then we should not     expect to find any K&R style formals list following the ANSI-style     formals list.  This is because GCC knows that such information is     useless in the case of function declarations (function definitions     are a different story however).     Since we are unprotoizing, we don't need any such lists anyway.     All we plan to do is to delete all characters between ()'s in any     case.  */  def_dec_p->formal_names = NULL;

⌨️ 快捷键说明

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