Пример #1
0
static void
append_arg (const struct cl_decoded_option *arg)
{
  static unsigned int newargsize;

  if (g77_new_decoded_options == g77_x_decoded_options
      && g77_newargc < g77_xargc
      && options_same (arg, &g77_x_decoded_options[g77_newargc]))
    {
      ++g77_newargc;
      return;			/* Nothing new here.  */
    }

  if (g77_new_decoded_options == g77_x_decoded_options)
    {				/* Make new arglist.  */
      unsigned int i;

      newargsize = (g77_xargc << 2) + 20;	/* This should handle all.  */
      g77_new_decoded_options = XNEWVEC (struct cl_decoded_option, newargsize);

      /* Copy what has been done so far.  */
      for (i = 0; i < g77_newargc; ++i)
	g77_new_decoded_options[i] = g77_x_decoded_options[i];
    }
Пример #2
0
/*
 * Classify the state of a file
 */
Ctype Classify_File (struct file_info *finfo, const char *tag, const char *date,
    const char *options, int force_tag_match, int aflag, Vers_TS **versp,
    int pipeout, int force_time_mismatch, int ignore_keywords)
    /* Keyword expansion options can be either NULL or "" to
       indicate none are specified here.  */
{
    Vers_TS *vers;
    Ctype ret;
	kflag kf,kf_ent;

    TRACE(3,"Classify_File (%s)",PATCH_NULL(finfo->file));
    /* get all kinds of good data about the file */
    vers = Version_TS (finfo, options, tag, date, force_tag_match, 0, 0);
    TRACE(3,"vn_rcs=%s",PATCH_NULL(vers->vn_rcs));	

	RCS_get_kflags(vers->options,false,kf);
	if(vers->entdata)
		RCS_get_kflags(vers->entdata->options,false,kf_ent);

	if(force_time_mismatch)
	{
		xfree(vers->ts_user);
		vers->ts_user=xstrdup("modified");
	}

    if (vers->vn_user == NULL)
    {
	/* No entry available, ts_rcs is invalid */
	if (vers->vn_rcs == NULL)
	{
	    /* there is no RCS file either */
	    if (vers->ts_user == NULL)
	    {
		/* there is no user file */
		/* FIXME: Why do we skip this message if vers->tag or
		   vers->date is set?  It causes "cvs update -r tag98 foo"
		   to silently do nothing, which is seriously confusing
		   behavior.  "cvs update foo" gives this message, which
		   is what I would expect.  */
		if (!force_tag_match || !(vers->tag || vers->date))
		{
		    if (!really_quiet)
				error (0, 0, "nothing known about %s", fn_root(finfo->fullname));
		}
		ret = T_UNKNOWN;
	    }
	    else
	    {
		/* there is a user file */
		/* FIXME: Why do we skip this message if vers->tag or
		   vers->date is set?  It causes "cvs update -r tag98 foo"
		   to silently do nothing, which is seriously confusing
		   behavior.  "cvs update foo" gives this message, which
		   is what I would expect.  */
		if (!force_tag_match || !(vers->tag || vers->date))
		    if (!really_quiet)
			error (0, 0, "use `%s add' to create an entry for %s",
			       program_name, fn_root(finfo->fullname));
		ret = T_UNKNOWN;
	    }
	}
	else if (RCS_isdead (vers->srcfile, vers->vn_rcs))
	{
	    /* there is an RCS file, but it's dead */
	    if (vers->ts_user == NULL)
		ret = T_UPTODATE;
	    else
	    {
		error (0, 0, "use `%s add' to create an entry for %s",
		       program_name, fn_root(finfo->fullname));
		ret = T_UNKNOWN;
	    }
	}
	else if (vers->ts_user && !strcmp(vers->ts_user,"0") && !strcmp(finfo->file,RCSREPOVERSION))
	{
		/* It's a directory entry, but there isn't one in the repository */
		ret = T_UNKNOWN;
	}
	else if (!pipeout && vers->ts_user && No_Difference(finfo, vers, (kf.flags&KFLAG_STATIC || kf_ent.flags&KFLAG_STATIC), ignore_keywords))
	{
	    /* the files were different so it is a conflict */
	    if (!really_quiet)
		error (0, 0, "move away %s; it is in the way",
		       fn_root(finfo->fullname));
	    ret = T_CONFLICT;
	}
	else
	{
	    /* no user file or no difference, just checkout */
	    ret = T_CHECKOUT;
	}
    }
    else if (strcmp (vers->vn_user, "0") == 0)
    {
	/* An entry for a new-born file; ts_rcs is dummy */

	if (vers->ts_user == NULL)
	{
	    /*
	     * There is no user file, but there should be one; remove the
	     * entry
	     */
		if(!really_quiet)
			error (0, 0, "warning: new-born %s has disappeared", fn_root(finfo->fullname));
		ret = T_REMOVE_ENTRY;
	}
	else if (vers->vn_rcs == NULL ||
		 RCS_isdead (vers->srcfile, vers->vn_rcs))
	    /* No RCS file or RCS file revision is dead  */
	    ret = T_ADDED;
	else
	{
	    if (vers->srcfile->flags & VALID)
	    {
		/* This file has been added on some branch other than
		   the one we are looking at.  In the branch we are
		   looking at, the file was already valid.  */
		if (!really_quiet)
		    error (0, 0,
			   "conflict: %s has been added, but already exists",
			   fn_root(finfo->fullname));
	    }
	    else
	    {
		/*
		 * There is an RCS file, so someone else must have checked
		 * one in behind our back; conflict
		 */
		if (!really_quiet)
		    error (0, 0,
			   "conflict: %s created independently by second party",
			   fn_root(finfo->fullname));
	    }
	    ret = T_CONFLICT;
	}
    }
    else if (vers->vn_user[0] == '-')
    {
	/* An entry for a removed file, ts_rcs is invalid */

	if (vers->ts_user == NULL)
	{
	    /* There is no user file (as it should be) */

	    if (vers->vn_rcs == NULL
		|| RCS_isdead (vers->srcfile, vers->vn_rcs))
	    {

		/*
		 * There is no RCS file; this is all-right, but it has been
		 * removed independently by a second party; remove the entry
		 */
		ret = T_REMOVE_ENTRY;
	    }
	    else if (strcmp (vers->vn_rcs, vers->vn_user + 1) == 0)
		/*
		 * The RCS file is the same version as the user file was, and
		 * that's OK; remove it
		 */
		ret = T_REMOVED;
	    else if (pipeout)
		/*
		 * The RCS file doesn't match the user's file, but it doesn't
		 * matter in this case
		 */
		ret = T_NEEDS_MERGE;
	    else
	    {

		/*
		 * The RCS file is a newer version than the removed user file
		 * and this is definitely not OK; make it a conflict.
		 */
		if (!really_quiet)
		    error (0, 0,
			   "conflict: removed %s was modified by second party",
			   fn_root(finfo->fullname));
		ret = T_CONFLICT;
	    }
	}
	else
	{
	    /* The user file shouldn't be there */
	    if (!really_quiet)
		error (0, 0, "%s should be removed and is still there",
		       fn_root(finfo->fullname));
	    ret = T_REMOVED;
	}
    }
    else
    {
	/* A normal entry, TS_Rcs is valid */
	if (vers->vn_rcs == NULL || RCS_isdead (vers->srcfile, vers->vn_rcs))
	{
	    /* There is no RCS file */

	    if (vers->ts_user == NULL)
	    {
		/* There is no user file, so just remove the entry */
		if (!really_quiet)
		    error (0, 0, "warning: %s is not (any longer) pertinent",
			   fn_root(finfo->fullname));
		ret = T_REMOVE_ENTRY;
	    }
	    else if (!strcmp (vers->ts_user, vers->ts_rcs))
	    {
		/*
		 * The user file is still unmodified, so just remove it from
		 * the entry list
		 */
		if (!really_quiet)
		    error (0, 0, "%s is no longer in the repository",
			   fn_root(finfo->fullname));
		ret = T_REMOVE_ENTRY;
	    }
		else if (No_Difference (finfo, vers, (kf.flags&KFLAG_STATIC || kf_ent.flags&KFLAG_STATIC), ignore_keywords))
	    {
		/* they are different -> conflict */
		if (!really_quiet)
		    error (0, 0,
	       "conflict: %s is modified but no longer in the repository",
			   fn_root(finfo->fullname));
		ret = T_CONFLICT;
	    }
	    else
	    {
		/* they weren't really different */
		if (!really_quiet)
		    error (0, 0,
			   "warning: %s is not (any longer) pertinent",
			   fn_root(finfo->fullname));
		ret = T_REMOVE_ENTRY;
	    }
	}
	else if (strcmp (vers->vn_rcs, vers->vn_user) == 0)
	{
	    /* The RCS file is the same version as the user file */

	    if (vers->ts_user == NULL)
	    {
		/*
		 * There is no user file, so note that it was lost and
		 * extract a new version
		 */
		/* Comparing the command_name against "update", in
		   addition to being an ugly way to operate, means
		   that this message does not get printed by the
		   server.  That might be considered just a straight
		   bug, although there is one subtlety: that case also
		   gets hit when a patch fails and the client fetches
		   a file.  I'm not sure there is currently any way
		   for the server to distinguish those two cases.  */
		if (strcmp (command_name, "update") == 0)
		    if (!really_quiet)
			error (0, 0, "warning: %s was lost", fn_root(finfo->fullname));
		ret = T_CHECKOUT;
	    }
		else if (!strcmp(vers->ts_user,"0") && !strcmp(finfo->file,RCSREPOVERSION))
		{
			/* This is a directory... The only important entry is the version*/
			ret = T_UPTODATE;
		}
	    else if (strcmp (vers->ts_user, vers->ts_rcs) == 0)
	    {
			/* Check for expansion option changes */
			if (options && !options_same(vers->entdata->options,vers->options))
				ret = T_CHECKOUT;
			else
			{
				if(aflag && !options_same(vers->entdata->options, vers->options))
					ret = T_CHECKOUT;
				else
					ret = T_UPTODATE;
				/* Changing the expansion option now requires a commit -f, which makes
				   sense (since you might have a sandbox specially checked out as -kb for example) */
				sticky_ck (finfo, aflag, vers);
			}
	    }
	    else if (vers->entdata->merge_from_tag_1[0]) 
		{
			ret = T_MODIFIED;
		}
		else if (No_Difference (finfo, vers, (kf.flags&KFLAG_STATIC || kf_ent.flags&KFLAG_STATIC), ignore_keywords))
	    {
			ret = T_MODIFIED;
			sticky_ck (finfo, aflag, vers);
	    }
	    else if (!options_same(vers->entdata->options,vers->options))
	    {
			/* file has not changed; check out if -k changed */
			ret = T_CHECKOUT;
	    }
	    else
	    {

		/*
		 * else -> note that No_Difference will Register the
		 * file already for us, using the new tag/date. This
		 * is the desired behaviour
		 */
		ret = T_UPTODATE;
	    }
	}
	else
	{
	    /* The RCS file is a newer version than the user file */

	    if (vers->ts_user == NULL)
	    {
		/* There is no user file, so just get it */

		/* See comment at other "update" compare, for more
		   thoughts on this comparison.  */
		if (strcmp (command_name, "update") == 0)
		    if (!really_quiet)
			error (0, 0, "warning: %s was lost", fn_root(finfo->fullname));
		ret = T_CHECKOUT;
	    }
	    else if (!strcmp (vers->ts_user, vers->ts_rcs))
	    {

		/*
		 * The user file is still unmodified, so just get it as well
		 */
		if (!options_same(vers->entdata->options,vers->options))
		    ret = T_CHECKOUT;
		else
		    ret = T_PATCH;
	    }
		else if (No_Difference (finfo, vers, (kf.flags&KFLAG_STATIC || kf_ent.flags&KFLAG_STATIC), ignore_keywords))
			/* really modified, needs to merge */
			ret = T_NEEDS_MERGE;
	    else if(!options_same(vers->entdata->options,vers->options))
			/* not really modified, check it out */
			ret = T_CHECKOUT;
	    else
			ret = T_PATCH;
	}
    }

    /* free up the vers struct, or just return it */
    if (versp != (Vers_TS **) NULL)
	*versp = vers;
    else
	freevers_ts (&vers);

    /* return the status of the file */
    return (ret);
}