Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package bitwise for openSUSE:Factory checked 
in at 2026-09-04 12:38:55
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/bitwise (Old)
 and      /work/SRC/openSUSE:Factory/.bitwise.new.1265 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "bitwise"

Fri Sep  4 12:38:55 2026 rev:5 rq:1375433 version:0.60

Changes:
--------
--- /work/SRC/openSUSE:Factory/bitwise/bitwise.changes  2023-08-28 
17:13:06.520112022 +0200
+++ /work/SRC/openSUSE:Factory/.bitwise.new.1265/bitwise.changes        
2026-09-04 12:39:43.137128261 +0200
@@ -1,0 +2,8 @@
+Wed Sep  2 10:51:25 UTC 2026 - Martin Hauke <[email protected]>
+
+- Update to version 0.60
+  * Fix binary prefix parsing.
+  * Add set, clear, toggle and test bit operators.
+  * Fix readline path resolution for Apple Silicon.
+
+-------------------------------------------------------------------

Old:
----
  bitwise-0.50.tar.gz

New:
----
  bitwise-0.60.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ bitwise.spec ++++++
--- /var/tmp/diff_new_pack.mh4BFl/_old  2026-09-04 12:39:44.009158894 +0200
+++ /var/tmp/diff_new_pack.mh4BFl/_new  2026-09-04 12:39:44.011158965 +0200
@@ -1,8 +1,8 @@
 #
 # spec file for package bitwise
 #
-# Copyright (c) 2023 SUSE LLC
-# Copyright (c) 2020-2021, Martin Hauke <[email protected]>
+# Copyright (c) 2026 SUSE LLC and contributors
+# Copyright (c) 2020-2026, Martin Hauke <[email protected]>
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 
 Name:           bitwise
-Version:        0.50
+Version:        0.60
 Release:        0
 Summary:        Interactive bit-wise operation in ncurses
 License:        GPL-3.0-or-later

++++++ bitwise-0.50.tar.gz -> bitwise-0.60.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitwise-0.50/.github/workflows/build-osx.yaml 
new/bitwise-0.60/.github/workflows/build-osx.yaml
--- old/bitwise-0.50/.github/workflows/build-osx.yaml   2023-07-20 
22:23:10.000000000 +0200
+++ new/bitwise-0.60/.github/workflows/build-osx.yaml   2026-08-22 
11:35:36.000000000 +0200
@@ -1,4 +1,4 @@
-name: C/C++ CI
+name: C build (OSX)
 
 on:
   push:
@@ -8,16 +8,16 @@
 
 jobs:
   build:
-    env:
-      LDFLAGS: "-L/usr/local/opt/readline/lib"
-      CPPFLAGS: "-I/usr/local/opt/readline/include"
-
     runs-on: macos-latest
 
     steps:
     - uses: actions/checkout@v2
     - name: Install lib-cunit
       run: brew install readline cunit autoconf automake
+    - name: Set readline/cunit flags
+      run: |
+        echo "CPPFLAGS=-I$(brew --prefix readline)/include -I$(brew --prefix 
cunit)/include" >> "$GITHUB_ENV"
+        echo "LDFLAGS=-L$(brew --prefix readline)/lib -L$(brew --prefix 
cunit)/lib" >> "$GITHUB_ENV"
     - name: Bootstrap
       run: ./bootstrap.sh
     - name: configure
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitwise-0.50/.github/workflows/c-cpp.yml 
new/bitwise-0.60/.github/workflows/c-cpp.yml
--- old/bitwise-0.50/.github/workflows/c-cpp.yml        2023-07-20 
22:23:10.000000000 +0200
+++ new/bitwise-0.60/.github/workflows/c-cpp.yml        2026-08-22 
11:35:36.000000000 +0200
@@ -14,7 +14,7 @@
     steps:
     - uses: actions/checkout@v2
     - name: Install xmllint
-      run: sudo apt-get install libcunit1-dev
+      run: sudo apt-get install libcunit1-dev libreadline-dev
     - name: Bootstrap
       run: ./bootstrap.sh
     - name: configure
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitwise-0.50/Makefile.am new/bitwise-0.60/Makefile.am
--- old/bitwise-0.50/Makefile.am        2023-07-20 22:23:10.000000000 +0200
+++ new/bitwise-0.60/Makefile.am        2026-08-22 11:35:36.000000000 +0200
@@ -1,9 +1,10 @@
 bin_PROGRAMS=bitwise
