File indexing completed on 2025-05-11 08:24:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #ifdef __rtems__
0035
0036 #define _GNU_SOURCE
0037 #endif
0038 #ifdef HAVE_CONFIG_H
0039 #include "config.h"
0040 #endif
0041
0042 #ifndef lint
0043 #if 0
0044 static char sccsid[] = "@(#)odsyntax.c 8.2 (Berkeley) 5/4/95";
0045 #endif
0046 #include <sys/cdefs.h>
0047 __FBSDID("$FreeBSD: src/usr.bin/hexdump/odsyntax.c,v 1.17 2004/07/22 13:14:42 johan Exp $");
0048 #endif
0049
0050 #include <sys/types.h>
0051
0052 #include <ctype.h>
0053 #include "err.h"
0054 #include <errno.h>
0055 #include <float.h>
0056 #include <stdio.h>
0057 #include <stdlib.h>
0058 #include <string.h>
0059 #include <unistd.h>
0060
0061 #include "hexdump.h"
0062
0063 #define __need_getopt_newlib
0064 #include <getopt.h>
0065
0066 #define PADDING " "
0067
0068 #ifndef __unused
0069 #define __unused RTEMS_UNUSED
0070 #endif
0071
0072 #if RTEMS_REMOVED
0073 int odmode;
0074 #endif
0075
0076 static void odadd(rtems_shell_hexdump_globals*, const char *);
0077 static void odformat(rtems_shell_hexdump_globals*, const char *);
0078 static const char *odformatfp(rtems_shell_hexdump_globals*, char, const char *);
0079 static const char *odformatint(rtems_shell_hexdump_globals*, char, const char *);
0080 static void odoffset(rtems_shell_hexdump_globals*, int, char ***);
0081 static void odusage(rtems_shell_hexdump_globals*);
0082
0083 void
0084 oldsyntax(rtems_shell_hexdump_globals* globals, int argc, char ***argvp)
0085 {
0086 static char empty[] = "", padding[] = PADDING;
0087 int ch;
0088 char **argv, *end;
0089
0090 struct getopt_data getopt_reent;
0091 memset(&getopt_reent, 0, sizeof(getopt_data));
0092
0093
0094 #define TYPE_OFFSET 7
0095 add(globals, "\"%07.7_Ao\n\"");
0096 add(globals, "\"%07.7_ao \"");
0097
0098 odmode = 1;
0099 argv = *argvp;
0100 while ((ch = getopt_r(argc, argv, "A:aBbcDdeFfHhIij:LlN:Oost:vXx", &getopt_reent)) != -1)
0101 switch (ch) {
0102 case 'A':
0103 switch (*optarg) {
0104 case 'd': case 'o': case 'x':
0105 fshead->nextfu->fmt[TYPE_OFFSET] = *optarg;
0106 fshead->nextfs->nextfu->fmt[TYPE_OFFSET] =
0107 *optarg;
0108 break;
0109 case 'n':
0110 fshead->nextfu->fmt = empty;
0111 fshead->nextfs->nextfu->fmt = padding;
0112 break;
0113 default:
0114 errx(exit_jump, 1, "%s: invalid address base", optarg);
0115 }
0116 break;
0117 case 'a':
0118 odformat(globals, "a");
0119 break;
0120 case 'B':
0121 case 'o':
0122 odformat(globals, "o2");
0123 break;
0124 case 'b':
0125 odformat(globals, "o1");
0126 break;
0127 case 'c':
0128 odformat(globals, "c");
0129 break;
0130 case 'd':
0131 odformat(globals, "u2");
0132 break;
0133 case 'D':
0134 odformat(globals, "u4");
0135 break;
0136 case 'e':
0137 case 'F':
0138 odformat(globals, "fD");
0139 break;
0140 case 'f':
0141 odformat(globals, "fF");
0142 break;
0143 case 'H':
0144 case 'X':
0145 odformat(globals, "x4");
0146 break;
0147 case 'h':
0148 case 'x':
0149 odformat(globals, "x2");
0150 break;
0151 case 'I':
0152 case 'L':
0153 case 'l':
0154 odformat(globals, "dL");
0155 break;
0156 case 'i':
0157 odformat(globals, "dI");
0158 break;
0159 case 'j':
0160 errno = 0;
0161 skip = strtoll(optarg, &end, 0);
0162 if (*end == 'b')
0163 skip *= 512;
0164 else if (*end == 'k')
0165 skip *= 1024;
0166 else if (*end == 'm')
0167 skip *= 1048576L;
0168 if (errno != 0 || skip < 0 || strlen(end) > 1)
0169 errx(exit_jump, 1, "%s: invalid skip amount", optarg);
0170 break;
0171 case 'N':
0172 if ((length = atoi(optarg)) <= 0)
0173 errx(exit_jump, 1, "%s: invalid length", optarg);
0174 break;
0175 case 'O':
0176 odformat(globals, "o4");
0177 break;
0178 case 's':
0179 odformat(globals, "d2");
0180 break;
0181 case 't':
0182 odformat(globals, optarg);
0183 break;
0184 case 'v':
0185 vflag = ALL;
0186 break;
0187 case '?':
0188 default:
0189 odusage(globals);
0190 }
0191
0192 if (fshead->nextfs->nextfs == NULL)
0193 odformat(globals, "oS");
0194
0195 argc -= getopt_reent.optind;
0196 *argvp += getopt_reent.optind;
0197
0198 if (argc)
0199 odoffset(globals, argc, argvp);
0200 }
0201
0202 static void
0203 odusage(rtems_shell_hexdump_globals* globals)
0204 {
0205
0206 fprintf(stderr,
0207 "usage: od [-aBbcDdeFfHhIiLlOosvXx] [-A base] [-j skip] [-N length] [-t type]\n");
0208 fprintf(stderr,
0209 " [[+]offset[.][Bb]] [file ...]\n");
0210 exit(1);
0211 }
0212
0213 static void
0214 odoffset(rtems_shell_hexdump_globals* globals, int argc, char ***argvp)
0215 {
0216 char *p, *num, *end;
0217 int base;
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231 p = argc == 1 ? (*argvp)[0] : (*argvp)[1];
0232
0233 if (*p != '+' && (argc < 2 ||
0234 (!isdigit((unsigned char)p[0]) && (p[0] != 'x' || !isxdigit((unsigned char)p[1])))))
0235 return;
0236
0237 base = 0;
0238
0239
0240
0241
0242 if (p[0] == '+')
0243 ++p;
0244 if (p[0] == 'x' && isxdigit((unsigned char)p[1])) {
0245 ++p;
0246 base = 16;
0247 } else if (p[0] == '0' && p[1] == 'x') {
0248 p += 2;
0249 base = 16;
0250 }
0251
0252
0253 if (base == 16)
0254 for (num = p; isxdigit((unsigned char)*p); ++p);
0255 else
0256 for (num = p; isdigit((unsigned char)*p); ++p);
0257
0258
0259 if (num == p)
0260 return;
0261
0262
0263 if (*p == '.') {
0264 if (base)
0265 return;
0266 base = 10;
0267 }
0268
0269 skip = strtoll(num, &end, base ? base : 8);
0270
0271
0272 if (end != p) {
0273 skip = 0;
0274 return;
0275 }
0276
0277 if (*p) {
0278 if (*p == 'B') {
0279 skip *= 1024;
0280 ++p;
0281 } else if (*p == 'b') {
0282 skip *= 512;
0283 ++p;
0284 }
0285 }
0286
0287 if (*p) {
0288 skip = 0;
0289 return;
0290 }
0291
0292
0293
0294
0295
0296 if (base == 16) {
0297 fshead->nextfu->fmt[TYPE_OFFSET] = 'x';
0298 fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'x';
0299 } else if (base == 10) {
0300 fshead->nextfu->fmt[TYPE_OFFSET] = 'd';
0301 fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'd';
0302 }
0303
0304
0305 (*argvp)[1] = NULL;
0306 }
0307
0308 static void
0309 odformat(rtems_shell_hexdump_globals* globals, const char *fmt)
0310 {
0311 char fchar;
0312
0313 while (*fmt != '\0') {
0314 switch ((fchar = *fmt++)) {
0315 case 'a':
0316 odadd(globals, "16/1 \"%3_u \" \"\\n\"");
0317 break;
0318 case 'c':
0319 odadd(globals, "16/1 \"%3_c \" \"\\n\"");
0320 break;
0321 case 'o': case 'u': case 'd': case 'x':
0322 fmt = odformatint(globals, fchar, fmt);
0323 break;
0324 case 'f':
0325 fmt = odformatfp(globals, fchar, fmt);
0326 break;
0327 default:
0328 errx(exit_jump, 1, "%c: unrecognised format character", fchar);
0329 }
0330 }
0331 }
0332
0333 static const char *
0334 odformatfp(rtems_shell_hexdump_globals* globals, char fchar __unused, const char *fmt)
0335 {
0336 size_t isize;
0337 int digits;
0338 char *end, *hdfmt;
0339
0340 isize = sizeof(double);
0341 switch (*fmt) {
0342 case 'F':
0343 isize = sizeof(float);
0344 fmt++;
0345 break;
0346 case 'D':
0347 isize = sizeof(double);
0348 fmt++;
0349 break;
0350 case 'L':
0351 isize = sizeof(long double);
0352 fmt++;
0353 break;
0354 default:
0355 if (isdigit((unsigned char)*fmt)) {
0356 errno = 0;
0357 isize = (size_t)strtoul(fmt, &end, 10);
0358 if (errno != 0 || isize == 0)
0359 errx(exit_jump, 1, "%s: invalid size", fmt);
0360 fmt = (const char *)end;
0361 }
0362 }
0363 if (isize == sizeof(float) ) {
0364 digits = FLT_DIG;
0365 } else if (isize == sizeof(double)) {
0366 digits = DBL_DIG;
0367 } else if (isize == sizeof(long double)) {
0368 digits = LDBL_DIG;
0369 } else {
0370 errx(exit_jump, 1, "unsupported floating point size %zu",
0371 isize);
0372 }
0373
0374 asprintf(&hdfmt, "%lu/%lu \" %%%d.%de \" \"\\n\"",
0375 16UL / (u_long)isize, (u_long)isize, digits + 8, digits);
0376 if (hdfmt == NULL)
0377 err(exit_jump, 1, NULL);
0378 odadd(globals, hdfmt);
0379 free(hdfmt);
0380
0381 return (fmt);
0382 }
0383
0384 static const char *
0385 odformatint(rtems_shell_hexdump_globals* globals, char fchar, const char *fmt)
0386 {
0387 unsigned long long n;
0388 size_t isize;
0389 int digits;
0390 char *end, *hdfmt;
0391
0392 isize = sizeof(int);
0393 switch (*fmt) {
0394 case 'C':
0395 isize = sizeof(char);
0396 fmt++;
0397 break;
0398 case 'I':
0399 isize = sizeof(int);
0400 fmt++;
0401 break;
0402 case 'L':
0403 isize = sizeof(long);
0404 fmt++;
0405 break;
0406 case 'S':
0407 isize = sizeof(short);
0408 fmt++;
0409 break;
0410 default:
0411 if (isdigit((unsigned char)*fmt)) {
0412 errno = 0;
0413 isize = (size_t)strtoul(fmt, &end, 10);
0414 if (errno != 0 || isize == 0)
0415 errx(exit_jump, 1, "%s: invalid size", fmt);
0416 if (isize != sizeof(char) && isize != sizeof(short) &&
0417 isize != sizeof(int) && isize != sizeof(long))
0418 errx(exit_jump, 1, "unsupported int size %lu",
0419 (u_long)isize);
0420 fmt = (const char *)end;
0421 }
0422 }
0423
0424
0425
0426
0427
0428
0429
0430 n = (1ULL << (8 * isize)) - 1;
0431 digits = 0;
0432 while (n != 0) {
0433 digits++;
0434 n >>= (fchar == 'x') ? 4 : 3;
0435 }
0436 if (fchar == 'd')
0437 digits++;
0438 asprintf(&hdfmt, "%lu/%lu \"%*s%%%s%d%c\" \"\\n\"",
0439 16UL / (u_long)isize, (u_long)isize, (int)(4 * isize - digits),
0440 "", (fchar == 'd' || fchar == 'u') ? "" : "0", digits, fchar);
0441 if (hdfmt == NULL)
0442 err(exit_jump, 1, NULL);
0443 odadd(globals, hdfmt);
0444 free(hdfmt);
0445
0446 return (fmt);
0447 }
0448
0449 static void
0450 odadd(rtems_shell_hexdump_globals* globals, const char *fmt)
0451 {
0452 static int needpad;
0453
0454 if (needpad)
0455 add(globals, "\""PADDING"\"");
0456 add(globals, fmt);
0457 needpad = 1;
0458 }