1
0

documentation

This commit is contained in:
dtb 2023-12-03 19:47:40 -07:00
parent 88f2cdcea8
commit 2c7f3f30e4
3 changed files with 139 additions and 0 deletions

1
intcmp/Makefile Normal file
View File

@ -0,0 +1 @@
intcmp: intcmp.c

63
intcmp/intcmp.1 Normal file
View File

@ -0,0 +1,63 @@
.TH intcmp 1
.SH NAME
intcmp \(en compare integers
.SH SYNOPSIS
intcmp
.RB ( -h )
.RB ( -e ( -g )|( -l ))|( -g ( -e )|( -l ))|( -l ( -e )|( -g ))
.RB [ integer ]
.RB [ integer... ]
.SH DESCRIPTION
Intcmp compares integers.
.SH USAGE
The -e option permits given integers to be equal to each other. If combined
with -g or -l, only adjacent integers in the argument sequence can be equal.
.PP
The -g option permits a given integer to be greater than the following integer.
.PP
The -l option permits a given integer to be less than the following integer.
.PP
It may help to think of the -e, -g, and -l options as equivalent to the
infix algebraic "=", ">", and "<" operators respectively, with each option
putting its symbol between every given integer. For example,
.R intcmp -l 1 2 3
is equivalent to evaluating "1 < 2 < 3".
.SH DIAGNOSTICS
Intcmp exits 0 for a valid expression and 1 for an invalid expression.
.PP
Intcmp prints a debug message and exits with the appropriate sysexits(3) error
code in the event of an error.
.SH BUGS
There are multiple ways to express compound comparisons; "less than or equal
to" can be -le or -el, for example.
.PP
The inequality comparison is -gl or -lg for "less than or greater than"; this
is elegant but unintuitive.
.PP
-egl, "equal to or less than or greater than", exits 0 no matter what for valid
program usage and may be abused to function as an integer validator.
Use str(1) instead.
.SH STANDARDS
This utility recreates functionality that in POSIX is fulfilled by test(1).
.SH COPYRIGHT
Public domain.
.SH SEE ALSO
str(1), test(1)

75
intcmp/intcmp.c Normal file
View File

@ -0,0 +1,75 @@
#include <errno.h> /* errno */
#include <stdio.h> /* fprintf(3), stderr */
#include <stdlib.h> /* strtol(3), size_t */
#ifndef EX_USAGE
# include <sysexits.h> /* EX_USAGE */
#endif
#include <unistd.h> /* getopt(3), optind */
/* 0b00? */ /* Equal | -e | 0b001 | 1 */
#define EQUAL 0x01 /* Greater | -g | 0b010 | 2 */
/* 0b0?0 */ /* Greater or Equal | -ge | 0b011 | 3 */
#define GREATER 0x02 /* Less | -l | 0b100 | 4 */
/* 0b?00 */ /* Less or Equal | -le | 0b101 | 5 */
#define LESS 0x04 /* Inequal (Greater or Less) | -gl | 0b110 | 6 */
static char *program_name = "intcmp";
int main(int argc, char *argv[]){
int c;
size_t i;
unsigned char mode;
int r; /* reference integer */
mode = 0;
if(argc < 3)
goto usage;
while((c = getopt(argc, argv, "egl")) != -1)
switch(c){
case 'e': mode |= EQUAL; break;
case 'g': mode |= GREATER; break;
case 'l': mode |= LESS; break;
default: goto usage;
}
if(optind + 2 /* ref cmp */ > argc){
usage: fprintf(stderr,
"Usage: %s (-h)\n"
"\t" "(-e (-g)|(-l))\n"
"\t" "|(-g (-e)|(-l))\n"
"\t" "|(-l (-e)|(-g))\n"
"\t\t" "[integer] [integer...]\n",
argv[0] == NULL ? program_name : argv[0]);
return EX_USAGE;
}
i = optind;
do{ c = strtol(argv[i], &argv[i], 10);
if(*argv[i] != '\0' || errno != 0){
fprintf(stderr, "%s: argument #%d: Invalid integer\n",
argv[0], (int)i);
return EX_USAGE;
}
if(i == optind){
r = c;
continue;
}
/* rule enforcement; if a mode isn't permitted and the numbers
* correspond to it, return 1 */
if( (!(mode & EQUAL) && r == c)
|| (!(mode & GREATER) && r > c)
|| (!(mode & LESS) && r < c))
return 1;
else if((mode ^ EQUAL) != 0) /* if the mode isn't ==
* make sure the numbers are in order by comparing the
* newest number to the last */
r = c;
}while(++i < argc);
return 0;
}