works imperfectly
This commit is contained in:
parent
0b3fc87718
commit
564f7a4381
1
Wip/dj/Makefile
Normal file
1
Wip/dj/Makefile
Normal file
@ -0,0 +1 @@
|
||||
dj: dj.c
|
74
Wip/dj/dj.c
74
Wip/dj/dj.c
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user