-bitwise_SOURCES= src/main.c src/misc.c \
+bitwise_SOURCES= src/main.c src/misc.c src/compat.c\
                                 src/interactive.c src/cmd.c \
                                 src/stack.c src/shunting-yard.c \
-                                src/help.c inc/bitwise.h inc/stack.h \
-                                inc/shunting-yard.h
+                                src/help.c inc/bitwise.h \
+                                inc/stack.h inc/shunting-yard.h \
+                                inc/compat.h
 
 dist_man_MANS=bitwise.1
 
@@ -24,7 +25,7 @@
 check_PROGRAMS = tests/test-shunting-yard
 tests_test_shunting_yard_SOURCES = src/shunting-yard.c inc/shunting-yard.h \
                                    src/stack.c inc/stack.h inc/bitwise.h \
-                                                                  src/misc.c \
+                                  src/misc.c src/compat.c \
                                    tests/test-shunting-yard.c
 tests_test_shunting_yard_LDADD = -lcunit
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitwise-0.50/README.md new/bitwise-0.60/README.md
--- old/bitwise-0.50/README.md  2023-07-20 22:23:10.000000000 +0200
+++ new/bitwise-0.60/README.md  2026-08-22 11:35:36.000000000 +0200
@@ -1,6 +1,5 @@
 # Bitwise
 ## Terminal based bitwise calculator in curses
