To: vim_dev@googlegroups.com
Subject: Patch 7.3.377
Fcc: outbox
From: Bram Moolenaar <Bram@moolenaar.net>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
------------

Patch 7.3.377
Problem:    No support for bitwise AND, OR, XOR and invert.
Solution:   Add and(), or(), invert() and xor() functions.
Files:	    src/eval.c, src/testdir/test49.in, src/testdir/test65.in,
	    src/testdir/test65.ok, runtime/doc/eval.txt


*** ../vim-7.3.376/src/eval.c	2011-11-30 15:19:25.000000000 +0100
--- src/eval.c	2011-12-11 13:49:31.000000000 +0100
***************
*** 474,479 ****
--- 474,480 ----
  static void f_acos __ARGS((typval_T *argvars, typval_T *rettv));
  #endif
  static void f_add __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_and __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_append __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_argc __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_argidx __ARGS((typval_T *argvars, typval_T *rettv));
***************
*** 602,607 ****
--- 603,609 ----
  static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_insert __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_invert __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_items __ARGS((typval_T *argvars, typval_T *rettv));
***************
*** 640,645 ****
--- 642,648 ----
  #endif
  static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_or __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_pathshorten __ARGS((typval_T *argvars, typval_T *rettv));
  #ifdef FEAT_FLOAT
  static void f_pow __ARGS((typval_T *argvars, typval_T *rettv));
***************
*** 751,756 ****
--- 754,760 ----
  static void f_winsaveview __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_xor __ARGS((typval_T *argvars, typval_T *rettv));
  
  static int list2fpos __ARGS((typval_T *arg, pos_T *posp, int *fnump));
  static pos_T *var2fpos __ARGS((typval_T *varp, int dollar_lnum, int *fnum));
***************
*** 7715,7720 ****
--- 7719,7725 ----
      {"acos",		1, 1, f_acos},	/* WJMc */
  #endif
      {"add",		2, 2, f_add},
+     {"and",		2, 2, f_and},
      {"append",		2, 2, f_append},
      {"argc",		0, 0, f_argc},
      {"argidx",		0, 0, f_argidx},
***************
*** 7850,7855 ****
--- 7855,7861 ----
      {"inputsave",	0, 0, f_inputsave},
      {"inputsecret",	1, 2, f_inputsecret},
      {"insert",		2, 3, f_insert},
+     {"invert",		1, 1, f_invert},
      {"isdirectory",	1, 1, f_isdirectory},
      {"islocked",	1, 1, f_islocked},
      {"items",		1, 1, f_items},
***************
*** 7888,7893 ****
--- 7894,7900 ----
  #endif
      {"nextnonblank",	1, 1, f_nextnonblank},
      {"nr2char",		1, 1, f_nr2char},
+     {"or",		2, 2, f_or},
      {"pathshorten",	1, 1, f_pathshorten},
  #ifdef FEAT_FLOAT
      {"pow",		2, 2, f_pow},
***************
*** 7999,8004 ****
--- 8006,8012 ----
      {"winsaveview",	0, 0, f_winsaveview},
      {"winwidth",	1, 1, f_winwidth},
      {"writefile",	2, 3, f_writefile},
+     {"xor",		2, 2, f_xor},
  };
  
  #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
***************
*** 8572,8577 ****
--- 8580,8597 ----
  }
  
  /*
+  * "and(expr, expr)" function
+  */
+     static void
+ f_and(argvars, rettv)
+     typval_T	*argvars;
+     typval_T	*rettv;
+ {
+     rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL)
+ 					& get_tv_number_chk(&argvars[1], NULL);
+ }
+ 
+ /*
   * "append(lnum, string/list)" function
   */
      static void
***************
*** 12958,12963 ****
--- 12978,12994 ----
  }
  
  /*
+  * "invert(expr)" function
+  */
+     static void
+ f_invert(argvars, rettv)
+     typval_T	*argvars;
+     typval_T	*rettv;
+ {
+     rettv->vval.v_number = ~get_tv_number_chk(&argvars[0], NULL);
+ }
+ 
+ /*
   * "isdirectory()" function
   */
      static void
***************
*** 14108,14113 ****
--- 14139,14156 ----
  }
  
  /*
+  * "or(expr, expr)" function
+  */
+     static void
+ f_or(argvars, rettv)
+     typval_T	*argvars;
+     typval_T	*rettv;
+ {
+     rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL)
+ 					| get_tv_number_chk(&argvars[1], NULL);
+ }
+ 
+ /*
   * "pathshorten()" function
   */
      static void
