[hackers] [sbase] Use strtonum and libutf in test(1), refactor code and manpage || FRIGN

From: <git_AT_suckless.org>
Date: Tue, 24 Mar 2015 23:53:40 +0100 (CET)

commit 360a63769ccb3068070ed004c3522f880dff9392
Author: FRIGN <dev_AT_frign.de>
Date: Mon Feb 9 22:21:23 2015 +0100

    Use strtonum and libutf in test(1), refactor code and manpage
    
    and mark it as finished in README.

diff --git a/README b/README
index ebd8120..d8e1e75 100644
--- a/README
+++ b/README
_AT_@ -67,7 +67,7 @@ The following tools are implemented ('*' == finished, '#' == UTF-8 support,
 =* tail yes none
 =* tar non-posix none
 =* tee yes none
- test yes none
+#* test yes none
 =* touch yes none
 #* tr yes none
 =* true yes none
diff --git a/libutil/strtonum.c b/libutil/strtonum.c
index 0779174..c0ac401 100644
--- a/libutil/strtonum.c
+++ b/libutil/strtonum.c
_AT_@ -67,13 +67,19 @@ strtonum(const char *numstr, long long minval, long long maxval,
 }
 
 long long
-estrtonum(const char *numstr, long long minval, long long maxval)
+enstrtonum(int status, const char *numstr, long long minval, long long maxval)
 {
         const char *errstr;
         long long ll;
 
         ll = strtonum(numstr, minval, maxval, &errstr);
         if (errstr)
- eprintf("strtonum %s: %s\n", numstr, errstr);
+ enprintf(status, "strtonum %s: %s\n", numstr, errstr);
         return ll;
 }
+
+long long
+estrtonum(const char *numstr, long long minval, long long maxval)
+{
+ return enstrtonum(1, numstr, minval, maxval);
+}
diff --git a/test.1 b/test.1
index b5196f7..8ddd49d 100644
--- a/test.1
+++ b/test.1
_AT_@ -1,75 +1,76 @@
-.Dd January 30, 2015
+.Dd February 9, 2015
 .Dt TEST 1
 .Os sbase
 .Sh NAME
 .Nm test
-.Nd check file types and compare values
+.Nd evaluate expression
 .Sh SYNOPSIS
 .Nm
-.Ar EXPRESSION
+.Ar expression
 .Sh DESCRIPTION
-Exit with the status determined by
-.Ar EXPRESSION .
+.Nm
+returns the status of the
+.Ar expression .
 .Sh OPTIONS
 .Bl -tag -width Ds
-.It ! Ar EXPRESSION
-invert EXPRESSION
-.It Fl b Ar FILE
-FILE exists and is block special
-.It Fl c Ar FILE
-FILE exists and is character special
-.It Fl d Ar FILE
-FILE exists and is a directory
-.It Fl e Ar FILE
-FILE exists
-.It Fl f Ar FILE
-FILE exists and is a regular file
-.It Fl g Ar FILE
-FILE exists and is set-group-ID
-.It Fl h Ar FILE
-FILE exists and is a symbolic link (same as
-.Fl L )
-.It Fl k Ar FILE
-FILE exists and its sticky bit is set
-.It Fl L Ar FILE
-FILE exists and is a symbolic link (same as
-.Fl h )
-.It Fl n Ar STRING
-the length of STRING is nonzero
-.It Fl p Ar FILE
-FILE exists and is a named pipe
-.It Fl r Ar FILE
-FILE exists and read permission is granted
-.It Fl S Ar FILE
-FILE exists and is a socket
-.It Fl s Ar FILE
-FILE exists and has a size greater than zero
-.It Fl t Ar FD
-file descriptor FD is opened on a terminal
-.It Fl u Ar FILE
-exists and its set-user-ID bit is set
-.It Fl w Ar FILE
-FILE exists and write permission is granted
-.It Fl x Ar FILE
-FILE exists and execute (or search) permission is granted
-.It Fl z Ar STRING
-the length of STRING is zero
-.It s1 = s2
-True if the strings s1 and s2 are identical
-.It s1 != s2
-True if the strings s1 and s2 are not identical
-.It s1
-True if s1 is not the null string
-.It n1 -eq n2
-True if the integers n1 and n2 are equal
-.It n1 -ne n2
-True if the integers n1 and n2 are not equal
-.It n1 -gt n2
-True if the integer n1 is greater than the integer n2
-.It n1 -ge n2
-True if the integer n1 is great than or equal to the integer n2
-.It n1 -lt n2
-True if the integer n1 is less than the integer n2
-.It n1 -le n2
-True if the integer n1 is less than or equal to the integer n2
+.It Sy ! Ar expression
+.Sy invert
+.Ar expression .
+.It Sy -(e | s) Ar file
+.Ar file
+.Sy exists
+and has
+.Sy arbitrary size | size greater than zero .
+.It Sy -(f | d | p | hL | S | b | c) Ar file
+.Ar file
+.Sy exists
+and is
+.Sy regular file | directory | named pipe | symbolic link | socket | block special | character special .
+.It Sy -(k | g | u | r | w | x) Ar file
+.Ar file
+.Sy exists
+and is
+.Sy sticky(1) | setgid(2) | setuid(4) | readable | writable | executable (or searchable) .
+.It Fl t Ar fd
+.Ar fd
+as a file descriptor is
+.Sy associated with a terminal .
+.It Ar string
+True if
+.Ar string
+is
+.Sy not the null string .
+.It Sy -(z | n) Ar string
+True if
+.Ar string
+has
+.Sy zero | non-zero
+length.
+.It Ar s1 Sy (= | !=) Ar s2
+True if strings
+.Ar s1
+and
+.Ar s2
+are
+.Sy identical | different .
+.It Ar n1 Sy -(eq | ne | gt | ge | le | lt) Ar n2
+True if integers
+.Ar n1
+and
+.Ar n2
+are
+.Sy = | != | > | >= | <= | < .
+.Sh EXIT STATUS
+.Bl -tag -width Ds
+.It 0
+.Ar expression
+is true.
+.It 1
+.Ar expression
+is false.
+.It > 1
+An error occurred.
 .El
+.Sh SEE ALSO
+.Xr expr 1
+.Sh STANDARDS
diff --git a/test.c b/test.c
index ad2ca7d..283ee32 100644
--- a/test.c
+++ b/test.c
_AT_@ -1,22 +1,14 @@
 /* See LICENSE file for copyright and license details. */
-#include <errno.h>
+#include <limits.h>
 #include <stdio.h>
-#include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
 #include <unistd.h>
 
+#include "utf.h"
 #include "util.h"
 
-static void
-stoi(char *s, int *a)
-{
- char *p;
- errno = 0;
- *a = strtol(s, &p, 0);
- if (errno || !*s || *p)
- enprintf(2, "bad integer %s\n", s);
-}
+#define STOI(s) enstrtonum(2, s, LLONG_MIN, LLONG_MAX)
 
 static int unary_b(char *s) { struct stat buf; if ( stat(s, &buf)) return 0; return S_ISBLK (buf.st_mode); }
 static int unary_c(char *s) { struct stat buf; if ( stat(s, &buf)) return 0; return S_ISCHR (buf.st_mode); }
_AT_@ -29,32 +21,32 @@ static int unary_S(char *s) { struct stat buf; if ( stat(s, &buf)) return 0; ret
 static int unary_s(char *s) { struct stat buf; if ( stat(s, &buf)) return 0; return buf.st_size ; }
 static int unary_u(char *s) { struct stat buf; if ( stat(s, &buf)) return 0; return S_ISUID & buf.st_mode ; }
 
-static int unary_n(char *s) { return strlen(s); }
-static int unary_z(char *s) { return !strlen(s); }
+static int unary_n(char *s) { return utflen(s); }
+static int unary_z(char *s) { return !utflen(s); }
 
 static int unary_e(char *s) { return access(s, F_OK); }
 static int unary_r(char *s) { return access(s, R_OK); }
 static int unary_w(char *s) { return access(s, W_OK); }
 static int unary_x(char *s) { return access(s, X_OK); }
 
-static int unary_t(char *s) { int fd; stoi(s, &fd); return isatty(fd); }
+static int unary_t(char *s) { int fd = enstrtonum(2, s, 0, INT_MAX); return isatty(fd); }
 
 static int binary_se(char *s1, char *s2) { return strcmp(s1, s2) == 0; }
 static int binary_sn(char *s1, char *s2) { return strcmp(s1, s2) != 0; }
 
-static int binary_eq(char *s1, char *s2) { int a, b; stoi(s1, &a); stoi(s2, &b); return a == b; }
-static int binary_ne(char *s1, char *s2) { int a, b; stoi(s1, &a); stoi(s2, &b); return a != b; }
-static int binary_gt(char *s1, char *s2) { int a, b; stoi(s1, &a); stoi(s2, &b); return a > b; }
-static int binary_ge(char *s1, char *s2) { int a, b; stoi(s1, &a); stoi(s2, &b); return a >= b; }
-static int binary_lt(char *s1, char *s2) { int a, b; stoi(s1, &a); stoi(s2, &b); return a < b; }
-static int binary_le(char *s1, char *s2) { int a, b; stoi(s1, &a); stoi(s2, &b); return a <= b; }
+static int binary_eq(char *s1, char *s2) { long long a = STOI(s1), b = STOI(s2); return a == b; }
+static int binary_ne(char *s1, char *s2) { long long a = STOI(s1), b = STOI(s2); return a != b; }
+static int binary_gt(char *s1, char *s2) { long long a = STOI(s1), b = STOI(s2); return a > b; }
+static int binary_ge(char *s1, char *s2) { long long a = STOI(s1), b = STOI(s2); return a >= b; }
+static int binary_lt(char *s1, char *s2) { long long a = STOI(s1), b = STOI(s2); return a < b; }
+static int binary_le(char *s1, char *s2) { long long a = STOI(s1), b = STOI(s2); return a <= b; }
 
-typedef struct {
+struct test {
         char *name;
         int (*func)();
-} Test;
+};
 
-static Test unary[] = {
+static struct test unary[] = {
         { "-b", unary_b },
         { "-c", unary_c },
         { "-d", unary_d },
_AT_@ -77,7 +69,7 @@ static Test unary[] = {
         { NULL, NULL },
 };
 
-static Test binary[] = {
+static struct test binary[] = {
         { "=" , binary_se },
         { "!=" , binary_sn },
         { "-eq", binary_eq },
_AT_@ -90,10 +82,10 @@ static Test binary[] = {
         { NULL, NULL },
 };
 
-static Test *
-find_test(Test *tests, char *name)
+static struct test *
+find_test(struct test *tests, char *name)
 {
- Test *t;
+ struct test *t;
 
         for (t = tests; t->name; ++t)
                 if (strcmp(t->name, name) == 0)
_AT_@ -116,7 +108,7 @@ onearg(char **argv)
 static int
 twoarg(char **argv)
 {
- Test *t = find_test(unary, *argv);
+ struct test *t = find_test(unary, *argv);
 
         if (strcmp(argv[0], "!") == 0)
                 return !onearg(argv + 1);
_AT_@ -130,7 +122,7 @@ twoarg(char **argv)
 static int
 threearg(char **argv)
 {
- Test *t = find_test(binary, argv[1]);
+ struct test *t = find_test(binary, argv[1]);
 
         if (t)
                 return t->func(argv[0], argv[2]);
_AT_@ -154,11 +146,10 @@ int
 main(int argc, char **argv)
 {
         int (*narg[])(char**) = { noarg, onearg, twoarg, threearg, fourarg };
- int len = strlen(argv[0]);
+ size_t len = strlen(argv[0]);
 
- if (len && argv[0][len - 1] == '[')
- if (strcmp(argv[--argc], "]") != 0)
- enprintf(2, "no matching ]\n");
+ if (len && argv[0][len - 1] == '[' && strcmp(argv[--argc], "]") != 0)
+ enprintf(2, "no matching ]\n");
 
         --argc; ++argv;
 
diff --git a/util.h b/util.h
index 7db5f1d..6716ae5 100644
--- a/util.h
+++ b/util.h
_AT_@ -57,5 +57,6 @@ void putword(const char *);
 void recurse(const char *, void (*)(const char *));
 #undef strtonum
 long long strtonum(const char *, long long, long long, const char **);
+long long enstrtonum(int, const char *, long long, long long);
 long long estrtonum(const char *, long long, long long);
 size_t unescape(char *);
Received on Tue Mar 24 2015 - 23:53:40 CET

This archive was generated by hypermail 2.3.0 : Wed Mar 25 2015 - 00:08:58 CET