Compare commits
3 Commits
7fe122ac3b
...
adda0d9580
Author | SHA1 | Date | |
---|---|---|---|
adda0d9580 | |||
2167f35f58 | |||
f4b97be1f1 |
65
docs/dj.1
65
docs/dj.1
@ -4,7 +4,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 DJ 1 2024-06-29 "Harakit X.X.X"
|
.TH DJ 1 2024-07-03 "Harakit X.X.X"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
dj \(en disk jockey
|
dj \(en disk jockey
|
||||||
.\"
|
.\"
|
||||||
@ -34,10 +34,17 @@ respectively. This language is inherited from the
|
|||||||
.BR dd (1p)
|
.BR dd (1p)
|
||||||
utility and used here to decrease ambiguity.
|
utility and used here to decrease ambiguity.
|
||||||
|
|
||||||
When seeking or skipping to a byte, writing or reading starts at the byte
|
The offset used when skipping or seeking refers to how many bytes are skipped
|
||||||
immediately subsequent to the specified byte. Seeks and skips aren\(cqt counted
|
or sought. Running
|
||||||
in the output statistics because they're guaranteed to succeed (or the utility
|
.BR dj (1)
|
||||||
will exit unsuccessfully).
|
with a skip offset of 1 skips one byte into the input and reads from the second
|
||||||
|
byte onwards. A programmer may think of a file as a zero-indexed array of
|
||||||
|
bytes; in this analogy, the offset given is the index of the byte at which to
|
||||||
|
start reading or writing.
|
||||||
|
|
||||||
|
Seeks and skips aren\(cqt counted in the output statistics because they're
|
||||||
|
guaranteed to succeed (or the utility will exit unsuccessfully, before it has
|
||||||
|
written any data).
|
||||||
.\"
|
.\"
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
|
|
||||||
@ -82,6 +89,54 @@ input file is \(lq-\(rq.
|
|||||||
The standard output shall be used as an output if no inputs are specified or if
|
The standard output shall be used as an output if no inputs are specified or if
|
||||||
the output file is \(lq-\(rq.
|
the output file is \(lq-\(rq.
|
||||||
.\"
|
.\"
|
||||||
|
.SH EXAMPLES
|
||||||
|
|
||||||
|
The following
|
||||||
|
.BR sh (1p)
|
||||||
|
line:
|
||||||
|
|
||||||
|
.RS
|
||||||
|
printf 'Hello, world!\(rsn' | dj -c 1 -b 7 -s 7 2>/dev/null
|
||||||
|
.RE
|
||||||
|
|
||||||
|
Produces the following output:
|
||||||
|
|
||||||
|
.RS
|
||||||
|
world!
|
||||||
|
.RE
|
||||||
|
|
||||||
|
The following
|
||||||
|
.BR sh (1p)
|
||||||
|
lines run sequentially:
|
||||||
|
|
||||||
|
.RS
|
||||||
|
tr '\(rs0' 0 </dev/zero | dj -c 1 -b 6 -o hello.txt
|
||||||
|
|
||||||
|
tr '\(rs0' H </dev/zero | dj -c 1 -b 1 -o hello.txt
|
||||||
|
|
||||||
|
tr '\(rs0' e </dev/zero | dj -c 1 -b 1 -o hello.txt -S 1
|
||||||
|
|
||||||
|
tr '\(rs0' l </dev/zero | dj -c 1 -b 2 -o hello.txt -S 2
|
||||||
|
|
||||||
|
tr '\(rs0' o </dev/zero | dj -c 1 -b 1 -o hello.txt -S 4
|
||||||
|
|
||||||
|
tr '\(rs0' '\(rsn' </dev/zero | dj -c 1 -b 1 -o hello.txt -S 5
|
||||||
|
|
||||||
|
dj -i hello.txt
|
||||||
|
.RE
|
||||||
|
|
||||||
|
Produce the following output:
|
||||||
|
|
||||||
|
.RS
|
||||||
|
Hello
|
||||||
|
.RE
|
||||||
|
|
||||||
|
It may be particularly illuminating to print the contents of the example
|
||||||
|
.B hello.txt
|
||||||
|
after each
|
||||||
|
.BR dj (1)
|
||||||
|
invocation.
|
||||||
|
.\"
|
||||||
.SH DIAGNOSTICS
|
.SH DIAGNOSTICS
|
||||||
|
|
||||||
On a partial or empty read, a diagnostic message is printed. Then, the program
|
On a partial or empty read, a diagnostic message is printed. Then, the program
|
||||||
|
37
src/dj.c
37
src/dj.c
@ -38,12 +38,12 @@ struct Io{
|
|||||||
int bs; /* buffer size (-bB) */
|
int bs; /* buffer size (-bB) */
|
||||||
size_t bufuse; /* buffer usage */
|
size_t bufuse; /* buffer usage */
|
||||||
char *buf; /* buffer */
|
char *buf; /* buffer */
|
||||||
int bytes; /* bytes processed */
|
size_t bytes; /* bytes processed */
|
||||||
int fd; /* file descriptor */
|
int fd; /* file descriptor */
|
||||||
int fl; /* file opening flags */
|
int fl; /* file opening flags */
|
||||||
char *fn; /* file name (may be stdin_name or stdout_name) (-io) */
|
char *fn; /* file name (may be stdin_name or stdout_name) (-io) */
|
||||||
int prec; /* partial records processed */
|
size_t prec; /* partial records processed */
|
||||||
int rec; /* records processed */
|
size_t rec; /* records processed */
|
||||||
long seek; /* bytes to seek/skip (will be 0 after skippage) (-sS) */
|
long seek; /* bytes to seek/skip (will be 0 after skippage) (-sS) */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -75,25 +75,6 @@ Io_bufrpad(struct Io *io, int padding){
|
|||||||
return io;
|
return io;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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
|
|
||||||
* units in the src buffer to the start of the buffer, modifying both the src
|
|
||||||
* and dest bufuse and returning dest. */
|
|
||||||
static struct Io*
|
|
||||||
Io_bufxapp(struct Io *dest, struct Io *src){
|
|
||||||
int n;
|
|
||||||
|
|
||||||
assert(dest != NULL && src != NULL);
|
|
||||||
|
|
||||||
n = MIN(src->bufuse, dest->bs - dest->bufuse);
|
|
||||||
memcpy(dest->buf + dest->bufuse, src->buf, n);
|
|
||||||
dest->bufuse += n;
|
|
||||||
memmove(src->buf, src->buf + n, src->bs - n);
|
|
||||||
src->bufuse -= n;
|
|
||||||
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copies from the buffer in src to the buffer in dest no more than n units,
|
/* Copies from the buffer in src to the buffer in dest no more than n units,
|
||||||
* removing the copied units from src and permuting the remaining units in the
|
* 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 and dest
|
* src buffer to the start of the buffer, modifying both the src and dest
|
||||||
@ -216,6 +197,7 @@ int main(int argc, char *argv[]){
|
|||||||
noerror = 0;
|
noerror = 0;
|
||||||
for(i = 0; i < 2; ++i){
|
for(i = 0; i < 2; ++i){
|
||||||
io[i].bs = 1024 /* 1 KiB */; /* GNU dd(1) default; POSIX says 512B */
|
io[i].bs = 1024 /* 1 KiB */; /* GNU dd(1) default; POSIX says 512B */
|
||||||
|
io[i].bufuse = 0;
|
||||||
io[i].bytes = 0;
|
io[i].bytes = 0;
|
||||||
io[i].fd = i == 0 ? STDIN_FILENO : STDOUT_FILENO;
|
io[i].fd = i == 0 ? STDIN_FILENO : STDOUT_FILENO;
|
||||||
io[i].fn = i == 0 ? stdin_name : stdout_name;
|
io[i].fn = i == 0 ? stdin_name : stdout_name;
|
||||||
@ -338,7 +320,16 @@ int main(int argc, char *argv[]){
|
|||||||
int t;
|
int t;
|
||||||
|
|
||||||
if(io[1].bs > io[0].bs){
|
if(io[1].bs > io[0].bs){
|
||||||
Io_bufxapp(&io[1], &io[0]);
|
int n;
|
||||||
|
|
||||||
|
/* copy from ibuf as much as possible to the obuf */
|
||||||
|
memcpy(io[1].buf + io[1].bufuse, io[0].buf,
|
||||||
|
(n = MIN(io[0].bufuse, io[1].bs - io[1].bufuse)));
|
||||||
|
io[1].bufuse += n;
|
||||||
|
/* permute out the copied units */
|
||||||
|
memmove(io[0].buf, io[0].buf + n, io[0].bs - n);
|
||||||
|
io[0].bufuse -= n;
|
||||||
|
|
||||||
if(io[0].bs + io[1].bufuse <= io[1].bs && count != 1)
|
if(io[0].bs + io[1].bufuse <= io[1].bs && count != 1)
|
||||||
continue; /* we could write more */
|
continue; /* we could write more */
|
||||||
}else
|
}else
|
||||||
|
Loading…
Reference in New Issue
Block a user