-[![Build 
Status](https://travis-ci.org/mellowcandle/bitwise.svg?branch=master)](https://travis-ci.org/mellowcandle/bitwise)[![codecov](https://codecov.io/gh/mellowcandle/bitwise/branch/master/graph/badge.svg)](https://codecov.io/gh/mellowcandle/bitwise)
 [![Snap 
Status](https://build.snapcraft.io/badge/mellowcandle/bitwise.svg)](https://build.snapcraft.io/user/mellowcandle/bitwise)<a
 href="https://scan.coverity.com/projects/mellowcandle-bitwise";>
   <img alt="Coverity Scan Build Status"
        src="https://img.shields.io/coverity/scan/18170.svg"/>
@@ -88,6 +87,7 @@
 ###### operators and functions
 * All C operators are supported, additionally, you can use the "$" symbol to 
refer to the last result.
 * Refer to a specific bit by using the function _BIT(x)_.
+* Set, clear, toggle or test a bit using `$ |= BIT(n)`, `$ &= ~BIT(n)`, `$ ^= 
BIT(n)` and `$ & BIT(n)`.
 
 ###### commands
 * _h(elp)_ - Show the help screen.
@@ -157,7 +157,7 @@
 ```
 
 ### Windows
-NCurses doesn't support Windows. You can use the Windows Subsystem for Linux 
as a workaround.
+Bitwise is possible to compile on Windows under mingw or msys2
 
 ### Nix
 ```
@@ -183,8 +183,9 @@
 brew install automake
 brew install autoconf
 brew install readline
-export LDFLAGS="-L/usr/local/opt/readline/lib"
-export CPPFLAGS="-I/usr/local/opt/readline/include"
+brew install cunit
+export LDFLAGS="-L$(brew --prefix readline)/lib -L$(brew --prefix cunit)/lib"
+export CPPFLAGS="-I$(brew --prefix readline)/include -I$(brew --prefix 
cunit)/include"
 ```
 - Download [the latest 
release](https://github.com/mellowcandle/bitwise/releases/latest)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitwise-0.50/bitwise.1 new/bitwise-0.60/bitwise.1
--- old/bitwise-0.50/bitwise.1  2023-07-20 22:23:10.000000000 +0200
+++ new/bitwise-0.60/bitwise.1  2026-08-22 11:35:36.000000000 +0200
@@ -1,5 +1,5 @@
 .\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.47.10.
-.TH BITWISE "1" "July 2023" "bitwise v0.50" "User Commands"
+.TH BITWISE "1" "August 2026" "bitwise v0.60" "User Commands"
 .SH NAME
 bitwise \- Terminal based bit manipulator in ncurses
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitwise-0.50/configure.ac 
new/bitwise-0.60/configure.ac
--- old/bitwise-0.50/configure.ac       2023-07-20 22:23:10.000000000 +0200
+++ new/bitwise-0.60/configure.ac       2026-08-22 11:35:36.000000000 +0200
@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ([2.69])
-AC_INIT([bitwise], [v0.50], [[email protected]])
+AC_INIT([bitwise], [v0.60], [[email protected]])
 AC_CONFIG_SRCDIR([src/misc.c])
 AC_CONFIG_HEADERS([inc/config.h])
 
@@ -15,6 +15,7 @@
 
 # Checks for programs.
 AC_PROG_CC
+AM_PROG_CC_C_O
 AC_PROG_CC_STDC
 AC_PROG_INSTALL
 AC_PROG_CC_C99
@@ -24,13 +25,17 @@
     AC_MSG_ERROR([requires readline library])
 fi
 
+# Checks for header files. Ncurses is a bit of a mess in windows/mingw, has 
form in separate include location
+AC_CHECK_HEADERS([fcntl.h inttypes.h stdint.h stdlib.h string.h curses.h 
form.h ncursesw/ncurses.h ncursesw/form.h])
+
 # Checks for libraries.
 AC_CHECK_LIB([form], [form_driver])
+AC_CHECK_LIB([formw], [form_driver])
 AC_CHECK_LIB([ncurses], [newwin])
+AC_CHECK_LIB([ncursesw], [newwin])
 AC_SEARCH_LIBS([sqrt], [m])
 
-# Checks for header files.
-AC_CHECK_HEADERS([fcntl.h inttypes.h stdint.h stdlib.h string.h curses.h 
form.h])
+
 
 AC_CHECK_DECLS([bswap_32], [], [], [[#include <byteswap.h>]])
 AM_CONDITIONAL(HAVE_BYTESWAP_H, [test "x$ac_cv_have_decl_bswap_32" = "xyes"])
@@ -41,7 +46,31 @@
 
 # Checks for library functions.
 AC_FUNC_STRCOLL
-AC_CHECK_FUNCS([memchr memmove memset stpcpy strchr strcspn strdup strerror 
strpbrk strrchr strspn strstr])
+AC_CHECK_FUNCS([memchr memmove memset stpcpy strchr strcspn strdup strndup 
strerror strpbrk strrchr strspn strstr l64a])
+
+# Then check for the variable considering both possible locations
+AC_CHECK_DECL([rl_change_environment],
+    [AC_DEFINE([HAVE_RL_CHANGE_ENVIRONMENT], [1], [Define if 
rl_change_environment is available])],
+    [AC_MSG_WARN([rl_change_environment not found])],
+    [[#ifdef HAVE_READLINE_H
+      #include <readline.h>
+      #endif
+      #ifdef HAVE_READLINE_READLINE_H
+      #include <readline/readline.h>
+      #endif
+    ]])
+
+AC_CHECK_DECL([rl_input_available_hook],
+    [AC_DEFINE([HAVE_RL_INPUT_AVAILABLE_HOOK], [1], [Define if 
rl_input_available_hook is available])],
+    [AC_MSG_WARN([rl_input_available_hook not found])],
+    [[#ifdef HAVE_READLINE_H
+      #include <readline.h>
+      #endif
+      #ifdef HAVE_READLINE_READLINE_H
+      #include <readline/readline.h>
+      #endif
+    ]])
+
 
 AC_CONFIG_FILES([Makefile])
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitwise-0.50/inc/bitwise.h 
new/bitwise-0.60/inc/bitwise.h
--- old/bitwise-0.50/inc/bitwise.h      2023-07-20 22:23:10.000000000 +0200
+++ new/bitwise-0.60/inc/bitwise.h      2026-08-22 11:35:36.000000000 +0200
@@ -9,11 +9,15 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdbool.h>
-#include <form.h>
 #include <string.h>
 #include "config.h"
+#include "compat.h"
+#if defined(HAVE_NCURSESW_FORM_H)
+#include <ncursesw/form.h>
+#else
+#include <form.h>
+#endif
 /* Readine checks */
-
 #ifdef HAVE_LIBREADLINE
 #  if defined(HAVE_READLINE_READLINE_H)
 #    include <readline/readline.h>
@@ -68,6 +72,7 @@
 
 void init_terminal(void);
 void deinit_terminal(void);
+const char *ipv4_to_str(uint32_t ip, char out[static 16]);
 
 /* Interactive */
 extern FORM *form;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitwise-0.50/inc/compat.h 
new/bitwise-0.60/inc/compat.h
--- old/bitwise-0.50/inc/compat.h       1970-01-01 01:00:00.000000000 +0100
+++ new/bitwise-0.60/inc/compat.h       2026-08-22 11:35:36.000000000 +0200
@@ -0,0 +1,14 @@
+#ifndef COMPAT_H
+#define COMPAT_H
+// Functions needed to substitute some POSIX extensions on Windows/MinGW
+
+#ifndef HAVE_STRNDUP
+char *strndup(const char *s, size_t n);
+#endif
+
+#ifndef HAVE_L64A
+char *l64a(long value);
+#endif
+
+#endif
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitwise-0.50/src/cmd.c new/bitwise-0.60/src/cmd.c
--- old/bitwise-0.50/src/cmd.c  2023-07-20 22:23:10.000000000 +0200
+++ new/bitwise-0.60/src/cmd.c  2026-08-22 11:35:36.000000000 +0200
@@ -4,6 +4,7 @@
 #include <string.h>
 #include <inttypes.h>
 #include <ctype.h>
+#include <unistd.h>
 #include "bitwise.h"
 #include "shunting-yard.h"
 
@@ -225,6 +226,12 @@
 
 static int readline_getc(FILE *dummy)
 {
+#ifndef HAVE_RL_INPUT_AVAILABLE_HOOK
+       /* Block until input is available when hook is not supported */
+       while (!g_input_avail) {
+               usleep(1000);
+       }
+#endif
        g_input_avail = false;
        return g_input;
 }
@@ -272,9 +279,13 @@
        rl_catch_sigwinch = 0;
        rl_deprep_term_function = NULL;
        rl_prep_term_function = NULL;
+#ifdef HAVE_RL_CHANGE_ENVIRONMENT
        rl_change_environment = 0;
+#endif
        rl_getc_function = readline_getc;
+#ifdef HAVE_RL_INPUT_AVAILABLE_HOOK
        rl_input_available_hook = readline_input_avail;
+#endif
        rl_redisplay_function = readline_redisplay;
        //rl_bind_key('\t', rl_insert);
        rl_callback_handler_install(":", got_command);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitwise-0.50/src/compat.c 
new/bitwise-0.60/src/compat.c
--- old/bitwise-0.50/src/compat.c       1970-01-01 01:00:00.000000000 +0100
+++ new/bitwise-0.60/src/compat.c       2026-08-22 11:35:36.000000000 +0200
@@ -0,0 +1,56 @@
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <stdint.h>
+
+#ifndef HAVE_STRNDUP
+char *strndup(const char *s, size_t n)
+{
+    char *copy;
+    size_t len;
+
+    if (!s) {
+        return NULL;  // Handle NULL input safely
+    }
+
+    // Determine the number of characters to copy (up to n or up to '\0')
+    len = 0;
+    while (len < n && s[len] != '\0') {
+        len++;
+    }
+
+    // Prevent overflow: len + 1 must not overflow size_t
+    if (len == SIZE_MAX) {
+        return NULL; // extremely unlikely but technically correct
+    }
+
+    copy = (char *)malloc(len + 1);
+    if (!copy) {
+        return NULL;
+    }
+
+    memcpy(copy, s, len);
+    copy[len] = '\0';
+    return copy;
+}
+#endif
+
+
+#ifndef HAVE_L64A
+char *l64a(long value)
+{
+    static char buf[7];
+    static const char tbl[] =
+        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+    int i = 0;
+    if (value == 0) {
+        buf[i++] = '.';
+    } else {        while (value && i < 6) {
+            buf[i++] = tbl[value & 0x3F];
+            value >>= 6;
+        }
+    }
+    buf[i] = '\0';
+    return buf;
+}
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitwise-0.50/src/help.c new/bitwise-0.60/src/help.c
--- old/bitwise-0.50/src/help.c 2023-07-20 22:23:10.000000000 +0200
+++ new/bitwise-0.60/src/help.c 2026-08-22 11:35:36.000000000 +0200
@@ -23,7 +23,7 @@
                                       "'q'  Exit back to shell.\n";
 
 static const char *command_mode = "Type expressions or commands, result will 
be appended to history window.\n" \
-                                  "Supported operators: (,),+, -, *, /, !, ~, 
<<_, >>_, BIT(_).\n" \
+                                  "Supported operators: (,),+, -, *, /, !, ~, 
<<_, >>_, BIT(_), |=, &=, ^=.\n" \
                                   "Precedence of operators is defined as C 
language precedence.\n\n" \
                                   "You can referr to the last result with '$' 
inside an expression.\n" \
                                   "To return to interactive mode type 
'ESC'.\n\n" \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitwise-0.50/src/interactive.c 
new/bitwise-0.60/src/interactive.c
--- old/bitwise-0.50/src/interactive.c  2023-07-20 22:23:10.000000000 +0200
+++ new/bitwise-0.60/src/interactive.c  2026-08-22 11:35:36.000000000 +0200
@@ -3,7 +3,6 @@
  */
 
 #include <stdlib.h>
-#include <form.h>
 #include <ctype.h>
 #include <stdint.h>
 #include <inttypes.h>
@@ -14,6 +13,11 @@
 #include <sys/stat.h>
 #include <math.h>
 #include "bitwise.h"
+#if defined(HAVE_NCURSESW_FORM_H)
+#include <ncursesw/form.h>
+#else
+#include <form.h>
+#endif
 
 #define MAX_DEC_DIGITS_64 20
 #define MAX_HEX_DIGITS_64 16
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitwise-0.50/src/main.c new/bitwise-0.60/src/main.c
--- old/bitwise-0.50/src/main.c 2023-07-20 22:23:10.000000000 +0200
+++ new/bitwise-0.60/src/main.c 2026-08-22 11:35:36.000000000 +0200
@@ -8,7 +8,6 @@
 #include <stdint.h>
 #include <getopt.h>
 #include <locale.h>
-#include <arpa/inet.h>
 #include <limits.h>
 
 #ifdef HAVE_DECL_BSWAP_32
@@ -23,14 +22,12 @@
 #include "bitwise.h"
 #include "shunting-yard.h"
 
-
 int print_conversions(uint64_t val, bool si)
 {
        char buf_size[16];
        char binary[512];
        int pos = 0;
        int i, j;
-       struct in_addr ip_addr;
 
        buf_size[0] = '\0';
        sprintf_size(val, buf_size, si);
@@ -69,10 +66,10 @@
        if (val > UINT_MAX) {
                printf("%sIPv4: %s%s\n", color_green, color_blue, "Value too 
big to be a valid IPv4 address");
        } else {
-               ip_addr.s_addr = val;
-               printf("%sIPv4 (Network byte order - Big): %s %s\n", 
color_green, color_blue, inet_ntoa(ip_addr));
-               ip_addr.s_addr = bswap_32(val);
-               printf("%sIPv4 (Reversed byte order - Little): %s %s\n", 
color_green, color_blue, inet_ntoa(ip_addr));
+               char ipstrbuf[16];
+               printf("%sIPv4 (Network byte order - Big): %s %s\n", 
color_green, color_blue, ipv4_to_str(val, ipstrbuf));
+               const uint64_t reversedval = bswap_32(val);
+               printf("%sIPv4 (Reversed byte order - Little): %s %s\n", 
color_green, color_blue, ipv4_to_str(reversedval, ipstrbuf));
        }
 
        printf("%sASCII: %s", color_green, color_blue);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitwise-0.50/src/misc.c new/bitwise-0.60/src/misc.c
--- old/bitwise-0.50/src/misc.c 2023-07-20 22:23:10.000000000 +0200
+++ new/bitwise-0.60/src/misc.c 2026-08-22 11:35:36.000000000 +0200
@@ -215,7 +215,7 @@
        if (tolower(input[0]) == 'b')
                base = 2;
        else if (input[0] == '0')
-               if (tolower(input[1] == 'b'))
+               if (tolower(input[1]) == 'b')
                        base = 2;
                else if (input[1] == 'x' || input[1] == 'X')
                        base = 16;
@@ -243,7 +243,7 @@
                break;
        case 2:
        default:
-               sprintf(buf, "Not implemeted");
+               sprintf(buf, "Not implemented");
                return -1;
        }
 
@@ -360,3 +360,17 @@
 
        return 0;
 }
+
+
+const char *
+ipv4_to_str(uint32_t ip, char out[static 16])
+{
+    const unsigned char b0 = (ip >> 24) & 0xFF;
+    const unsigned char b1 = (ip >> 16) & 0xFF;
+    const unsigned char b2 = (ip >> 8)  & 0xFF;
+    const unsigned char b3 = ip & 0xFF;
+
+    snprintf(out, 16, "%u.%u.%u.%u", b0, b1, b2, b3);
+    return out;
+}
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitwise-0.50/src/shunting-yard.c 
new/bitwise-0.60/src/shunting-yard.c
--- old/bitwise-0.50/src/shunting-yard.c        2023-07-20 22:23:10.000000000 
+0200
+++ new/bitwise-0.60/src/shunting-yard.c        2026-08-22 11:35:36.000000000 
+0200
@@ -63,6 +63,9 @@
        {"&", 1, 5, OPERATOR_BINARY, OPERATOR_LEFT},
        {"^", 1, 5, OPERATOR_BINARY, OPERATOR_LEFT},
        {"|", 1, 6, OPERATOR_BINARY, OPERATOR_LEFT},
+       {"&=", 2, 5, OPERATOR_BINARY, OPERATOR_LEFT},
+       {"^=", 2, 5, OPERATOR_BINARY, OPERATOR_LEFT},
+       {"|=", 2, 6, OPERATOR_BINARY, OPERATOR_LEFT},
        {"(", 1, 7, OPERATOR_OTHER,  OPERATOR_NONE}
 };
 
@@ -150,6 +153,9 @@
                else if (!strncmp("<<", c, 2) || !strncmp(">>", c, 2)) {
                        token.type = TOKEN_OPERATOR;
                        token.value = strndup(c, 2);
+               } else if (strchr("^|&", *c) && *(c + 1) == '=') {
+                       token.type = TOKEN_OPERATOR;
+                       token.value = strndup(c, 2);
                } else if (strchr("~!^*/%+-|&", *c)) {
                        token.type = TOKEN_OPERATOR;
                        token.value = strndup(c, 1);
@@ -351,6 +357,8 @@
                x = x / y;
                break;
        case '%':
+               if (y == 0)
+                       return ERROR_DIVIDE_BY_ZERO;
                x = x % y;
                break;
        case '+':
@@ -392,6 +400,8 @@
                break;
        case '~':
                x = ~x;
+               if (g_width)
+                       x &= MASK(g_width);
                break;
        case '!':
                x = !x;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitwise-0.50/tests/test-shunting-yard.c 
new/bitwise-0.60/tests/test-shunting-yard.c
--- old/bitwise-0.50/tests/test-shunting-yard.c 2023-07-20 22:23:10.000000000 
+0200
+++ new/bitwise-0.60/tests/test-shunting-yard.c 2026-08-22 11:35:36.000000000 
+0200
@@ -90,6 +90,81 @@
        ASSERT_RESULT("2+6/2*5+10/3-2/6", 20);
 }
 
+static void test_bitwise_and()
+{
+       ASSERT_RESULT("0xFF & 0x0F", 0x0F);
+       ASSERT_RESULT("7 & 3", 3);
+       ASSERT_RESULT("0xABCD & 0xFF00", 0xAB00);
+}
+
+static void test_bitwise_or()
+{
+       ASSERT_RESULT("0xF0 | 0x0F", 0xFF);
+       ASSERT_RESULT("4 | 2", 6);
+       ASSERT_RESULT("0 | 0", 0);
+}
+
+static void test_bitwise_xor()
+{
+       ASSERT_RESULT("0xFF ^ 0x0F", 0xF0);
+       ASSERT_RESULT("5 ^ 5", 0);
+       ASSERT_RESULT("0xA ^ 0x5", 0xF);
+}
+
+static void test_bitwise_not()
+{
+       extern int g_width;
+
+       /* With 8-bit width, ~0 should be 0xFF */
+       g_width = 8;
+       ASSERT_RESULT("~0", 0xFF);
+       ASSERT_RESULT("~0xFF", 0);
+       ASSERT_RESULT("~0x0F", 0xF0);
+
+       /* With 16-bit width */
+       g_width = 16;
+       ASSERT_RESULT("~0", 0xFFFF);
+       ASSERT_RESULT("~0xFF", 0xFF00);
+
+       /* With 32-bit width */
+       g_width = 32;
+       ASSERT_RESULT("~0", 0xFFFFFFFF);
+       ASSERT_RESULT("~1", 0xFFFFFFFE);
+
+       /* Reset */
+       g_width = 0;
+}
+
+static void test_logical_not()
+{
+       ASSERT_RESULT("!0", 1);
+       ASSERT_RESULT("!1", 0);
+       ASSERT_RESULT("!42", 0);
+}
+
+static void test_compound_assignment()
+{
+       ASSERT_RESULT("$ |= BIT(0)", 0x513);
+       ASSERT_RESULT("0x0F |= 0xF0", 0xFF);
+
+       ASSERT_RESULT("$ &= ~BIT(4)", 0x502);
+       ASSERT_RESULT("0xFF &= 0x0F", 0x0F);
+
+       ASSERT_RESULT("$ ^= BIT(0)", 0x513);
+       ASSERT_RESULT("$ ^= BIT(1)", 0x510);
+
+       ASSERT_RESULT("$ & BIT(1)", 0x2);
+       ASSERT_RESULT("$ & BIT(0)", 0);
+}
+
+static void test_combined_operations()
+{
+       ASSERT_RESULT("(1 << 4) | (1 << 2)", 20);
+       ASSERT_RESULT("0xFF & (0x0F << 4)", 0xF0);
+       ASSERT_RESULT("(3 + 2) * (8 - 3)", 25);
+       ASSERT_RESULT("BIT(0) | BIT(1) | BIT(2)", 7);
+}
+
 static void test_errors()
 {
        ASSERT_STATUS("2+*2", ERROR_SYNTAX);
@@ -103,9 +178,8 @@
        ASSERT_STATUS("", ERROR_NO_INPUT);
        ASSERT_STATUS("       ", ERROR_NO_INPUT);
        ASSERT_STATUS("foo(2)", ERROR_UNDEFINED_FUNCTION);
-//     ASSERT_STATUS("bit(foo)", ERROR_FUNCTION_ARGUMENTS);
-//    ASSERT_STATUS("foo", ERROR_UNDEFINED_CONSTANT);
-
+       ASSERT_STATUS("10 / 0", ERROR_DIVIDE_BY_ZERO);
+       ASSERT_STATUS("10 % 0", ERROR_DIVIDE_BY_ZERO);
 }
 
 int main()
@@ -124,6 +198,13 @@
            !CU_add_test(suite, "multiplication", test_multiplication) ||
            !CU_add_test(suite, "division", test_division) ||
            !CU_add_test(suite, "modulus", test_modulus) ||
+           !CU_add_test(suite, "bitwise AND", test_bitwise_and) ||
+           !CU_add_test(suite, "bitwise OR", test_bitwise_or) ||
+           !CU_add_test(suite, "bitwise XOR", test_bitwise_xor) ||
+           !CU_add_test(suite, "bitwise NOT", test_bitwise_not) ||
+           !CU_add_test(suite, "logical NOT", test_logical_not) ||
+           !CU_add_test(suite, "compound assignment", 
test_compound_assignment) ||
+           !CU_add_test(suite, "combined operations", 
test_combined_operations) ||
            !CU_add_test(suite, "functions", test_functions) ||
            !CU_add_test(suite, "constants", test_constants) ||
            !CU_add_test(suite, "operator precedence", test_precedence) ||

Reply via email to