1
0
Fork 0

debug mode, new option parsing, also i broke it

This commit is contained in:
dtb 2024-01-07 10:39:39 -07:00
parent 3bc4e01b35
commit 71612d7308
1 changed files with 53 additions and 36 deletions

89
dj/dj.c
View File

@ -1,3 +1,4 @@
#include <ctype.h> /* isupper(3), tolower(3) */
#include <errno.h> /* errno */
#include <fcntl.h> /* open(2) */
#include <stdio.h> /* fprintf(3), stderr */
@ -149,26 +150,32 @@ Io_read(struct Io *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. */
* error occurred. io->buf will be cleared of useful bytes and io->seek will
* be set to zero to indicate the seek occurred. */
static int
Io_seek(struct Io *io){
ssize_t (*op)(int, void *, size_t);
Io_fdseek(struct Io *io){
int (*op)(int, void *, size_t);
if(!fdisstd(io->fd) && lseek(io->fd, io->seek, SEEK_SET) != -1)
return -1;
else if(io->fl == write_flags){
/* cheat and use bufuse as the retval for write */
memset(io->buf, '\0', io->bs);
/* This is a dirty trick; rather than testing conditions and operating
* likewise, because the parameters to read or write are going to be
* the same either way, just use a function pointer to keep track of
* the intended operation. */
op = &write; /* Ignore -Wincompatible-pointer-types, it's fine. */
/* The difference is between const void * and void * which isn't
* significant enough to affect program behavior. */
op = (int (*)(int, void *, size_t))&write;
/* Function pointer casts are risky; this works because the difference
* is in the second parameter and only that write(2) makes the buffer
* const whereas read(2) does not. To avoid even the slightest
* undefined behavior comment out the cast, just be ready for a
* -Wincompatible-function-pointer-types if your compiler notices it.
*/
}else
op = &read;
/* We're going to cheat and use bufuse as the retval for write(2), which is
* fine because it'll be zeroed as this function returns anyway. */
do{ if( (io->bufuse = (*op)(io->fd, io->buf, MIN(io->bs, io->seek))) == 0)
/* second chance */
io->bufuse = (*op)(io->fd, io->buf, MIN(io->bs, io->seek));
@ -250,7 +257,7 @@ parse(char *s){
static int
usage(char *argv0){
fprintf(stderr, "Usage: %s (-dfAH) (-a [byte]) (-c [count])\n"
fprintf(stderr, "Usage: %s (-AdfHqQ) (-a [byte]) (-c [count])\n"
"\t(-i [input file]) (-b [input block size]) (-s [input offset])\n"
"\t(-o [output file]) (-B [output block size]) (-S [output offset])\n",
ARGV0(argv0));
@ -259,7 +266,7 @@ usage(char *argv0){
}
int main(int argc, char *argv[]){
char align;
int align;
char debug;
char noerror;
int c;
@ -279,36 +286,46 @@ int main(int argc, char *argv[]){
Io_setdefaults(&io[1]);
if(argc > 0)
while((c = getopt(argc, argv, "a:Ab:B:c:i:fHqQs:S:o:")) != -1)
if(c == 'i' || c == 'o'){
if(Io_fdopen(&io[c == 'o'], optarg) == -1){
terminate(io);
return oserr(argv[0], optarg);
while((c = getopt(argc, argv, "a:Ab:B:c:di:fhHqQs:S:o:")) != -1)
switch(c){
case 'i': case 'o':
if(Io_fdopen(&io[c == 'o'], optarg) != -1)
break;
terminate(io);
return oserr(argv[0], optarg);
case 'A': align = '\0'; break;
case 'd': debug = 3; break;
case 'f': noerror = 1; break;
case 'H': fmt_output = fmt_human; break;
case 'q': /* be quiet / BE QUIET */
case 'Q': debug -= 1 + (c == 'Q'); break;
case 'a':
if(optarg[0] != '\0' && optarg[1] == '\0'){
align = optarg[0];
break;
}
/* boolean/flag arguments */
}else if(c == 'A')
align = '\0';
else if(c == 'f')
noerror = 1;
else if(c == 'H')
fmt_output = fmt_human;
else if(c == 'q')
debug = 1;
else if(c == 'Q')
debug = 0;
/* optarg */
else if(c == 'a' && optarg[0] != '\0' && optarg[1] == '\0')
align = optarg[0];
/* numeric args */
else if(!((c == 'c' && (count = parse(optarg)) >= 0)
|| (c == 'b' && (io[0].bs = parse(optarg)) >= 0)
|| (c == 's' && (io[0].seek = parse(optarg)) >= 0)
|| (c == 'B' && (io[1].bs = parse(optarg)) >= 0)
|| (c == 'S' && (io[1].seek = parse(optarg)) >= 0))){
case 'c': case 'b': case 's': case 'B': case 'S':
if(c == 'c' && (count = parse(optarg)) >= 0)
break;
p = isupper(c);
c = tolower(c);
if((c == 'b' && (io[p].bs = parse(optarg)) > 0)
|| (c == 's' && (io[p].seek = parse(optarg)) >= 0))
break;
default:
terminate(io);
return usage(argv[0]);
}
if(debug >= 3)
fprintf(stderr,
"argv0=%s\n"
"in=%s\tibs=%d\tskip=%ld\talign=%hhx\tcount=%d\n"
"out=%s\tobs=%d\tseek=%ld\tdebug=%2d\tnoerror=%d\n",
ARGV0(argv[0]),
io[0].fn, io[0].bs, io[0].seek, align, count,
io[1].fn, io[1].bs, io[1].seek, debug, noerror);
if(argc > optind){
terminate(io);
return usage(argv[0]);
@ -320,8 +337,8 @@ int main(int argc, char *argv[]){
ARGV0(argv[0]), io[p].bs);
terminate(io);
return EX_OSERR;
}else if(io[p].seek > 0) /* seek */
switch(Io_seek(&io[p])){
}else if(io[p].seek > 0)
switch(Io_fdseek(&io[p])){
case EX_OK:
if(debug >= 1)
output(io);