141457Sbostic /*- 241457Sbostic * Copyright (c) 1990 The Regents of the University of California. 341457Sbostic * All rights reserved. 441457Sbostic * 541457Sbostic * %sccs.include.redist.c% 641457Sbostic */ 741457Sbostic 841457Sbostic #ifndef lint 9*47154Sbostic static char sccsid[] = "@(#)odsyntax.c 5.4 (Berkeley) 03/08/91"; 1041457Sbostic #endif /* not lint */ 1141457Sbostic 1241457Sbostic #include <sys/types.h> 1345217Sbostic #include <stdlib.h> 1441457Sbostic #include <stdio.h> 1541457Sbostic #include "hexdump.h" 1641457Sbostic 1741457Sbostic int deprecated; 1841457Sbostic 1941457Sbostic oldsyntax(argc, argvp) 2041457Sbostic int argc; 2141457Sbostic char ***argvp; 2241457Sbostic { 2341457Sbostic extern enum _vflag vflag; 2441457Sbostic extern FS *fshead; 2541457Sbostic extern char *optarg; 2641457Sbostic extern int length, optind; 27*47154Sbostic int ch; 2841457Sbostic char **argv; 29*47154Sbostic static void odprecede(); 3041457Sbostic 3141457Sbostic deprecated = 1; 3241457Sbostic argv = *argvp; 3341457Sbostic while ((ch = getopt(argc, argv, "aBbcDdeFfHhIiLlOoPpswvXx")) != EOF) 3441457Sbostic switch (ch) { 3541457Sbostic case 'a': 36*47154Sbostic odprecede(); 3742362Sbostic add("16/1 \"%3_u \" \"\\n\""); 3841457Sbostic break; 3941457Sbostic case 'B': 4041457Sbostic case 'o': 41*47154Sbostic odprecede(); 4242362Sbostic add("8/2 \" %06o \" \"\\n\""); 4341457Sbostic break; 4441457Sbostic case 'b': 45*47154Sbostic odprecede(); 4642362Sbostic add("16/1 \"%03o \" \"\\n\""); 4741457Sbostic break; 4841457Sbostic case 'c': 49*47154Sbostic odprecede(); 5042362Sbostic add("16/1 \"%3_c \" \"\\n\""); 5141457Sbostic break; 5241457Sbostic case 'd': 53*47154Sbostic odprecede(); 5442362Sbostic add("8/2 \" %05u \" \"\\n\""); 5541457Sbostic break; 5641457Sbostic case 'D': 57*47154Sbostic odprecede(); 5842362Sbostic add("4/4 \" %010u \" \"\\n\""); 5941457Sbostic break; 6041457Sbostic case 'e': /* undocumented in od */ 6141457Sbostic case 'F': 62*47154Sbostic odprecede(); 6342362Sbostic add("2/8 \" %21.14e \" \"\\n\""); 6441457Sbostic break; 6541457Sbostic 6641457Sbostic case 'f': 67*47154Sbostic odprecede(); 6842362Sbostic add("4/4 \" %14.7e \" \"\\n\""); 6941457Sbostic break; 7041457Sbostic case 'H': 7141457Sbostic case 'X': 72*47154Sbostic odprecede(); 7342362Sbostic add("4/4 \" %08x \" \"\\n\""); 7441457Sbostic break; 7541457Sbostic case 'h': 7641457Sbostic case 'x': 77*47154Sbostic odprecede(); 7842362Sbostic add("8/2 \" %04x \" \"\\n\""); 7941457Sbostic break; 8041457Sbostic case 'I': 8141457Sbostic case 'L': 8241457Sbostic case 'l': 83*47154Sbostic odprecede(); 8442362Sbostic add("4/4 \" %11d \" \"\\n\""); 8541457Sbostic break; 8641457Sbostic case 'i': 87*47154Sbostic odprecede(); 8842362Sbostic add("8/2 \" %6d \" \"\\n\""); 8941457Sbostic break; 9041457Sbostic case 'O': 91*47154Sbostic odprecede(); 9242362Sbostic add("4/4 \" %011o \" \"\\n\""); 9341457Sbostic break; 9441457Sbostic case 'v': 9541457Sbostic vflag = ALL; 9641457Sbostic break; 9741457Sbostic case 'P': 9841457Sbostic case 'p': 9941457Sbostic case 's': 10041457Sbostic case 'w': 10141457Sbostic case '?': 10241457Sbostic default: 10341457Sbostic (void)fprintf(stderr, 10441457Sbostic "od: od(1) has been deprecated for hexdump(1).\n"); 10541457Sbostic if (ch != '?') 10641457Sbostic (void)fprintf(stderr, 10741457Sbostic "od: hexdump(1) compatibility doesn't support the -%c option%s\n", 10841457Sbostic ch, ch == 's' ? "; see strings(1)." : "."); 10941457Sbostic usage(); 11041457Sbostic } 11141457Sbostic 11241457Sbostic if (!fshead) { 11341457Sbostic add("\"%07.7_Ao\n\""); 11441457Sbostic add("\"%07.7_ao \" 8/2 \"%06o \" \"\\n\""); 11541457Sbostic } 11641457Sbostic 11745217Sbostic argc -= optind; 11841457Sbostic *argvp += optind; 11945217Sbostic 12045217Sbostic odoffset(argc, argvp); 12141457Sbostic } 12245217Sbostic 12345217Sbostic #define ishexdigit(c) \ 12445217Sbostic (c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F') 12545217Sbostic 12645217Sbostic odoffset(argc, argvp) 12745217Sbostic int argc; 12845217Sbostic char ***argvp; 12945217Sbostic { 13045217Sbostic extern off_t skip; 13145217Sbostic register char *num, *p; 13245217Sbostic int base; 13345217Sbostic char *end; 13445217Sbostic 13545217Sbostic /* 13645217Sbostic * The offset syntax of od(1) was genuinely bizarre. First, if 13745217Sbostic * it started with a plus it had to be an offset. Otherwise, if 13845217Sbostic * there were at least two arguments, a number or lower-case 'x' 13945217Sbostic * followed by a number makes it an offset. By default it was 14045217Sbostic * octal; if it started with 'x' or '0x' it was hex. If it ended 14145217Sbostic * in a '.', it was decimal. If a 'b' or 'B' was appended, it 14245217Sbostic * multiplied the number by 512 or 1024 byte units. There was 14345217Sbostic * no way to assign a block count to a hex offset. 14445217Sbostic * 14545217Sbostic * We assumes it's a file if the offset is bad. 14645217Sbostic */ 14745217Sbostic p = **argvp; 14845217Sbostic if (*p != '+' && (argc < 2 || 14945217Sbostic (!isdigit(p[0]) && (p[0] != 'x' || !ishexdigit(p[1]))))) 15045217Sbostic return; 15145217Sbostic 15245217Sbostic base = 0; 15345217Sbostic /* 15445217Sbostic * skip over leading '+', 'x[0-9a-fA-f]' or '0x', and 15545217Sbostic * set base. 15645217Sbostic */ 15745217Sbostic if (p[0] == '+') 15845217Sbostic ++p; 15945217Sbostic if (p[0] == 'x' && ishexdigit(p[1])) { 16045217Sbostic ++p; 16145217Sbostic base = 16; 16245217Sbostic } else if (p[0] == '0' && p[1] == 'x') { 16345217Sbostic p += 2; 16445217Sbostic base = 16; 16545217Sbostic } 16645217Sbostic 16745217Sbostic /* skip over the number */ 16845217Sbostic if (base == 16) 16945217Sbostic for (num = p; ishexdigit(*p); ++p); 17045217Sbostic else 17145217Sbostic for (num = p; isdigit(*p); ++p); 17245217Sbostic 17345217Sbostic /* check for no number */ 17445217Sbostic if (num == p) 17545217Sbostic return; 17645217Sbostic 17745217Sbostic /* if terminates with a '.', base is decimal */ 17845217Sbostic if (*p == '.') { 17945217Sbostic if (base) 18045217Sbostic return; 18145217Sbostic base = 10; 18245217Sbostic } 18345217Sbostic 18445217Sbostic skip = strtol(num, &end, base ? base : 8); 18545217Sbostic 18645217Sbostic /* if end isn't the same as p, we got a non-octal digit */ 18745217Sbostic if (end != p) 18845217Sbostic skip = 0; 18945217Sbostic else { 19045217Sbostic if (*p) { 19145217Sbostic if (*p == 'b') 19245217Sbostic skip *= 512; 19345217Sbostic else if (*p == 'B') 19445217Sbostic skip *= 1024; 19545217Sbostic ++p; 19645217Sbostic } 19745217Sbostic if (*p) 19845217Sbostic skip = 0; 19945217Sbostic else { 20045217Sbostic ++*argvp; 20145217Sbostic /* 20245217Sbostic * If the offset uses a non-octal base, the base of 20345217Sbostic * the offset is changed as well. This isn't pretty, 20445217Sbostic * but it's easy. 20545217Sbostic */ 20645217Sbostic #define TYPE_OFFSET 7 20745217Sbostic if (base == 16) { 20845217Sbostic fshead->nextfu->fmt[TYPE_OFFSET] = 'x'; 20945217Sbostic fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'x'; 21045217Sbostic } else if (base == 10) { 21145217Sbostic fshead->nextfu->fmt[TYPE_OFFSET] = 'd'; 21245217Sbostic fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'd'; 21345217Sbostic } 21445217Sbostic } 21545217Sbostic } 21645217Sbostic } 217*47154Sbostic 218*47154Sbostic static void 219*47154Sbostic odprecede() 220*47154Sbostic { 221*47154Sbostic static int first = 1; 222*47154Sbostic 223*47154Sbostic if (first) { 224*47154Sbostic first = 0; 225*47154Sbostic add("\"%07.7_Ao\n\""); 226*47154Sbostic add("\"%07.7_ao \""); 227*47154Sbostic } else 228*47154Sbostic add("\" \""); 229*47154Sbostic } 230