1
0

works imperfectly

This commit is contained in:
dtb 2024-01-06 09:24:53 -07:00
parent 0b3fc87718
commit 564f7a4381
2 changed files with 62 additions and 13 deletions

1
Wip/dj/Makefile Normal file
View File

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

View File

@ -2,7 +2,7 @@
#include <fcntl.h> /* open(2) */
#include <stdio.h> /* fprintf(3), stderr */
#include <stdlib.h> /* free(3), malloc(3), strtol(3), size_t */
#include <string.h> /* memcpy(3), memset(3) */
#include <string.h> /* memcpy(3), memmove(3), memset(3) */
#include <sysexits.h> /* EX_OK, EX_USAGE */
#include <unistd.h> /* close(2), getopt(3), lseek(2), read(2), write(2),
optarg, optind, STDIN_FILENO, STDOUT_FILENO */
@ -20,7 +20,8 @@
&& (fd) != STDERR_FILENO)
/* Macro to call the cleanup functions that operate on struct io on the
* particular io[2] used in main. */
* 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). */
#define terminate(io) do{ \
Io_buffree(&(io)[0]); \
Io_buffree(&(io)[1]); \
@ -61,6 +62,30 @@ Io_buffree(struct Io *io){
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 to the buffer in dest no more than n units,
* 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_bufxfer(struct Io *dest, struct Io *src, int n){
memcpy(dest->buf, src->buf, (dest->bufuse = n));
memmove(src->buf, src->buf + n, (src->bufuse -= n));
return dest;
}
/* Closes io->fn and returns -1 on error, otherwise io->fd. */
static int
Io_fdclose(struct Io *io){
@ -96,6 +121,19 @@ Io_read(struct Io *io){
return io;
}
/* Writes io->bufuse units from io->buf to io->fd, permuting any unwritten
* bytes to the start of io->buf and updating io->bufuse. If io->bufuse doesn't
* change, errno will probably be set. Returns io. */
static struct Io *
Io_write(struct Io *io){
int t;
if((t = write(io->fd, io->buf, io->bufuse)) > 0)
memmove(io->buf, io->buf + t, (io->bufuse -= t));
return io;
}
/* Seeks io->seek bytes through *io's file descriptor, (counter-intuitively)
* returning -1 if successful and a sysexits.h exit code if an unrecoverable
* error occurred. */
@ -171,7 +209,7 @@ oserr(char *argv0, char *s){
struct Io *
output(struct Io io[2]){
fprintf(stderr, "%d:%d / %d:%d\n", /* dd(1p) does %d+%d\n%d+%d\n */
fprintf(stderr, "%d:%d > %d:%d\n", /* dd(1p) does %d+%d\n%d+%d\n */
io[0].rec, io[0].prec, io[1].rec, io[1].prec);;
return io;
@ -253,22 +291,32 @@ int main(int argc, char *argv[]){
if(io[0].bufuse == 0) /* that's all she wrote */
break;
else if(io[0].bufuse < io[0].bs){
io[0].prec += 1;
++io[0].prec;
if(noerror){
output(io);
}else
count = 1;
if(align >= 0){
memset(io[0].buf + io[0].bufuse, align,
io[0].bs - io[0].bufuse);
io[0].bufuse = io[0].bs;
}
}
if(align >= 0)
Io_bufrpad(&io[0], align);
}else
++io[0].rec;
/* write */ while(io[0].bufuse > 0){
memcpy(io[1].buf, io[0].buf, io[1].bs);
memmove(io[0].buf, io[0].buf + io[1].bs, io[0].bs - io[1].bs);
Io_bufxfer(&io[1], &io[0], MIN(io[0].bufuse, io[1].bs));
c = io[1].bufuse;
Io_write(&io[1]);
if(!noerror && io[1].bufuse == c)
Io_write(&io[1]); /* second chance */
if(io[1].bufuse == c) /* no more love */
count = 1;
else if(c > io[1].bufuse && io[1].bufuse > 0){
io[1].prec += 1;
if(noerror){
output(io);
}else
count = 1;
}else if(io[1].bufuse == 0)
++io[1].rec;
}
}while(count == 0 || --count > 0);