***************
*** 18394,18399 ****
--- 18437,18455 ----
  }
  
  /*
+  * "xor(expr, expr)" function
+  */
+     static void
+ f_xor(argvars, rettv)
+     typval_T	*argvars;
+     typval_T	*rettv;
+ {
+     rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL)
+ 					^ get_tv_number_chk(&argvars[1], NULL);
+ }
+ 
+ 
+ /*
   * Translate a String variable into a position.
   * Returns NULL when there is an error.
   */
*** ../vim-7.3.376/src/testdir/test65.in	2010-08-15 21:57:29.000000000 +0200
--- src/testdir/test65.in	2011-12-11 13:55:06.000000000 +0100
***************
*** 1,4 ****
! Test for floating point.
  
  STARTTEST
  :so small.vim
--- 1,4 ----
! Test for floating point and logical operators.
  
  STARTTEST
  :so small.vim
***************
*** 72,77 ****
--- 72,94 ----
  :$put ='float2nr'
  :$put =float2nr(123.456)
  :$put =float2nr(-123.456)
+ :$put ='AND'
+ :$put =and(127, 127)
+ :$put =and(127, 16)
+ :$put =and(127, 128)
+ :$put ='OR'
+ :$put =or(16, 7)
+ :$put =or(8, 7)
+ :$put =or(0, 123)
+ :$put ='XOR'
+ :$put =xor(127, 127)
+ :$put =xor(127, 16)
+ :$put =xor(127, 128)
+ :$put ='invert'
+ :$put =and(invert(127), 65535)
+ :$put =and(invert(16), 65535)
+ :$put =and(invert(128), 65535)
+ :$put =invert(1.0)
  :/^Results/,$wq! test.out
  ENDTEST
  
*** ../vim-7.3.376/src/testdir/test65.ok	2010-08-15 21:57:29.000000000 +0200
--- src/testdir/test65.ok	2011-12-11 13:55:30.000000000 +0100
***************
*** 54,56 ****
--- 54,73 ----
  float2nr
  123
  -123
+ AND
+ 127
+ 16
+ 0
+ OR
+ 23
+ 15
+ 123
+ XOR
+ 0
+ 111
+ 255
+ invert
+ 65408
+ 65519
+ 65407
+ 0
*** ../vim-7.3.376/runtime/doc/eval.txt	2011-06-19 02:55:32.000000000 +0200
--- runtime/doc/eval.txt	2011-12-14 15:28:23.000000000 +0100
***************
*** 798,808 ****
  For |Lists| only "+" is possible and then both expr6 must be a list.  The
  result is a new list with the two lists Concatenated.
  
