text: /*	$OpenBSD: modes.c,v 1.18 2008/06/14 08:46:30 kjell Exp $	*/
  
  /* This file is in the public domain. */
  
  /*
   * Commands to toggle modes.   Without an argument, these functions will
   * toggle the given mode.  A negative or zero argument will turn the mode
   * off.  A positive argument will turn the mode on.
   */
  
  #include "def.h"
  #include "kbd.h"
  
  int	changemode(int, int, char *);
  
  int	 defb_nmodes = 0;
  struct maps_s	*defb_modes[PBMODES] = { &fundamental_mode };
  int	 defb_flag = 0;
  
  int
  changemode(int f, int n, char *mode)
  {
  	int	 i;
  	struct maps_s	*m;
  
  	if ((m = name_mode(mode)) == NULL) {
  		ewprintf("Can't find mode %s", mode);
  		return (FALSE);
  	}
  	if (!(f & FFARG)) {
  		for (i = 0; i <= curbp->b_nmodes; i++)
  			if (curbp->b_modes[i] == m) {
  				/* mode already set */
  				n = 0;
  				break;
  			}
  	}
  	if (n > 0) {
  		for (i = 0; i <= curbp->b_nmodes; i++)
  			if (curbp->b_modes[i] == m)
  				/* mode already set */
  				return (TRUE);
  		if (curbp->b_nmodes >= PBMODES - 1) {
  			ewprintf("Too many modes");
  			return (FALSE);
  		}
  		curbp->b_modes[++(curbp->b_nmodes)] = m;
  	} else {
  		/* fundamental is b_modes[0] and can't be unset */
  		for (i = 1; i <= curbp->b_nmodes && m != curbp->b_modes[i];
  		    i++);
  		if (i > curbp->b_nmodes)
  			return (TRUE);	/* mode wasn't set */
  		for (; i < curbp->b_nmodes; i++)
  			curbp->b_modes[i] = curbp->b_modes[i + 1];
  		curbp->b_nmodes--;
  	}
  	upmodes(curbp);
  	return (TRUE);
  }
  
  int
  indentmode(int f, int n)
  {
  	return (changemode(f, n, "indent"));
  }
  
  int
  fillmode(int f, int n)
  {
  	return (changemode(f, n, "fill"));
  }
  
  #ifdef NOTAB
  int
  notabmode(int f, int n)
  {
  	if (changemode(f, n, "notab") == FALSE)
  		return (FALSE);
  	if (f & FFARG) {
  		if (n <= 0)
  			curbp->b_flag &= ~BFNOTAB;
  		else
  			curbp->b_flag |= BFNOTAB;
  	} else
  		curbp->b_flag ^= BFNOTAB;
  	return (TRUE);
  }
  #endif	/* NOTAB */
  
  int
  overwrite_mode(int f, int n)
  {
  	if (changemode(f, n, "overwrite") == FALSE)
  		return (FALSE);
  	if (f & FFARG) {
  		if (n <= 0)
  			curbp->b_flag &= ~BFOVERWRITE;
  		else
  			curbp->b_flag |= BFOVERWRITE;
  	} else
  		curbp->b_flag ^= BFOVERWRITE;
  	return (TRUE);
  }
  
  int
  set_default_mode(int f, int n)
  {
  	int	 i;
  	struct maps_s	*m;
  	char	 modebuf[32], *bufp;
  
  	if ((bufp = eread("Set Default Mode: ", modebuf, sizeof(modebuf),
  	    EFNEW)) == NULL)
  		return (ABORT);
  	else if (bufp[0] == '\0')
  		return (FALSE);
  	if ((m = name_mode(modebuf)) == NULL) {
  		ewprintf("can't find mode %s", modebuf);
  		return (FALSE);
  	}
  	if (!(f & FFARG)) {
  		for (i = 0; i <= defb_nmodes; i++)
  			if (defb_modes[i] == m) {
  				/* mode already set */
  				n = 0;
  				break;
  			}
  	}
  	if (n > 0) {
  		for (i = 0; i <= defb_nmodes; i++)
  			if (defb_modes[i] == m)
  				/* mode already set */
  				return (TRUE);
  		if (defb_nmodes >= PBMODES - 1) {
  			ewprintf("Too many modes");
  			return (FALSE);
  		}
  		defb_modes[++defb_nmodes] = m;
  	} else {
  		/* fundamental is defb_modes[0] and can't be unset */
  		for (i = 1; i <= defb_nmodes && m != defb_modes[i]; i++);
  		if (i > defb_nmodes)
  			/* mode was not set */
  			return (TRUE);
  		for (; i < defb_nmodes; i++)
  			defb_modes[i] = defb_modes[i + 1];
  		defb_nmodes--;
  	}
  	if (strcmp(modebuf, "overwrite") == 0) {
  		if (n <= 0)
  			defb_flag &= ~BFOVERWRITE;
  		else
  			defb_flag |= BFOVERWRITE;
  	}
  #ifdef NOTAB
  	if (strcmp(modebuf, "notab") == 0) {
  		if (n <= 0)
  			defb_flag &= ~BFNOTAB;
  		else
  			defb_flag |= BFNOTAB;
  	}
  #endif	/* NOTAB */
  	return (TRUE);
  }
  