=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/hexdump/odsyntax.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- src/usr.bin/hexdump/odsyntax.c 2001/11/19 19:02:14 1.8 +++ src/usr.bin/hexdump/odsyntax.c 2001/12/30 08:17:32 1.9 @@ -1,8 +1,9 @@ -/* $OpenBSD: odsyntax.c,v 1.8 2001/11/19 19:02:14 mpech Exp $ */ +/* $OpenBSD: odsyntax.c,v 1.9 2001/12/30 08:17:32 pvalchev Exp $ */ +/* $NetBSD: odsyntax.c,v 1.15 2001/12/07 15:14:29 bjh21 Exp $ */ /*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,34 +36,65 @@ #ifndef lint /*static char sccsid[] = "from: @(#)odsyntax.c 5.4 (Berkeley) 3/8/91";*/ -static char rcsid[] = "$OpenBSD: odsyntax.c,v 1.8 2001/11/19 19:02:14 mpech Exp $"; +static char rcsid[] = "$OpenBSD: odsyntax.c,v 1.9 2001/12/30 08:17:32 pvalchev Exp $"; #endif /* not lint */ #include -#include -#include + #include #include +#include +#include +#include + #include "hexdump.h" int deprecated; +static void odoffset __P((int, char ***)); +static void posixtypes __P((char *)); +static void odprecede __P((void)); + + +/* + * formats used for -t + */ +static const char *fmt[4][4] = { + { + "16/1 \"%3d \" \"\\n\"", + "8/2 \" %05d \" \"\\n\"", + "4/4 \" %010d \" \"\\n\"", + "2/8 \" %019d \" \"\\n\"" + }, { + "16/1 \"%03o \" \"\\n\"", + "8/2 \" %06o \" \"\\n\"", + "4/4 \" %011o\" \"\\n\"", + "2/8 \" %022o \" \"\\n\"" + }, { + "16/1 \"%03u \" \"\\n\"", + "8/2 \" %05u \" \"\\n\"", + "4/4 \" %010u \" \"\\n\"", + "2/8 \" %020u \" \"\\n\"" + }, { + "16/1 \" %02x \" \"\\n\"", + "8/2 \" %04x \" \"\\n\"", + "4/4 \" %08x \" \"\\n\"", + "2/8 \" %16x \" \"\\n\"" + } +}; + void oldsyntax(argc, argvp) int argc; char ***argvp; { - extern enum _vflag vflag; - extern FS *fshead; - extern char *optarg; - extern int optind; int ch; - char **argv; - static void odprecede(); + char *p, **argv; deprecated = 1; argv = *argvp; - while ((ch = getopt(argc, argv, "aBbcDdeFfHhIiLlOoPpswvXx")) != -1) + while ((ch = getopt(argc, argv, + "aBbcDdeFfHhIij:LlN:OoPpst:wvXx")) != -1) switch (ch) { case 'a': odprecede(); @@ -119,10 +151,32 @@ odprecede(); add("8/2 \" %6d \" \"\\n\""); break; + case 'j': + if ((skip = strtol(optarg, &p, 0)) < 0) + errx(1, "%s: bad skip value", optarg); + switch(*p) { + case 'b': + skip *= 512; + break; + case 'k': + skip *= 1024; + break; + case 'm': + skip *= 1048576; + break; + } + break; + case 'N': + if ((length = atoi(optarg)) < 0) + errx(1, "%s: bad length value", optarg); + break; case 'O': odprecede(); add("4/4 \" %011o \" \"\\n\""); break; + case 't': + posixtypes(optarg); + break; case 'v': vflag = ALL; break; @@ -132,10 +186,10 @@ case 'w': case '?': default: - warnx("od(1) has been deprecated for hexdump(1)"); + warnx("od(1) has been deprecated for hexdump(1)."); if (ch != '?') - warnx("hexdump(1) compatibility doesn't" - "support the -%c option%s", + warnx( +"hexdump(1) compatibility doesn't support the -%c option%s\n", ch, ch == 's' ? "; see strings(1)." : "."); usage(); } @@ -148,18 +202,114 @@ argc -= optind; *argvp += optind; - odoffset(argc, argvp); + if (argc) + odoffset(argc, argvp); } -#define ishexdigit(c) \ - (c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F') +/* + * Interpret a POSIX-style -t argument. + */ +static void +posixtypes(type_string) + char *type_string; +{ + int x, y, nbytes; -void + while (*type_string) { + odprecede(); + switch (*type_string) { + case 'a': + type_string++; + add("16/1 \"%3_u \" \"\\n\""); + break; + case 'c': + type_string++; + add("16/1 \"%3_c \" \"\\n\""); + break; + case 'f': + type_string++; + if (*type_string == 'F' || + *type_string == '4') { + type_string++; + add("4/4 \" %14.7e\" \"\\n\""); + } else if (*type_string == 'L' || + *type_string == '8') { + type_string++; + add("2/8 \" %16.14e\" \"\\n\""); + } else if (*type_string == 'D') + /* long doubles vary in size */ + usage(); + else + add("2/8 \" %16.14e\" \"\\n\""); + break; + case 'd': + x = 0; + goto extensions; + case 'o': + x = 1; + goto extensions; + case 'u': + x = 2; + goto extensions; + case 'x': + x = 3; + extensions: + type_string++; + y = 2; + if (isupper(*type_string)) { + switch(*type_string) { + case 'C': + nbytes = sizeof(char); + break; + case 'S': + nbytes = sizeof(short); + break; + case 'I': + nbytes = sizeof(int); + break; + case 'L': + nbytes = sizeof(long); + break; + default: + warnx("Bad type-size qualifier '%c'", + *type_string); + usage(); + } + type_string++; + } else if (isdigit(*type_string)) + nbytes = strtol(type_string, &type_string, 10); + + switch (nbytes) { + case 1: + y = 0; + break; + case 2: + y = 1; + break; + case 4: + y = 2; + break; + case 8: + y = 3; + break; + default: + warnx("%d-byte integer formats are not " + "supported", nbytes); + usage(); + } + add(fmt[x][y]); + break; + default: + usage(); + } + } +} + +static void odoffset(argc, argvp) int argc; char ***argvp; { - extern off_t skip; char *num, *p; int base; char *end; @@ -174,13 +324,15 @@ * multiplied the number by 512 or 1024 byte units. There was * no way to assign a block count to a hex offset. * - * We assumes it's a file if the offset is bad. + * We assume it's a file if the offset is bad. */ - p = **argvp; + p = argc == 1 ? (*argvp)[0] : (*argvp)[1]; if (!p) return; + if (*p != '+' && (argc < 2 || - (!isdigit(p[0]) && (p[0] != 'x' || !ishexdigit(p[1]))))) + (!isdigit((unsigned char)p[0]) && + (p[0] != 'x' || !isxdigit((unsigned char)p[1]))))) return; base = 0; @@ -190,7 +342,7 @@ */ if (p[0] == '+') ++p; - if (p[0] == 'x' && ishexdigit(p[1])) { + if (p[0] == 'x' && isxdigit((unsigned char)p[1])) { ++p; base = 16; } else if (p[0] == '0' && p[1] == 'x') { @@ -200,9 +352,9 @@ /* skip over the number */ if (base == 16) - for (num = p; ishexdigit(*p); ++p); + for (num = p; isxdigit((unsigned char)*p); ++p); else - for (num = p; isdigit(*p); ++p); + for (num = p; isdigit((unsigned char)*p); ++p); /* check for no number */ if (num == p) @@ -218,35 +370,39 @@ skip = strtol(num, &end, base ? base : 8); /* if end isn't the same as p, we got a non-octal digit */ - if (end != p) + if (end != p) { skip = 0; - else { - if (*p) { - if (*p == 'b') - skip *= 512; - else if (*p == 'B') - skip *= 1024; + return; + } + + if (*p) { + if (*p == 'B') { + skip *= 1024; ++p; + } else if (*p == 'b') { + skip *= 512; + ++p; } - if (*p) - skip = 0; - else { - ++*argvp; - /* - * If the offset uses a non-octal base, the base of - * the offset is changed as well. This isn't pretty, - * but it's easy. - */ + } + if (*p) { + skip = 0; + return; + } + /* + * If the offset uses a non-octal base, the base of the offset + * is changed as well. This isn't pretty, but it's easy. + */ #define TYPE_OFFSET 7 - if (base == 16) { - fshead->nextfu->fmt[TYPE_OFFSET] = 'x'; - fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'x'; - } else if (base == 10) { - fshead->nextfu->fmt[TYPE_OFFSET] = 'd'; - fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'd'; - } - } + if (base == 16) { + fshead->nextfu->fmt[TYPE_OFFSET] = 'x'; + fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'x'; + } else if (base == 10) { + fshead->nextfu->fmt[TYPE_OFFSET] = 'd'; + fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'd'; } + + /* Terminate file list. */ + (*argvp)[1] = NULL; } static void