debug mode, new option parsing, also i broke it
This commit is contained in:
parent
3bc4e01b35
commit
71612d7308
89
dj/dj.c
89
dj/dj.c
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user