if (mynewattr != NULL) free (mynewattr);
watch_modify_watchers (file, what)    char *file;    struct addremove_args *what;{    char *curattr = fileattr_get0 (file, "_watchers");    char *p;    char *pend;    char *nextp;    char *who;    int who_len;    char *mycurattr;    char *mynewattr;    size_t mynewattr_size;    int add_edit_pending;    int add_unedit_pending;    int add_commit_pending;    int remove_edit_pending;    int remove_unedit_pending;    int remove_commit_pending;    int add_tedit_pending;    int add_tunedit_pending;    int add_tcommit_pending;    who = getcaller ();    who_len = strlen (who);    /* Look for current watcher types for this user.  */    mycurattr = NULL;    if (curattr != NULL)    {	p = curattr;	while (1) {	    if (strncmp (who, p, who_len) == 0		&& p[who_len] == '>')	    {		/* Found this user.  */		mycurattr = p + who_len + 1;	    }	    p = strchr (p, ',');	    if (p == NULL)		break;	    ++p;	}    }    if (mycurattr != NULL)    {	mycurattr = xstrdup (mycurattr);	p = strchr (mycurattr, ',');	if (p != NULL)	    *p = '\0';    }    /* Now copy mycurattr to mynewattr, making the requisite modifications.       Note that we add a dummy '+' to the start of mynewattr, to reduce       special cases (but then we strip it off when we are done).  */    mynewattr_size = sizeof "+edit+unedit+commit+tedit+tunedit+tcommit";    if (mycurattr != NULL)	mynewattr_size += strlen (mycurattr);    mynewattr = xmalloc (mynewattr_size);    mynewattr[0] = '\0';    add_edit_pending = what->adding && what->edit;    add_unedit_pending = what->adding && what->unedit;    add_commit_pending = what->adding && what->commit;    remove_edit_pending = !what->adding && what->edit;    remove_unedit_pending = !what->adding && what->unedit;    remove_commit_pending = !what->adding && what->commit;    add_tedit_pending = what->add_tedit;    add_tunedit_pending = what->add_tunedit;    add_tcommit_pending = what->add_tcommit;    /* Copy over existing watch types, except those to be removed.  */    p = mycurattr;    while (p != NULL)    {	pend = strchr (p, '+');	if (pend == NULL)	{	    pend = p + strlen (p);	    nextp = NULL;	}	else	    nextp = pend + 1;	/* Process this item.  */	if (pend - p == 4 && strncmp ("edit", p, 4) == 0)	{	    if (!remove_edit_pending)		strcat (mynewattr, "+edit");	    add_edit_pending = 0;	}	else if (pend - p == 6 && strncmp ("unedit", p, 6) == 0)	{	    if (!remove_unedit_pending)		strcat (mynewattr, "+unedit");	    add_unedit_pending = 0;	}	else if (pend - p == 6 && strncmp ("commit", p, 6) == 0)	{	    if (!remove_commit_pending)		strcat (mynewattr, "+commit");	    add_commit_pending = 0;	}	else if (pend - p == 5 && strncmp ("tedit", p, 5) == 0)	{	    if (!what->remove_temp)		strcat (mynewattr, "+tedit");	    add_tedit_pending = 0;	}	else if (pend - p == 7 && strncmp ("tunedit", p, 7) == 0)	{	    if (!what->remove_temp)		strcat (mynewattr, "+tunedit");	    add_tunedit_pending = 0;	}	else if (pend - p == 7 && strncmp ("tcommit", p, 7) == 0)	{	    if (!what->remove_temp)		strcat (mynewattr, "+tcommit");	    add_tcommit_pending = 0;	}	else	{	    char *mp;	    /* Copy over any unrecognized watch types, for future	       expansion.  */	    mp = mynewattr + strlen (mynewattr);	    *mp++ = '+';	    strncpy (mp, p, pend - p);	    *(mp + (pend - p)) = '\0';	}	/* Set up for next item.  */	p = nextp;    }    /* Add in new watch types.  */    if (add_edit_pending)	strcat (mynewattr, "+edit");    if (add_unedit_pending)	strcat (mynewattr, "+unedit");    if (add_commit_pending)	strcat (mynewattr, "+commit");    if (add_tedit_pending)	strcat (mynewattr, "+tedit");    if (add_tunedit_pending)	strcat (mynewattr, "+tunedit");    if (add_tcommit_pending)	strcat (mynewattr, "+tcommit");    {	char *curattr_new;	curattr_new =	  fileattr_modify (curattr,			   who,			   mynewattr[0] == '\0' ? NULL : mynewattr + 1,			   '>',			   ',');	/* If the attribute is unchanged, don't rewrite the attribute file.  */	if (!((curattr_new == NULL && curattr == NULL)	      || (curattr_new != NULL		  && curattr != NULL		  && strcmp (curattr_new, curattr) == 0)))	    fileattr_set (file,			  "_watchers",			  curattr_new);	if (curattr_new != NULL)	    free (curattr_new);    }    if (curattr != NULL)	free (curattr);    if (mycurattr != NULL)	free (mycurattr);}