! expr7 *	 expr7 ..	number multiplication			*expr-star*
! expr7 /	 expr7 ..	number division				*expr-/*
! expr7 %	 expr7 ..	number modulo				*expr-%*
  
  For all, except ".", Strings are converted to Numbers.
  
  Note the difference between "+" and ".":
  	"123" + "456" = 579
--- 800,811 ----
  For |Lists| only "+" is possible and then both expr6 must be a list.  The
  result is a new list with the two lists Concatenated.
  
! expr7 *	 expr7 ..	Number multiplication			*expr-star*
! expr7 /	 expr7 ..	Number division				*expr-/*
! expr7 %	 expr7 ..	Number modulo				*expr-%*
  
  For all, except ".", Strings are converted to Numbers.
+ For bitwise operators see |and()|, |or()| and |xor()|.
  
  Note the difference between "+" and ".":
  	"123" + "456" = 579
***************
*** 1679,1684 ****
--- 1688,1694 ----
  abs( {expr})			Float or Number  absolute value of {expr}
  acos( {expr})			Float	arc cosine of {expr}
  add( {list}, {item})		List	append {item} to |List| {list}
+ and( {expr}, {expr})		Number  bitwise AND
  append( {lnum}, {string})	Number	append {string} below line {lnum}
  append( {lnum}, {list})		Number	append lines {list} below line {lnum}
  argc()				Number	number of files in the argument list
***************
*** 1817,1822 ****
--- 1827,1833 ----
  inputsave()			Number	save and clear typeahead
  inputsecret( {prompt} [, {text}]) String  like input() but hiding the text
  insert( {list}, {item} [, {idx}]) List	insert {item} in {list} [before {idx}]
+ invert( {expr})			Number  bitwise invert
  isdirectory( {directory})	Number	TRUE if {directory} is a directory
  islocked( {expr})		Number	TRUE if {expr} is locked
  items( {dict})			List	key-value pairs in {dict}
***************
*** 1856,1861 ****
--- 1868,1874 ----
  mzeval( {expr})			any	evaluate |MzScheme| expression
  nextnonblank( {lnum})		Number	line nr of non-blank line >= {lnum}
  nr2char( {expr})		String	single char with ASCII value {expr}
+ or( {expr}, {expr})		Number  bitwise OR
  pathshorten( {expr})		String	shorten directory names in a path
  pow( {x}, {y})			Float	{x} to the power of {y}
  prevnonblank( {lnum})		Number	line nr of non-blank line <= {lnum}
***************
*** 1978,1983 ****
--- 1992,1998 ----
  winwidth( {nr})			Number	width of window {nr}
  writefile( {list}, {fname} [, {binary}])
  				Number	write list of lines to file {fname}
+ xor( {expr}, {expr})		Number  bitwise XOR
  
  abs({expr})							*abs()*
  		Return the absolute value of {expr}.  When {expr} evaluates to
***************
*** 2017,2022 ****
--- 2032,2044 ----
  		Use |insert()| to add an item at another position.
  
  
+ and({expr}, {expr})					*and()*
+ 		Bitwise AND on the two arguments.  The arguments are converted
+ 		to a number.  A List, Dict or Float argument causes an error.
+ 		Example: >
+ 			:let flag = and(bits, 0x80)
+ 
+ 
  append({lnum}, {expr})					*append()*
  		When {expr} is a |List|: Append each item of the |List| as a
  		text line below line {lnum} in the current buffer.
***************
*** 3770,3775 ****
--- 3798,3808 ----
  		Note that when {item} is a |List| it is inserted as a single
  		item.  Use |extend()| to concatenate |Lists|.
  
+ invert({expr})						*invert()*
+ 		Bitwise invert.  The argument is converted to a number.  A
+ 		List, Dict or Float argument causes an error.  Example: >
+ 			:let bits = invert(bits)
+ 
  isdirectory({directory})				*isdirectory()*
  		The result is a Number, which is non-zero when a directory
  		with the name {directory} exists.  If {directory} doesn't
***************
*** 4334,4339 ****
--- 4368,4380 ----
  			call setpos('.', save_cursor)
  <		Also see |setpos()|.
  
+ or({expr}, {expr})					*or()*
+ 		Bitwise OR on the two arguments.  The arguments are converted
+ 		to a number.  A List, Dict or Float argument causes an error.
+ 		Example: >
+ 			:let bits = or(bits, 0x80)
+ 
+ 
  pathshorten({expr})					*pathshorten()*
  		Shorten directory names in the path {expr} and return the
  		result.  The tail, the file name, is kept as-is.  The other
***************
*** 6097,6103 ****
  		To copy a file byte for byte: >
  			:let fl = readfile("foo", "b")
  			:call writefile(fl, "foocopy", "b")
! <
  
  							*feature-list*
  There are three types of features:
--- 6149,6163 ----
  		To copy a file byte for byte: >
  			:let fl = readfile("foo", "b")
  			:call writefile(fl, "foocopy", "b")
! 
! 
! xor({expr}, {expr})					*xor()*
! 		Bitwise XOR on the two arguments.  The arguments are converted
! 		to a number.  A List, Dict or Float argument causes an error.
! 		Example: >
! 			:let bits = xor(bits, 0x80)
! 
! 
  
  							*feature-list*
  There are three types of features:
*** ../vim-7.3.376/src/version.c	2011-12-14 15:23:53.000000000 +0100
--- src/version.c	2011-12-14 15:28:39.000000000 +0100
***************
*** 716,717 ****
--- 716,719 ----
  {   /* Add new patch number below this line */
+ /**/
+     377,
  /**/

-- 
DINGO: Wicked wicked Zoot ... she is a bad person and she must pay the
       penalty.  And here in Castle Anthrax, we have but one punishment
       ... you must tie her down on a bed ... and spank her.  Come!
GIRLS: A spanking!  A spanking!
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///
