commit: ff9d229451c7020f0d69f099ece61b90ac1a69fe
parent 249c3c4d49660400f7112733015f72c3c2fed312
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Sat, 3 Jan 2026 14:33:11 +0100
expr: toss out FreeBSD -e compatibility option
Causes issues with getopt() triggering when commands like
expr --foobar : --foobar
are ran without POSIXLY_CORRECT set.
Diffstat:
| M | cmd/expr.1 | 79 | +++++-------------------------------------------------------------------------- |
| M | cmd/expr.y | 45 | ++++++++------------------------------------- |
2 files changed, 13 insertions(+), 111 deletions(-)
diff --git a/cmd/expr.1 b/cmd/expr.1
@@ -29,7 +29,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd October 5, 2016
+.Dd January 3, 2026
.Dt EXPR 1
.Os
.Sh NAME
@@ -37,7 +37,6 @@
.Nd evaluate expression
.Sh SYNOPSIS
.Nm
-.Op Fl e
.Ar expression
.Sh DESCRIPTION
The
@@ -65,10 +64,6 @@ All conversions and operations are checked for overflow.
Overflow results in program termination with an error message on stdout
and with an error status.
.Pp
-The
-.Fl e
-option enables backwards compatible behaviour as detailed below.
-.Pp
Operators are listed below in order of increasing precedence; all
are left-associative.
Operators with equal precedence are grouped within symbols
@@ -138,54 +133,6 @@ The syntax of the
command in general is historic and inconvenient.
New applications are advised to use shell arithmetic rather than
.Nm .
-.Ss Compatibility with previous implementations
-Unless
-.Fx
-4.x
-compatibility is enabled, this version of
-.Nm
-adheres to the
-.Tn POSIX
-Utility Syntax Guidelines, which require that a leading argument beginning
-with a minus sign be considered an option to the program.
-The standard
-.Fl Fl
-syntax may be used to prevent this interpretation.
-However, many historic implementations of
-.Nm ,
-including the one in previous versions of
-.Fx ,
-will not permit this syntax.
-See the examples below for portable ways to guarantee the correct
-interpretation.
-The
-.Xr check_utility_compat 3
-function (with a
-.Fa utility
-argument of
-.Dq Li expr )
-is used to determine whether backwards compatibility mode should be enabled.
-This feature is intended for use as a transition and debugging aid, when
-.Nm
-is used in complex scripts which cannot easily be recast to avoid the
-non-portable usage.
-Enabling backwards compatibility mode also implicitly enables the
-.Fl e
-option, since this matches the historic behavior of
-.Nm
-in
-.Fx . This option makes number parsing less strict and permits leading
-white space and an optional leading plus sign.
-In addition, empty operands
-have an implied value of zero in numeric context.
-For historical reasons, defining the environment variable
-.Ev EXPR_COMPAT
-also enables backwards compatibility mode.
-.Sh ENVIRONMENT
-.Bl -tag -width ".Ev EXPR_COMPAT"
-.It Ev EXPR_COMPAT
-If set, enables backwards compatibility mode.
-.El
.Sh EXIT STATUS
The
.Nm
@@ -267,25 +214,13 @@ expands to the required number.
.El
.Sh SEE ALSO
.Xr sh 1 ,
-.Xr test 1 ,
-.Xr check_utility_compat 3
+.Xr test 1
.Sh STANDARDS
The
.Nm
-utility conforms to
-.St -p1003.1-2008 ,
-provided that backwards compatibility mode is not enabled.
-.Pp
-Backwards compatibility mode performs less strict checks of numeric arguments:
-.Bl -bullet
-.It
-An empty operand string is interpreted as 0.
-.El
-.Bl -bullet
-.It
-Leading white space and/or a plus sign before an otherwise valid positive
-numeric operand are allowed and will be ignored.
-.El
+utility should be compliant with the
+IEEE Std 1003.1-2024 (“POSIX.1”)
+specification.
.Pp
The extended arithmetic range and overflow checks do not conflict with
POSIX's requirement that arithmetic be done using signed longs, since
@@ -304,10 +239,6 @@ produces undefined results.
In this version of
.Nm ,
these arguments are treated just as their respective string values.
-.Pp
-The
-.Fl e
-flag is an extension.
.Sh HISTORY
An
.Nm
diff --git a/cmd/expr.y b/cmd/expr.y
@@ -15,20 +15,18 @@
* #include <stdlib.h>
*/
+#include "../libutils/err.h"
#include <assert.h>
-#include <sys/types.h>
#include <ctype.h>
-#include "../libutils/err.h"
-#include "../libutils/getopt_nolong.h"
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
#include <locale.h>
+#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <regex.h>
-#include <unistd.h>
+#include <sys/types.h>
/*
* POSIX specifies a specific error code for syntax errors. We exit
@@ -49,7 +47,6 @@ struct val {
} ;
char **av;
-int nonposix;
struct val *result;
static void assert_to_integer(struct val *);
@@ -228,18 +225,15 @@ to_string(struct val *vp)
static int
is_integer(const char *s)
{
- if (nonposix) {
- if (*s == '\0')
- return (1);
- while (isspace((unsigned char)*s))
- s++;
- }
- if (*s == '-' || (nonposix && *s == '+'))
+ if (*s == '-')
s++;
+
if (*s == '\0')
return (0);
+
while (isdigit((unsigned char)*s))
s++;
+
return (*s == '\0');
}
@@ -287,8 +281,6 @@ is_zero_or_null(struct val *vp)
int
main(int argc, char *argv[])
{
- int c;
-
char *lc_all = setlocale(LC_ALL, "");
if(lc_all == NULL)
{
@@ -296,28 +288,7 @@ main(int argc, char *argv[])
}
errno = 0;
- if (getenv("EXPR_COMPAT") != NULL
- || getenv("POSIXLY_CORRECT") != NULL) {
- av = argv + 1;
- nonposix = 1;
- } else {
- while ((c = getopt_nolong(argc, argv, ":e")) != -1) {
- switch (c) {
- case 'e':
- nonposix = 1;
- break;
- case ':':
- utils_errx(1, "Missing operand for option: '-%c'", optopt);
- break;
- case '?':
- utils_errx(1, "Unrecognised option: '-%c'", optopt);
- break;
- default:
- abort();
- }
- }
- av = argv + optind;
- }
+ av = argv + 1;
yyparse();