suckless unix tools
git clone git://
Log | Files | Refs | README | LICENSE

commit b98bf41eccfe7a14dbbb2256001d5ef59987c116
parent 1a8dfaca372fba96615e8559d76a13b1fc1f217f
Author: FRIGN <>
Date:   Sun Jan 25 16:49:46 +0100

Add mandoc-manpage for expr(1)

and mark it as finished in README.
Upon further checking, expr(1) turns out to be implicitly UTF-8 compliant.

README | 2+-
expr.1 | 207+++++++++++++++++++++++++++++--------------------------------------------------
expr.c | 4++--
3 files changed, 79 insertions(+), 134 deletions(-)
diff --git a/README b/README @@ -29,7 +29,7 @@ The following tools are implemented ('*' == finished, '#' == UTF-8 support, =* echo yes none =* env yes none #* expand yes none - expr yes none +=* expr yes none =* false yes none fold yes none grep yes none diff --git a/expr.1 b/expr.1 @@ -1,12 +1,5 @@ -.\" $OpenBSD: src/bin/expr/expr.1,v 1.22 2014/02/23 18:13:27 schwarze Exp $ -.\" $NetBSD: expr.1,v 1.9 1995/04/28 23:27:13 jtc Exp $ -.\" -.\" Written by J.T. Conklin <>. -.\" Public domain. -.\" -.Dd $Mdocdate: September 3 2010 $ -.Dt EXPR 1 -.Os +.Dd January 25, 2015 +.Dt EXPR 1 sbase\-VERSION .Sh NAME .Nm expr .Nd evaluate expression @@ -14,143 +7,95 @@ .Nm expr .Ar expression .Sh DESCRIPTION -The .Nm -utility evaluates +evaluates .Ar expression -and writes the result on standard output. -All operators are separate arguments to the -.Nm -utility. -Characters special to the command interpreter must be escaped. -.Pp -Operators are listed below in order of increasing precedence. -Operators with equal precedence are grouped within { } symbols. -.Bl -tag -width indent -.It Ar expr1 | expr2 -Returns the evaluation of -.Ar expr1 -if it is neither an empty string nor zero; -otherwise, returns the evaluation of -.Ar expr2 . -.It Ar expr1 Li & Ar expr2 -Returns the evaluation of -.Ar expr1 -if neither expression evaluates to an empty string or zero; -otherwise, returns zero. -.It Ar expr1 Li "{=, >, >=, <, <=, !=}" Ar expr2 -Returns the results of integer comparison if both arguments are integers; -otherwise, returns the results of string comparison using the locale-specific -collation sequence. -The result of each comparison is 1 if the specified relation is true, -or 0 if the relation is false. -.It Ar expr1 Li "{+, -}" Ar expr2 -Returns the results of addition or subtraction of integer-valued arguments. -.It Ar expr1 Li "{*, /, %}" Ar expr2 -Returns the results of multiplication, integer division, or remainder of -integer-valued arguments. -.It Ar expr1 Li : Ar expr2 -The -.Ql \&: -operator matches -.Ar expr1 -against -.Ar expr2 , -which must be a basic regular expression. -The regular expression is anchored -to the beginning of the string with an implicit -.Ql ^ . +and writes the result to stdout. .Pp -If the match succeeds and the pattern contains at least one regular -expression subexpression -.Dq "\e(...\e)" , -the string corresponding to -.Dq "\e1" -is returned; -otherwise, the matching operator returns the number of characters matched. -If the match fails and the pattern contains a regular expression subexpression -the null string is returned; -otherwise, returns 0. +There are two elemental expressions, +.Sy integer +and +.Sy string. +Let +.Sy expr +be a non-elemental expression and +.Sy expr1 , +.Sy expr2 +arbitrary expressions. Then +.Sy expr +has the recursive form +.Sy expr = [(] expr1 operand expr2 [)]. .Pp -Note: the empty string cannot be matched using -.Bd -literal -offset indent -expr '' : '$' -.Ed +With +.Sy operand +being in oder of increasing precedence: +.Bl -tag -width Ds +.It | +Evaluate to +.Sy expr1 +if it is neither an empty string nor 0; otherwise evaluate to +.Sy expr2 . +.It & +Evaluate to +.Sy expr1 +if +.Sy expr1 +and +.Sy expr2 +are neither empty strings nor 0; otherwise evaluate to 0. +.It = > >= < <= != +If +.Sy expr1 +and +.Sy expr2 +are integers, evaluate to 1 if the relation is true and 0 if it is false. +If +.Sy expr1 +and +.Sy expr2 +are strings, apply the relation to the return value of +.Xr strcmp 3 . +.It + - +If +.Sy expr1 +and +.Sy expr2 +are integers, evaluate to their sum or subtraction. +.It * / % +If +.Sy expr1 +and +.Sy expr2 +are integers, evaluate to their mulitplication, division or remainder. +.It : +Evaluate to the number of characters matched in +.Sy expr1 +against +.Sy expr2 . expr2 +is anchored with an implicit '^'. .Pp -This is because the returned number of matched characters -.Pq zero -is indistinguishable from a failed match, so -.Nm -returns failure -.Pq 0 . -To match the empty string, use a structure such as: -.Bd -literal -offset indent -expr X'' : 'X$' -.Ed +You can't directly match the empty string, since zero matched characters +resolve equally to a failed match. To work around this limitation, use "expr X'' : 'X$' instead of "expr '' : '$'" .El -.Pp -Parentheses are used for grouping in the usual manner. .Sh EXIT STATUS -The -.Nm -utility exits with one of the following values: -.Pp -.Bl -tag -width Ds -offset indent -compact +.Bl -tag -width Ds .It 0 -The expression is neither an empty string nor 0. +.Ar expression +is neither an empty string nor 0 .It 1 -The expression is an empty string or 0. +.Ar expression +is an empty string or 0 .It 2 -The expression is invalid. -.It \*(Gt2 -An error occurred (such as memory allocation failure). +.Ar expression +is invalid +.It > 2 +An error occured .El -.Sh EXAMPLES -Add 1 to the variable -.Va a : -.Bd -literal -offset indent -$ a=`expr $a + 1` -.Ed -.Pp -Return the filename portion of a pathname stored -in variable -.Va a . -The -.Ql // -characters act to eliminate ambiguity with the division operator: -.Bd -literal -offset indent -$ expr "//$a" \&: '.*/\e(.*\e)' -.Ed -.Pp -Return the number of characters in variable -.Va a : -.Bd -literal -offset indent -$ expr $a \&: '.*' -.Ed .Sh SEE ALSO -.Xr test 1 , -.Xr re_format 7 +.Xr test 1 .Sh STANDARDS The .Nm utility is compliant with the .St -p1003.1-2008 specification. -.Sh HISTORY -The -.Nm -utility first appeared in the Programmer's Workbench (PWB/UNIX) -and has supported regular expressions since -.At v7 . -It was rewritten from scratch for -.Bx 386 0.1 -and again for -.Nx 1.1 . -.Sh AUTHORS -.An -nosplit -The first free version was written by -.An Pace Willisson -in 1992. -This version was written by -.An John T. Conklin -in 1994. diff --git a/expr.c b/expr.c @@ -182,11 +182,11 @@ lex(char *p) } /* one-char operand */ - if (*p && !*(p+1) && strchr(ops, *p)) + if (*p && !*(p + 1) && strchr(ops, *p)) return *p; /* two-char operand */ - if (*p && *(p+1) == '=' && !*(p+2)) { + if (*p && *(p + 1) == '=' && !*(p + 2)) { switch (*p) { case '>': return GE;