Compare commits

..
3 Commits
Author SHA1 Message Date
trinity fe1216868b dj(1): refactor source 2024-03-28 21:22:36 -06:00
aryal b562898a74 copyright 2024-03-27 09:21:19 +05:45
aryal d05d2fae05 Makefile: add a missing build target for npc(1) 2024-03-26 17:19:21 +05:45
15 changed files with 326 additions and 563 deletions
+8 -1
View File
@@ -1,6 +1,7 @@
# Copyright (c) 20232024 Emma Tebibyte <emma@tebibyte.media> # Copyright (c) 20232024 Emma Tebibyte <emma@tebibyte.media>
# Copyright (c) 20232024 DTB <trinity@trinity.moe> # Copyright (c) 20232024 DTB <trinity@trinity.moe>
# Copyright (c) 2023 Sasha Koshka <sashakoshka@tebibyte.media> # Copyright (c) 2023 Sasha Koshka <sashakoshka@tebibyte.media>
# Copyright (c) 2024 Aaditya Aryal <aryalaadi123@gmail.com>
# SPDX-License-Identifier: FSFAP # SPDX-License-Identifier: FSFAP
# #
# Copying and distribution of this file, with or without modification, are # Copying and distribution of this file, with or without modification, are
@@ -17,7 +18,7 @@ CC=cc
RUSTC=rustc RUSTC=rustc
.PHONY: all .PHONY: all
all: dj false fop hru intcmp mm rpn scrut str strcmp swab true all: dj false fop hru intcmp mm npc rpn scrut str strcmp swab true
build: build:
# keep build/include until bindgen(1) has stdin support # keep build/include until bindgen(1) has stdin support
@@ -91,6 +92,12 @@ mm: build/bin/mm
build/bin/mm: src/mm.c build build/bin/mm: src/mm.c build
$(CC) $(CFLAGS) -o $@ src/mm.c $(CC) $(CFLAGS) -o $@ src/mm.c
.PHONY: npc
npc: build/bin/npc
build/bin/npc: src/npc.c build
$(CC) $(CFLAGAS) -o $@ src/npc.c
.PHONY: rpn .PHONY: rpn
rpn: build/bin/rpn rpn: build/bin/rpn
build/bin/rpn: src/rpn.rs build build/o/libsysexits.rlib build/bin/rpn: src/rpn.rs build build/o/libsysexits.rlib
+70 -127
View File
@@ -1,5 +1,4 @@
.\" Copyright (c) 2024 DTB <trinity@trinity.moe> .\" Copyright (c) 2024 DTB <trinity@trinity.moe>
.\" Copyright (c) 2024 Emma Tebibyte <emma@tebibyte.media>
.\" .\"
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license, .\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>. .\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
@@ -45,139 +44,87 @@ dj
.B output offset .B output offset
.R ]) .R ])
.SH OPTIONS .SH USAGE
The
.B -i .B -i
.RS option takes a path as an argument to open and use in place of standard input.
Takes a file path as an argument to open and use as an input. The
.RE
.B -b
.RS
Takes a numeric argument as the size in bytes of the input buffer, with the
default being 1024 bytes or one kibibyte (KiB).
.RE
.B -s
.RS
Takes a numeric argument as the number of bytes to skip into the input
before starting to read. If the standard input is used, bytes read to this point
are discarded.
.RE
.B -o .B -o
.RS option does the same in place of standard output. Dj does not truncate output
Takes a file path as an argument to open and use as an output. files and instead writes over the bytes in the existing file.
.RE .PP
The
.B -B
.RS
Does the same as
.B -b .B -b
but for the output buffer. option takes a numeric argument as the size in bytes of the input buffer and
.RE the
.B -B
option does the same for the output buffer, the default for both being 1024
bytes, or one kibibyte (KiB).
.PP
The
.B -s
option takes a numeric argument as the number of bytes to skip into the input
before starting to read, and the
.B -S .B -S
.RS option skips a number of bytes through the output before starting to write from
Skips a number of bytes through the output before starting to write from the input. If the input is a stream the bytes are read and discarded. If the
the input. If the output is a stream, null characters are printed. output is a stream, nul characters are printed.
.RE .PP
The
.B -a .B -a
.RS option takes one argument of one byte in length and pads the input buffer with
Accepts a single literal byte with which input buffer is padded in the event that byte in the event that a read doesn't fill the input buffer, and the
of an incomplete read from the input file.
.RE
.B -c
.RS
Specifies a number of reads to make. If set to zero (the default), reading will
continue until a partial or empty read is encountered.
.RE
.B -A .B -A
.RS option takes no arguments and pads with nuls.
If the output is a stream, null bytes are printed. This option is equivalent to The
specifying .B -c
.B -a option specifies an amount of reads to make, and if 0 (the default) dj will
with a null byte instead of a character. continue reading until a partial or empty read.
.RE .PP
On a partial or empty read, dj prints a diagnostic message (unless the
.B -d
.RS
Prints invocation information before program execution as described in the
DIAGNOSTICS section below. Each invocation increments the debug level of the
program.
.RE
.B -H
.RS
Prints diagnostics messages in a human-readable manner as described in the
DIAGNOSTICS section below.
.RE
.B -n
.RS
Retries failed reads once more before exiting.
.RE
.B -q .B -q
.RS option is specified) and exits (unless the
Suppresses error messages which print when a read or write is partial or .B -n
empty. Each invocation decrements the debug level of the program. option is specified, in which case only two consecutive empty reads will cause
.RE dj to exit).
At exit, usage statistics are printed unless the option
.SH STANDARD INPUT .B -q
is specified a second time. The
The standard input shall be used as an input if no inputs are specified one or .B -H
more of the input files is “-”. option will make these diagnostics human-readable.
.SH DIAGNOSTICS .SH DIAGNOSTICS
On a partial or empty read, a diagnostic message is printed (unless the The
.B -q .B -d
option is specified) and the program exits (unless the option prints all information, user-specified or otherwise, before program
.B -n execution.
option is specified. .PP
When dj exits, by default statistics are printed for input and output to
By default statistics are printed for input and output to the standard error in standard error in the following format:
the following format: .PP
.RS
.R {records read} {ASCII unit separator} {partial records read} .R {records read} {ASCII unit separator} {partial records read}
.R {ASCII record separator} {records written} {ASCII unit separator} .R {ASCII record separator} {records written} {ASCII unit separator}
.R {partial records written} {ASCII group separator} {bytes read} .R {partial records written} {ASCII group separator} {bytes read}
.R {ASCII record separator} {bytes written} {ASCII file separator} .R {ASCII record separator} {bytes written} {ASCII file separator}
.RE .PP
If the
This format for diagnostic output is designed to be machine-parseable for
convenience. For a more human-readable format, the
.B -H .B -H
option may be specified. In this event, the following format is used instead: option is specified dj instead uses this following format:
.PP
.RS
.R {records read} '+' {partial records read} '>' {records written} .R {records read} '+' {partial records read} '>' {records written}
.R '+' {partial records written} ';' {bytes read} '>' {bytes written} .R '+' {partial records written} ';' {bytes read} '>' {bytes written}
.R {ASCII line feed} .R {ASCII line feed}
.RE .PP
The
If the .B -q
.B -d option suppresses error messages which print when a read or write is partial or
option is specified, debug output will be printed at the beginning of execution. empty and when used twice suppresses diagnostic output entirely.
This debug information contains information regarding how the program was .PP
invoked. The following example is the result of running the program with In non-recoverable errors that don't pertain to dj's read-write cycle, a
.B -d diagnostic message is printed and dj exits with the appropriate sysexits(3)
as the only argument: status.
.RS
.R argv0=dj
.R in=<stdin> ibs=1024 skip=0 align=ff count=0
.R out=<stdout> obs=1024 seek=0 debug= 3 noerror=0
.RE
In non-recoverable errors that dont pertain to the read-write cycle, a
diagnostic message is printed and the program exits with the appropriate
sysexits.h(3) status.
.SH BUGS .SH BUGS
@@ -189,29 +136,25 @@ expected (the product of the count multiplied by the input block size). If the
or or
.B -A .B -A
options are used this could make data written nonsensical. options are used this could make data written nonsensical.
.PP
Many lowercase options have capitalized variants and vice-versa which can be Many lowercase options have capitalized variants and vice-versa which can be
confusing. Capitalized options tend to affect output or are more intense confusing. Capitalized options tend to affect output or are more intense
versions of lowercase options. versions of lowercase options.
.SH CAVEATS
Existing files are not truncated on ouput and are instead overwritten.
.SH RATIONALE .SH RATIONALE
This program was based on the dd(1p) utility as specified in POSIX. While Dj was modeled after the dd utility specified in POSIX but adds additional
character conversion may have been the original intent of dd(1p), it is features: typical option formatting, allowing seeks to be specified in bytes
irrelevant to its modern use. Because of this, it eschews character conversion
and adds typical option formatting, allowing seeks to be specified in bytes
rather than in blocks, allowing arbitrary bytes as padding, and printing in a rather than in blocks, allowing arbitrary bytes as padding, and printing in a
format thats easy to parse for machines. format that's easy to parse for machines. It also neglects character
conversion, which may be dd's original intent but is irrelevant to its modern
use.
.SH COPYRIGHT .SH COPYRIGHT
Copyright © 2023 DTB. License AGPLv3+: GNU AGPL version 3 or later Copyright (C) 2023 DTB. License AGPLv3+: GNU AGPL version 3 or later
<https://gnu.org/licenses/agpl.html>. <https://gnu.org/licenses/agpl.html>.
.SH SEE ALSO .SH SEE ALSO
dd(1p) dd(1)
+6 -5
View File
@@ -1,5 +1,5 @@
.\" Copyright (c) 2022, 2024 DTB <trinity@trinity.moe> .\" Copyright (c) 2022, 2024 DTB <trinity@trinity.moe>
.\" Copyright (c) 20232024 Emma Tebibyte <emma@tebibyte.media> .\" Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media>
.\" .\"
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license, .\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>. .\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
@@ -12,13 +12,14 @@ false \(en do nothing, unsuccessfully
.SH DESCRIPTION .SH DESCRIPTION
Do nothing regardless of operands or standard input. False does nothing regardless of operands or standard input.
An exit code of 1 will always be returned. False will always return an exit code of 1.
.SH RATIONALE .SH RATIONALE
In POSIX.1-2017, false(1p) exists for the construction of control flow and loops False exists for the construction of control flow and loops based on a failure.
based on a failure. This implementation functions as described in that standard.
False functions as described in POSIX.1-2017.
.SH AUTHOR .SH AUTHOR
-60
View File
@@ -1,60 +0,0 @@
.\" Copyright (c) 2024 DTB <trinity@trinity.moe>
.\" Copyright (c) 2024 Emma Tebibyte <emma@tebibyte.media>
.\"
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
.TH fop 1
.SH NAME
fop \(en field operator
.SH SYNOPSIS
fop
.RB ( -d )
.RB [ delimiter ]
.RB index
.RB program...
.SH DESCRIPTION
Performs operations on specified fields in input data.
.SH OPTIONS
.B -d
.RS
Sets a delimiter by which the input data will be split into fields. The default
is an ASCII record separator (␞).
.RE
.SH STANDARD INPUT
Data will be read from the standard input.
.SH CAVEATS
Field indices are zero-indexed, which may be unexpected behavior for some users.
.SH RATIONALE
With the assumption that tools will output data separated with ASCII field
separators, there is
The idea for this utility originated in the fact that GNU ls(1) utility contains
a
.B -h
option which enables human-readable units in file size outputs. This
functionality was broken out into hru(1), but there was no easy way to modify
the field in the ouput of ls(1p) without a new tool.
.SH COPYRIGHT
Copyright © 2024 Emma Tebibyte. License AGPLv3+: GNU AGPL version 3 or later
<https://gnu.org/licenses/agpl.html>.
.SH SEE ALSO
sed(1p)
+10 -12
View File
@@ -3,7 +3,7 @@
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license, .\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>. .\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
.TH hru 1 .TH rpn 1
.SH NAME .SH NAME
@@ -15,20 +15,18 @@ hru
.SH DESCRIPTION .SH DESCRIPTION
Convert counts to higher units. Hru reads byte counts in the form of whole numbers from the standard input and
writes to the standard output the same number converted one of the units of data
The program will read byte counts in the form of whole numbers from the standard defined by the International System of Units.
input and write to the standard output the same number converted to a higher
unit of data as defined by the International System of Units.
The program will convert the byte count to the highest unit possible where the The program will convert the byte count to the highest unit possible where the
value is greater than one. value is greater than one.
.SH DIAGNOSTICS .SH DIAGNOSTICS
If encountering non-integer characters in the standard input, the program will If encountering non-integer characters in the standard input, hru will exit with
exit with the appropriate error code as defined by sysexits.h(3) and print an the appropriate error code as defined by sysexits.h(3) and print an error
error message. message.
.SH RATIONALE .SH RATIONALE
@@ -41,9 +39,9 @@ program.
.SH STANDARDS .SH STANDARDS
The standard unit prefixes as specified by the Bureau International des Poids Hru follows the standard unit prefixes as specified by the Bureau International
et Mesures (BIPM) in the ninth edition of The International System of Units des Poids et Mesures (BIPM) in the ninth edition of The International System of
(SI) are utilized for the ouput of conversions. Units (SI).
.SH AUTHOR .SH AUTHOR
+20 -34
View File
@@ -1,5 +1,5 @@
.\" Copyright (c) 20232024 DTB <trinity@trinity.moe> .\" Copyright (c) 20232024 DTB <trinity@trinity.moe>
.\" Copyright (c) 20232024 Emma Tebibyte <emma@tebibyte.media> .\" Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media>
.\" .\"
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license, .\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>. .\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
@@ -13,59 +13,45 @@ intcmp \(en compare integers
.SH SYNOPSIS .SH SYNOPSIS
intcmp intcmp
.RB ( -egl ) .RB ( -eghl )
.RB [ integer ] .RB [ integer ]
.RB [ integer... ] .RB [ integer... ]
.SH DESCRIPTION .SH DESCRIPTION
Compare integers to each other. Intcmp compares integers.
.SH USAGE .SH USAGE
.B -e The -e option permits given integers to be equal to each other. If combined
.RS with -g or -l, only adjacent integers in the argument sequence can be equal.
Permits given integers to be equal to each other. .PP
.RE The -g option permits a given integer to be greater than the following integer.
.PP
.B -g The -l option permits a given integer to be less than the following integer.
.RS .PP
Permits a given integer to be greater than the following integer.
.RE
.B -l
.RS
Permits a given integer to be less than the following integer.
.RE
.SH EXAMPLES
It may help to think of the -e, -g, and -l options as equivalent to the It may help to think of the -e, -g, and -l options as equivalent to the
infix algebraic “=”, “>”, and “<” operators respectively, with each option infix algebraic “=”, “>”, and “<” operators respectively, with each option
putting its symbol between every given integer. The following example is putting its symbol between every given integer. For example,
equivalent to evaluating “1 < 2 < 3”:
.RS
.R intcmp -l 1 2 3 .R intcmp -l 1 2 3
.RE is equivalent to evaluating "1 < 2 < 3".
.SH DIAGNOSTICS .SH DIAGNOSTICS
The program will exit with a status code of 0 for a valid expression and with a Intcmp exits 0 for a valid expression and 1 for an invalid expression.
code of 1 for an invalid expression. .PP
Intcmp prints a debug message and exits with the appropriate sysexits(3) error
In the event of an error, a debug message will be printed and the program will code in the event of an error.
exit with the appropriate sysexits.h(3) error code.
.SH BUGS .SH BUGS
There are multiple ways to express compound comparisons; “less than or equal There are multiple ways to express compound comparisons; “less than or equal
to” can be -le or -el, for example. to” can be -le or -el, for example.
.PP
The inequality comparison is -gl or -lg for “less than or greater than”; this The inequality comparison is -gl or -lg for “less than or greater than”; this
is elegant but unintuitive. is elegant but unintuitive.
.PP
-egl, equal to or less than or greater than, exits 0 no matter what for valid -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. program usage and may be abused to function as an integer validator.
Use str(1) instead. Use str(1) instead.
@@ -75,7 +61,7 @@ The traditional tool for integer comparisons in POSIX and other Unix shells has
been test(1). This tool also handles string comparisons and file scrutiny. been test(1). This tool also handles string comparisons and file scrutiny.
These parts of its functionality have been broken out into multiple utilities. These parts of its functionality have been broken out into multiple utilities.
This programs functionality may be performed on a POSIX-compliant system with Strcmps functionality may be performed on a POSIX-compliant system with
test(1p). test(1p).
.SH AUTHOR .SH AUTHOR
+26 -38
View File
@@ -20,63 +20,51 @@ mm
.SH DESCRIPTION .SH DESCRIPTION
Catenate input files and write them to the start of each output file or stream. Mm catenates input files and writes them to the start of each output file.
.SH OPTIONS .SH OPTIONS
Mm, upon receiving the
.B -a .B -a
.RS option, will open subsequent outputs for appending rather than updating.
Opens subsequent outputs for appending rather than updating. .PP
.RE The
.B -e
.RS
Use the standard error as an output.
.RE
.B -i .B -i
.RS option opens a path as an input. Without any inputs specified mm will use
Opens a path as an input. Without any inputs specified mm will use the standard input. Standard input itself can be specified by giving the path '-'.
standard input. The standard input shall be used as an input if one or more of .PP
the input files is “-”. The
.RE
.B -o .B -o
.RS option opens a path as an output. Without any outputs specified mm will use
Opens a path as an output. Without any outputs specified mm will use the standard output. Standard output itself can be specified by giving the
standard output. The standard output shall be used as an output if one or more path '-'. Standard error itself can be specified with the
of the output files is “-”. .B -e
option.
.RE .PP
The
.B -u .B -u
.RS option ensures neither input or output will be buffered.
Ensures neither input or output will be buffered. .PP
.RE The
.B -n .B -n
.RS option tells mm to ignore SIGINT signals.
Causes SIGINT signals to be ignored.
.RE
.SH DIAGNOSTICS .SH DIAGNOSTICS
If an output can no longer be written mm prints a diagnostic message, ceases If an output can no longer be written mm prints a diagnostic message, ceases
writing to that particular output, and if there are more outputs specified, writing to that particular output, and if there are more outputs specified,
continues, eventually exiting unsuccessfully. continues, eventually exiting unsuccessfully.
.PP
On error mm prints a diagnostic message and exits with the appropriate
sysexits.h(3) status.
When an error is encountered, diagnostic message is printed and the program .SH BUGS
exits with the appropriate sysexits.h(3) status.
.SH CAVEATS Mm does not truncate existing files, which may lead to unexpected results.
Existing files are not truncated on ouput and are instead overwritten.
.SH RATIONALE .SH RATIONALE
The cat(1p) and tee(1p) programs specified in POSIX together provide similar Mm was modeled after the cat and tee utilities specified in POSIX.
functionality. The separation of the two sets of functionality into separate
APIs seemed unncessary.
.SH COPYRIGHT .SH COPYRIGHT
+20 -27
View File
@@ -1,5 +1,5 @@
.\" Copyright (c) 20232024 DTB <trinity@trinity.moe> .\" Copyright (c) 20232024 DTB <trinity@trinity.moe>
.\" Copyright (c) 20232024 Emma Tebibyte <emma@tebibyte.media> .\" Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media>
.\" .\"
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license, .\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>. .\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
@@ -13,50 +13,43 @@ npc \(en show non-printing characters
.SH SYNOPSIS .SH SYNOPSIS
npc npc
.RB ( -et ) .RB ( -eht )
.SH DESCRIPTION .SH DESCRIPTION
Print normally non-printing characters. Npc reads from standard input and writes to standard output, replacing non-
printing characters with printable equivalents. Control characters print as a
The program reads from standard input and writes to standard output, replacing carat ('^') followed by the character '@' through '_' corresponding to the
non-printing characters with printable equivalents. Control characters print as character replaced (e.g. control-X becomes "^X"). The delete character (0x7F)
a carat ('^') followed by the character '@' through '_' corresponding to the becomes "^?". Characters with the high bit set (>127) are printed as "M-"
character replaced (e.g. control-X becomes '^X'). The delete character (0x7F)
becomes '^?'. Characters with the high bit set (>127) are printed as 'M-'
followed by the graphical representation for the same character without the followed by the graphical representation for the same character without the
high bit set. high bit set.
.PP
.SH USAGE The
.B -e .B -e
.RS option prints a currency sign ('$') before each line ending.
Prints a currency sign ('$') before each line ending. .PP
.RE The
.B -t .B -t
.RS option prints tab characters as "^I" rather than a literal horizontal tab.
Prints tab characters as '^I' rather than a literal horizontal tab.
.RE
.SH DIAGNOSTICS .SH DIAGNOSTICS
In the event of an error, a debug message will be printed and the program will Npc prints a debug message and exits with the appropriate sysexits(3) error
exit with the appropriate sysexits.h(3) error code. code in the event of an error, otherwise it exits successfully.
.SH BUGS .SH BUGS
The program operates in single-byte chunks regardless of intended encoding. Npc operates in single-byte chunks regardless of intended encoding.
.SH RATIONALE .SH RATIONALE
POSIX currently lacks a way to display non-printing characters in the terminal POSIX currently lacks a way to display non-printing characters in the terminal
using a standard tool. A popular extension to cat(1p), the using a standard tool. A popular extension to cat(1p), the -v option, is the
.B -v bandage solution GNU and other software suites use.
option, is the bandage solution GNU and other software suites use.
This functionality is a separate tool because its usefulness extends beyond that This functionality should be a separate tool because its usefulness extends
of cat(1p). beyond that of cat(1p).
.SH AUTHOR .SH AUTHOR
+9 -14
View File
@@ -17,13 +17,10 @@ rpn
.SH DESCRIPTION .SH DESCRIPTION
Evaluate reverse polish notation. Rpn evaluates reverse polish notation expressions either read from the standard
input or parsed from provided arguments. See the STANDARD INPUT section.
The program evaluates reverse polish notation expressions either read from the Upon evaluation, rpn will print the resulting number on the stack to the
standard input or parsed from provided arguments. See the STANDARD INPUT
section.
Upon evaluation, the program will print the resulting number on the stack to the
standard output. Any further specified numbers will be placed at the end of the standard output. Any further specified numbers will be placed at the end of the
stack. stack.
@@ -31,16 +28,14 @@ For information on for reverse polish notation syntax, see rpn(7).
.SH STANDARD INPUT .SH STANDARD INPUT
If arguments are passed , they are interpreted as an expression to be evaluated. If arguments are passed to rpn, it interprets them as an expression to be
Otherwise, it reads whitespace-delimited numbers and operations from the evaluated. Otherwise, it reads whitespace-delimited numbers and operations from
standard input. the standard input.
.SH DIAGNOSTICS .SH DIAGNOSTICS
In the event of a syntax error, the program will print an If encountering a syntax error, rpn will exit with the appropriate error code
as defined by sysexits.h(3) and print an error message.
In the event of an error, a debug message will be printed and the program will
exit with the appropriate sysexits.h(3) error code.
.SH CAVEATS .SH CAVEATS
@@ -49,7 +44,7 @@ with the IEEE Standard for Floating Point Arithmetic (IEEE 754), floating-point
arithmetic has rounding errors. This is somewhat curbed by using the arithmetic has rounding errors. This is somewhat curbed by using the
machine epsilon as provided by the Rust standard library to which to round machine epsilon as provided by the Rust standard library to which to round
numbers. Because of this, variation is expected in the number of decimal places numbers. Because of this, variation is expected in the number of decimal places
the program can handle based on the platform and hardware of any given machine. rpn can handle based on the platform and hardware of any given machine.
.SH RATIONALE .SH RATIONALE
+35 -66
View File
@@ -1,5 +1,4 @@
.\" Copyright (c) 2024 DTB <trinity@trinity.moe> .\" Copyright (c) 2024 DTB <trinity@trinity.moe>
.\" Copyright (c) 2024 Emma Tebibyte <emma@tebibyte.media>
.\" .\"
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license, .\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>. .\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
@@ -18,92 +17,62 @@ scrut
.SH DESCRIPTION .SH DESCRIPTION
Determine if files comply with requirements. Scrut determines if given files comply with the opted requirements.
.SH OPTIONS .SH OPTIONS
.B -L
.RS
Requires the given files to exist and be symbolic links.
.RE
.B -S
.RS
Requires the given files to exist and be sockets.
.RE
.B -b .B -b
.RS requires the given files to exist and be block special files.
Requires the given files to exist and be block special files. .PP
.RE
.B -c .B -c
.RS requires the given files to exist and be character special files.
Requires the given files to exist and be character special files. .PP
.RE
.B -d .B -d
.RS requires the given files to exist and be directories.
Requires the given files to exist and be directories. .PP
.RE
.B -e .B -e
.RS requires the given files to exist, and is redundant to any other option.
Requires the given files to exist, and is redundant to any other option. .PP
.RE
.B -e .B -e
.RS requires the given files to exist and be regular files.
Requires the given files to exist and be regular files. .PP
.RE
.B -g .B -g
.RS requires the given files to exist and have their set group ID flags set.
Requires the given files to exist and have their set group ID flags set. .PP
.RE
.B -k .B -k
.RS requires the given files to exist and have their sticky bit set.
Requires the given files to exist and have their sticky bit set. .PP
.RE
.B -p .B -p
.RS requires the given files to exist and be named pipes.
Requires the given files to exist and be named pipes. .PP
.RE
.B -r .B -r
.RS requires the given files to exist and be readable.
Requires the given files to exist and be readable. .PP
.RE
.B -u .B -u
.RS requires the given files to exist and have their set user ID flags set.
Requires the given files to exist and have their set user ID flags set. .PP
.RE
.B -w .B -w
.RS requires the given files to exist and be writable.
Requires the given files to exist and be writable. .PP
.RE
.B -x .B -x
.RS requires the given files to exist and be executable.
Requires the given files to exist and be executable. .PP
.RE .B -L
requires the given files to exist and be symbolic links.
.PP
.B -S
requires the given files to exist and be sockets.
.SH EXIT STATUS .SH EXIT STATUS
If the given files comply with the specified requirements, the program will exit Scrut prints a debug message and exits unsuccessfully with the appropriate
successfully. If not, it exits unsuccessfully. sysexits.h(3) error code if invoked incorrectly. Scrut exits successfully if
the given files comply with their requirements and unsuccessfully otherwise.
When invoked incorrectly, a debug message will be printed and the program will
exit with the appropriate sysexits.h(3) error code.
.SH STANDARDS .SH STANDARDS
The test(1p) utility contains functionality that was broken out into separate Scrut is nearly compatible with POSIX's test utility though it is narrower in
programs. Thus, the scope of this program is narrower than it. Notably, the scope. Notably, the
.B -h .B -h
option is now invalid and therefore shows usage information instead of being an option is now invalid and therefore shows usage information instead of being an
alias to the modern alias to the modern
+16 -13
View File
@@ -1,5 +1,5 @@
.\" Copyright (c) 20232024 DTB <trinity@trinity.moe> .\" Copyright (c) 20232024 DTB <trinity@trinity.moe>
.\" Copyright (c) 20232024 Emma Tebibyte <emma@tebibyte.media> .\" Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media>
.\" .\"
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license, .\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>. .\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
@@ -18,27 +18,30 @@ str
.SH DESCRIPTION .SH DESCRIPTION
Test string arguments. Str tests each character in an arbitrary quantity of string arguments against
the function of the same name within ctype(3).
The tests in this program are equivalent to the functions with the same names in
ctype.h(0p) and are the methods by which string arguments are tested.
.SH DIAGNOSTICS .SH DIAGNOSTICS
If all tests pass, the program will exit with an exit code of 0. If any of the Str exits successfully if all tests pass and unsuccessfully if a test failed.
tests fail, the program will exit unsuccessfully with an error code of 1. .PP
Str will exit unsuccessfully if a string is empty, as none of its contents
passed the test.
.PP
Str will print a message to standard error and exit unsuccessfully if used
improperly.
An empty string will cause an unsuccessful exit as none of its contents pass any .SH DEPRECATED FEATURES
tests.
When invoked incorrectly, a debug message will be printed and the program will Str used to have an "isvalue" type as an extension to ctype(3). This was
exit with the appropriate sysexits.h(3) error code. removed in favor of using strcmp(1) to compare strings against the empty string
('').
.SH BUGS .SH BUGS
Theres no way of knowing which argument failed the test without re-testing There's no way of knowing which argument failed the test without re-testing
arguments individually. arguments individually.
.PP
If a character in a string isn't valid ASCII str will exit unsuccessfully. If a character in a string isn't valid ASCII str will exit unsuccessfully.
.SH AUTHOR .SH AUTHOR
+13 -14
View File
@@ -1,5 +1,5 @@
.\" Copyright (c) 20232024 DTB <trinity@trinity.moe> .\" Copyright (c) 20232024 DTB <trinity@trinity.moe>
.\" Copyright (c) 20232024 Emma Tebibyte <emma@tebibyte.media> .\" Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media>
.\" .\"
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license, .\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>. .\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
@@ -18,27 +18,26 @@ strcmp
.SH DESCRIPTION .SH DESCRIPTION
Check whether string arguments are the same. Strcmp checks whether the given strings are the same.
Strcmp exits successfully if the strings are identical. Otherwise, strcmp exits
.SH DIAGNOSTICS with the value 1 if an earlier string has a greater byte value than a later
string (e.g.
The program will exit successfully if the strings are identical. Otherwise, it
exits with the value 1 if an earlier string has a greater byte value than a
later string (e.g.
.R strcmp b a .R strcmp b a
) )
and 255 if an earlier string has a lesser byte value (e.g. and 255 if an earlier string has a lesser byte value (e.g.
.R strcmp a b .R strcmp a b
). ).
When invoked incorrectly, a debug message will be printed and the program will .SH DIAGNOSTICS
exit with the appropriate sysexits.h(3) error code.
Strcmp will print an error message and exit unsuccessfully with a status
described in sysexits(3) if used incorrectly (given less than two operands).
.SH UNICODE .SH UNICODE
The program will exit unsuccessfully if the given strings are not identical; Strcmp will exit unsuccessfully if the given strings are not identical;
therefore, Unicode strings may need to be normalized if the intent is to check Unicode strings may need to be normalized if the intent is to check visual
visual similarity and not byte similarity. similarity and not byte similarity.
.SH RATIONALE .SH RATIONALE
@@ -46,7 +45,7 @@ The traditional tool for string comparisons in POSIX and other Unix shells has
been test(1). This tool also handles integer comparisons and file scrutiny. been test(1). This tool also handles integer comparisons and file scrutiny.
These parts of its functionality have been broken out into multiple utilities. These parts of its functionality have been broken out into multiple utilities.
This programs functionality may be performed on a POSIX-compliant system with Strcmps functionality may be performed on a POSIX-compliant system with
test(1p). test(1p).
.SH AUTHOR .SH AUTHOR
+23 -29
View File
@@ -1,5 +1,4 @@
.\" Copyright (c) 2024 DTB <trinity@trinity.moe> .\" Copyright (c) 2024 DTB <trinity@trinity.moe>
.\" Copyright (c) 2024 Emma Tebibyte <emma@tebibyte.media>
.\" .\"
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license, .\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>. .\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
@@ -21,51 +20,46 @@ swab
.SH USAGE .SH USAGE
Swap the latter and former halves of a block of bytes. Swab swaps the latter and former halves of a block of bytes.
.SH OPTIONS
.B -f
.RS
Ignore system call interruptions.
.RE
.B -w
.RS
Configures the word size; that is, the size in bytes of the block size
on which to operate. By default the word size is 2. The word size must be
cleanly divisible by 2, otherwise the block of bytes being processed can't be
halved.
.RE
.SH EXAMPLES .SH EXAMPLES
The following sh(1p) line: The following sh(1p) line:
.RS
.R printf 'hello world!\n' | swab .R printf 'hello world!\n' | swab
.RE
Produces the following output: Produces the following output:
.RS
.R ehll oowlr!d .R ehll oowlr!d
.RE
.SH OPTIONS
The
.B -f
option ignores system call interruptions.
.PP
The
.B -w
option configures the word size; that is, the size in bytes of the block size
on which to operate. By default the word size is 2. The word size must be
cleanly divisible by 2, otherwise the block of bytes being processed can't be
halved.
.SH DIAGNOSTICS .SH DIAGNOSTICS
In the event of an error, a debug message will be printed and the program will If an error is encountered in input, output, or invocation, a diagnostic
exit with the appropriate sysexits.h(3) error code. message will be written to standard error and swab will exit with the
appropriate status from sysexits.h(3).
.SH RATIONALE .SH RATIONALE
This program was modeled and named after the Swab was modeled after the
.R conv=swab .R conv=swab
functionality specified in the dd(1p) utility. It additionally allows the word functionality specified in the POSIX dd utility but additionally allows the
size to be configured. word size to be configured.
.PP
This functionality is useful for fixing the endianness of binary files produced Swab is useful for fixing the endianness of binary files produced on other
on other machines. machines.
.SH COPYRIGHT .SH COPYRIGHT
+6 -5
View File
@@ -1,5 +1,5 @@
.\" Copyright (c) 2022, 2024 DTB <trinity@trinity.moe> .\" Copyright (c) 2022, 2024 DTB <trinity@trinity.moe>
.\" Copyright (c) 20232024 Emma Tebibyte <emma@tebibyte.media> .\" Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media>
.\" .\"
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license, .\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>. .\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
@@ -12,13 +12,14 @@ true \(en do nothing, successfully
.SH DESCRIPTION .SH DESCRIPTION
Do nothing regardless of operands or standard input. True does nothing regardless of operands or standard input.
An exit code of 0 will always be returned. True will always return an exit code of 0.
.SH RATIONALE .SH RATIONALE
In POSIX.1-2017, true(1p) exists for the construction of control flow and loops True exists for the construction of control flow and loops based on a success.
based on a success. This implementation functions as described in that standard.
True functions as described in POSIX.1-2017.
.SH AUTHOR .SH AUTHOR
+58 -112
View File
@@ -46,31 +46,11 @@ struct Io{
/* Additionally, the following global variables are used to store user options. /* Additionally, the following global variables are used to store user options.
*/ */
/* (-a) */ static int align; /* Only the lower 8b are used but align is
* negative if no alignment is being done. */
/* (-c) */ static int count; /* 0 if dj(1) runs until no more reads are
* possible. */
/* ASCII field separator delimited statistics */ /* ASCII field separator delimited statistics */
static char *fmt_asv = "%d\037%d\036%d\037%d\035%d\036%d\034"; static char *fmt_asv = "%d\037%d\036%d\037%d\035%d\036%d\034";
/* human-readable statistics */
/* (-H) Human-readable statistics */
static char *fmt_human = "%d+%d > %d+%d; %d > %d\n"; static char *fmt_human = "%d+%d > %d+%d; %d > %d\n";
/* pointer to chosen formatting */
/* (-H) */ static char *fmt_output; /* fmt_asv (default) or fmt_human (-H) */
/* (-dq) */ static char debug; /*
* -d increments dj -qq | 0 - no diagnostic output whatsoever
* -q decrements dj -q | 1 - typical output without
* | notifications on partial reads or
* | writes
* dj | 2 - typical output (default)
* dj -d | 3 - verbose status messages */
/* (-n) */ static char noerror; /* 0 - exits on partial reads or writes
* (default)
* 1 - retries on partial reads/writes
* (-n) */
/* Non-configurable defaults. */ /* Non-configurable defaults. */
#define bs_default 1024 /* GNU dd(1) default; twice POSIX but a neat 2^10 */ #define bs_default 1024 /* GNU dd(1) default; twice POSIX but a neat 2^10 */
@@ -80,19 +60,8 @@ static char *stdout_name = "<stdout>";
static int read_flags = O_RDONLY; /* These flags are consistent with Busybox */ static int read_flags = O_RDONLY; /* These flags are consistent with Busybox */
static int write_flags = O_WRONLY | O_CREAT; /* dd(1). */ static int write_flags = O_WRONLY | O_CREAT; /* dd(1). */
/* Macro to set defaults for user-configurable options. */
#define setdefaults do{ \
align = -1; \
count = 0; \
debug = 2; \
fmt_output = fmt_asv; \
noerror = 0; \
ep[0].fl = read_flags; \
Io_setdefaults(&ep[0]); \
ep[1].fl = write_flags; \
Io_setdefaults(&ep[1]); }while(0)
#define MIN(a, b) (((a) < (b)) ? (a) : (b)) #define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
/* Macro to check if fd is a std* file, e.g. stdin. */ /* Macro to check if fd is a std* file, e.g. stdin. */
#define fdisstd(fd) \ #define fdisstd(fd) \
@@ -104,38 +73,11 @@ static int write_flags = O_WRONLY | O_CREAT; /* dd(1). */
* particular io[2] used in main. Error conditions are not checked because this * particular io[2] used in main. Error conditions are not checked because this
* is only used when the program is about to terminate (hence its name). */ * is only used when the program is about to terminate (hence its name). */
#define terminate(io) do{ \ #define terminate(io) do{ \
Io_buffree(&(io)[0]); \ free((io)[0].buf); \
Io_buffree(&(io)[1]); \ free((io)[1].buf); \
Io_fdclose(&(io)[0]); \ Io_fdclose(&(io)[0]); \
Io_fdclose(&(io)[1]); }while(0) Io_fdclose(&(io)[1]); }while(0)
/* Allocates *io's buffer. Returns NULL if unsuccessful. */
static void *
Io_bufalloc(struct Io *io){
return (io->buf = malloc(io->bs * (sizeof *io->buf)));
}
/* Frees *io's buffer. Returns io. */
static struct Io *
Io_buffree(struct Io *io){
free(io->buf);
return io;
}
/* Fills the unused portion of io's buffer with padding, updating io->bufuse.
* Returns io. */
static struct Io *
Io_bufrpad(struct Io *io, int padding){
memset(io->buf + io->bufuse, padding, io->bs - io->bufuse);
io->bufuse = io->bs;
return io;
}
/* Copies from the buffer in src as much as possible to the free space in the /* Copies from the buffer in src as much as possible to the free space in the
* dest buffer, removing the copied units from src and permuting the remaining * dest buffer, removing the copied units from src and permuting the remaining
* units in the src buffer to the start of the buffer, modifying both the src * units in the src buffer to the start of the buffer, modifying both the src
@@ -167,13 +109,10 @@ Io_bufxfer(struct Io *dest, struct Io *src, int n){
} }
/* Closes io->fn and returns -1 on error, otherwise io->fd. */ /* Closes io->fn and returns -1 on error, otherwise io->fd. */
static int #define Io_fdclose(io) \
Io_fdclose(struct Io *io){ (fdisstd((io)->fd) \
? 0 \
return fdisstd(io->fd) : close((io)->fd))
? 0
: close(io->fd);
}
/* Opens io->fn and saves the file descriptor into io->fd. Returns io->fd, /* Opens io->fn and saves the file descriptor into io->fd. Returns io->fd,
* which will be -1 if an error occured. */ * which will be -1 if an error occured. */
@@ -199,7 +138,6 @@ Io_fdopen(struct Io *io, char *fn){
* be set to zero to indicate the seek occurred. */ * be set to zero to indicate the seek occurred. */
static int static int
Io_fdseek(struct Io *io){ Io_fdseek(struct Io *io){
int (*op)(int, void *, size_t);
if(!fdisstd(io->fd) && lseek(io->fd, io->seek, SEEK_SET) != -1) if(!fdisstd(io->fd) && lseek(io->fd, io->seek, SEEK_SET) != -1)
return -1; return -1;
@@ -283,19 +221,6 @@ oserr(char *s){
return EX_OSERR; return EX_OSERR;
} }
/* Prints statistics regarding the use of dj, particularly partially and
* completely read and written records, accessing debug, ep, and fmt_output. */
static void
output(void){
if(debug >= 1)
fprintf(stderr, fmt_output,
ep[0].rec, ep[0].prec, ep[1].rec, ep[1].prec,
ep[0].bytes, ep[1].bytes);
return;
}
/* Parses the string s to an integer, returning either the integer or in the /* Parses the string s to an integer, returning either the integer or in the
* case of an error a negative integer. This is used for argument parsing * case of an error a negative integer. This is used for argument parsing
* (e.g. -B [int]) in dj and no negative integer would be valid anyway. */ * (e.g. -B [int]) in dj and no negative integer would be valid anyway. */
@@ -321,11 +246,30 @@ usage(void){
return EX_USAGE; return EX_USAGE;
} }
int main(int argc, char *argv[]){ /* For use in main only.
int c; * Prints statistics regarding the use of dj, particularly partially and
int i; * completely read and written records, accessing ep, and fmt_output. */
#define output fprintf(stderr, fmt_output, \
ep[0].rec, ep[0].prec, ep[1].rec, ep[1].prec, ep[0].bytes, ep[1].bytes \
)
setdefaults; int main(int argc, char *argv[]){
int align; /* Only the lower 8b are used, negative if no alignment. */
int count;
int c, i;
enum { QUIETER = 0, TYPICAL = 1, VERBOSE = 2 } debug;
enum { GIVEUP = 0, RETRY = 1 } error;
char *fmt_output = fmt_asv;
ep[0].fl = read_flags;
Io_setdefaults(&ep[0]);
ep[1].fl = write_flags;
Io_setdefaults(&ep[1]);
align = -1;
count = 0;
debug = TYPICAL;
error = GIVEUP;
if(argc > 0){ if(argc > 0){
program_name = argv[0]; program_name = argv[0];
@@ -342,10 +286,10 @@ int main(int argc, char *argv[]){
terminate(ep); terminate(ep);
return oserr(optarg); return oserr(optarg);
case 'A': align = '\0'; break; case 'A': align = '\0'; break;
case 'd': ++debug; break; case 'd': debug = VERBOSE; break;
case 'n': noerror = 1; break; case 'n': error = RETRY; break;
case 'H': fmt_output = fmt_human; break; case 'H': fmt_output = fmt_human; break;
case 'q': --debug; break; case 'q': debug = QUIETER; break;
case 'a': case 'a':
if(optarg[0] != '\0' && optarg[1] == '\0'){ if(optarg[0] != '\0' && optarg[1] == '\0'){
align = optarg[0]; align = optarg[0];
@@ -367,14 +311,15 @@ int main(int argc, char *argv[]){
} }
} }
if(debug >= 3) if(debug >= VERBOSE)
fprintf(stderr, fprintf(stderr,
"argv0=%s\n" "argv0=%s\n"
"in=%s\tibs=%d\tskip=%ld\talign=%hhx\tcount=%d\n" "in=%s\tibs=%d\tskip=%ld\talign=%hhx\tcount=%d\n"
"out=%s\tobs=%d\tseek=%ld\tdebug=%2d\tnoerror=%d\n", "out=%s\tobs=%d\tseek=%ld\tdebug=%2d\terror=%s\n",
program_name, program_name,
ep[0].fn, ep[0].bs, ep[0].seek, align, count, ep[0].fn, ep[0].bs, ep[0].seek, align, count,
ep[1].fn, ep[1].bs, ep[1].seek, debug, noerror); ep[1].fn, ep[1].bs, ep[1].seek, debug,
error == GIVEUP ? "GIVEUP" : "RETRY");
if(argc > optind){ if(argc > optind){
terminate(ep); terminate(ep);
@@ -382,36 +327,37 @@ int main(int argc, char *argv[]){
} }
for(i = 0; i <= 1; ++i){ for(i = 0; i <= 1; ++i){
if(Io_bufalloc(&ep[i]) == NULL){ if((ep[i].buf = malloc(ep[i].bs * (sizeof ep[i].buf))) == NULL){
fprintf(stderr, "%s: Failed to allocate %d bytes\n", fprintf(stderr, "%s: Failed to allocate %d bytes\n",
program_name, ep[i].bs); program_name, ep[i].bs * (sizeof ep[i].buf));
terminate(ep); terminate(ep);
return EX_OSERR; return EX_OSERR;
}else if(ep[i].seek > 0) }else if(ep[i].seek > 0 && (c = Io_fdseek(&ep[i])) != -1){
switch(Io_fdseek(&ep[i])){ output;
case EX_OK:
output();
terminate(ep); terminate(ep);
return EX_OK; return c;
} }
} }
do{ /* read */ do{ /* read */
Io_read(&ep[0]); Io_read(&ep[0]);
if(!noerror && ep[0].bufuse == 0) if(error == RETRY && ep[0].bufuse == 0)
Io_read(&ep[0]); /* second chance */ Io_read(&ep[0]); /* second chance */
if(ep[0].bufuse == 0) /* that's all she wrote */ if(ep[0].bufuse == 0) /* that's all she wrote */
break; break;
else if(ep[0].bufuse < ep[0].bs){ else if(ep[0].bufuse < ep[0].bs){
++ep[0].prec; ++ep[0].prec;
if(debug >= 2){ if(debug >= TYPICAL){
fprintf(stderr, "%s: Partial read:\n\t", program_name); fprintf(stderr, "%s: Partial read:\n\t", program_name);
output(); output;
} }
if(!noerror) if(error == GIVEUP)
count = 1; count = 1;
if(align >= 0) if(align >= 0){
Io_bufrpad(&ep[0], align); memset(ep[0].buf + ep[0].bufuse, align,
ep[0].bs - ep[0].bufuse);
ep[0].bufuse = ep[0].bs;
}
}else }else
++ep[0].rec; ++ep[0].rec;
@@ -425,18 +371,18 @@ int main(int argc, char *argv[]){
c = ep[1].bufuse; c = ep[1].bufuse;
Io_write(&ep[1]); Io_write(&ep[1]);
if(!noerror && ep[1].bufuse == c) if(error == GIVEUP && ep[1].bufuse == c)
Io_write(&ep[1]); /* second chance */ Io_write(&ep[1]); /* second chance */
if(c == ep[1].bufuse){ /* no more love */ if(c == ep[1].bufuse){ /* no more love */
count = 1; count = 1;
break; break;
}else if(c > ep[1].bufuse && ep[1].bufuse > 0){ }else if(c > ep[1].bufuse && ep[1].bufuse > 0){
ep[1].prec += 1; ep[1].prec += 1;
if(debug >= 2){ if(debug >= TYPICAL){
fprintf(stderr, "%s: Partial write:\n\t", program_name); fprintf(stderr, "%s: Partial write:\n\t", program_name);
output(); output;
} }
if(!noerror) if(error == GIVEUP)
count = 1; count = 1;
}else if(ep[1].bufuse == 0 && c < ep[1].bs) }else if(ep[1].bufuse == 0 && c < ep[1].bs)
++ep[1].prec; ++ep[1].prec;
@@ -445,7 +391,7 @@ int main(int argc, char *argv[]){
}while(ep[0].bufuse > 0); }while(ep[0].bufuse > 0);
}while(count == 0 || --count > 0); }while(count == 0 || --count > 0);
output(); output;
terminate(ep); terminate(ep);
return EX_OK; return EX_OK;