hexl.c 5.19 KB
Newer Older
1
/* Convert files for Emacs Hexl mode.
2
   Copyright (C) 1989, 2001-2014 Free Software Foundation, Inc.
3 4 5

Author: Keith Gabryelski
(according to authors.el)
6 7 8

This file is not considered part of GNU Emacs.

9
This program is free software: you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11 12
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
13 14 15 16 17 18 19

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
20 21
along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

22

23 24
#include <config.h>

Jim Blandy's avatar
Jim Blandy committed
25 26
#include <stdio.h>
#include <ctype.h>
27
#ifdef DOS_NT
28
#include <fcntl.h>
29 30 31
#if __DJGPP__ >= 2
#include <io.h>
#endif
32
#endif
33 34 35
#ifdef WINDOWSNT
#include <io.h>
#endif
Jim Blandy's avatar
Jim Blandy committed
36 37 38 39

#define DEFAULT_GROUPING	0x01
#define DEFAULT_BASE		16

40 41
int base = DEFAULT_BASE;
bool un_flag = false, iso_flag = false, endian = true;
Jim Blandy's avatar
Jim Blandy committed
42 43 44
int group_by = DEFAULT_GROUPING;
char *progname;

45
_Noreturn void usage (void);
46 47

int
48
main (int argc, char **argv)
Jim Blandy's avatar
Jim Blandy committed
49
{
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
  register long address;
  char string[18];
  FILE *fp;

  progname = *argv++; --argc;

  /*
   ** -hex		hex dump
   ** -oct		Octal dump
   ** -group-by-8-bits
   ** -group-by-16-bits
   ** -group-by-32-bits
   ** -group-by-64-bits
   ** -iso		iso character set.
   ** -big-endian	Big Endian
   ** -little-endian	Little Endian
   ** -un || -de	from hexl format to binary.
   ** --		End switch list.
   ** <filename>	dump filename
   ** -		(as filename == stdin)
   */
Pavel Janík's avatar
Pavel Janík committed
71

72
  while (*argv && *argv[0] == '-' && (*argv)[1])
Jim Blandy's avatar
Jim Blandy committed
73
    {
74 75
      /* A switch! */
      if (!strcmp (*argv, "--"))
Jim Blandy's avatar
Jim Blandy committed
76
	{
77 78 79 80
	  --argc; argv++;
	  break;
	}
      else if (!strcmp (*argv, "-un") || !strcmp (*argv, "-de"))
Jim Blandy's avatar
Jim Blandy committed
81
	{
82
	  un_flag = true;
83 84 85
	  --argc; argv++;
	}
      else if (!strcmp (*argv, "-hex"))
Jim Blandy's avatar
Jim Blandy committed
86
	{
87 88 89 90
	  base = 16;
	  --argc; argv++;
	}
      else if (!strcmp (*argv, "-iso"))
Jim Blandy's avatar
Jim Blandy committed
91
	{
92
	  iso_flag = true;
93 94 95
	  --argc; argv++;
	}
      else if (!strcmp (*argv, "-oct"))
Jim Blandy's avatar
Jim Blandy committed
96
	{
97 98 99 100
	  base = 8;
	  --argc; argv++;
	}
      else if (!strcmp (*argv, "-big-endian"))
Jim Blandy's avatar
Jim Blandy committed
101
	{
102
	  endian = true;
103 104 105
	  --argc; argv++;
	}
      else if (!strcmp (*argv, "-little-endian"))
Jim Blandy's avatar
Jim Blandy committed
106
	{
107
	  endian = false;
108 109 110
	  --argc; argv++;
	}
      else if (!strcmp (*argv, "-group-by-8-bits"))
Jim Blandy's avatar
Jim Blandy committed
111
	{
112 113 114 115
	  group_by = 0x00;
	  --argc; argv++;
	}
      else if (!strcmp (*argv, "-group-by-16-bits"))
Jim Blandy's avatar
Jim Blandy committed
116
	{
117 118 119 120
	  group_by = 0x01;
	  --argc; argv++;
	}
      else if (!strcmp (*argv, "-group-by-32-bits"))
Jim Blandy's avatar
Jim Blandy committed
121
	{
122 123 124 125
	  group_by = 0x03;
	  --argc; argv++;
	}
      else if (!strcmp (*argv, "-group-by-64-bits"))
Jim Blandy's avatar
Jim Blandy committed
126
	{
127
	  group_by = 0x07;
128
	  endian = false;
129 130 131
	  --argc; argv++;
	}
      else
Jim Blandy's avatar
Jim Blandy committed
132
	{
133 134 135
	  fprintf (stderr, "%s: invalid switch: \"%s\".\n", progname,
		   *argv);
	  usage ();
Jim Blandy's avatar
Jim Blandy committed
136 137 138
	}
    }

139
  do
Jim Blandy's avatar
Jim Blandy committed
140
    {
141 142 143
      if (*argv == NULL)
	fp = stdin;
      else
Jim Blandy's avatar
Jim Blandy committed
144
	{
145
	  char *filename = *argv++;
Jim Blandy's avatar
Jim Blandy committed
146

147 148 149 150 151 152 153
	  if (!strcmp (filename, "-"))
	    fp = stdin;
	  else if ((fp = fopen (filename, "r")) == NULL)
	    {
	      perror (filename);
	      continue;
	    }
Jim Blandy's avatar
Jim Blandy committed
154 155
	}

156
      if (un_flag)
Jim Blandy's avatar
Jim Blandy committed
157
	{
158
	  char buf[18];
Jim Blandy's avatar
Jim Blandy committed
159

160 161
#ifdef DOS_NT
#if (__DJGPP__ >= 2) || (defined WINDOWSNT)
162 163
          if (!isatty (fileno (stdout)))
	    setmode (fileno (stdout), O_BINARY);
164
#else
165 166
	  (stdout)->_flag &= ~_IOTEXT; /* print binary */
	  _setmode (fileno (stdout), O_BINARY);
167
#endif
168 169
#endif
	  for (;;)
Jim Blandy's avatar
Jim Blandy committed
170
	    {
171
	      register int i, c = 0, d;
Jim Blandy's avatar
Jim Blandy committed
172

173
#define hexchar(x) (isdigit (x) ? x - '0' : x - 'a' + 10)
Jim Blandy's avatar
Jim Blandy committed
174

175 176 177
	      /* Skip 10 bytes.  */
	      if (fread (buf, 1, 10, fp) != 10)
		break;
Jim Blandy's avatar
Jim Blandy committed
178

179
	      for (i=0; i < 16; ++i)
Jim Blandy's avatar
Jim Blandy committed
180
		{
181 182
		  if ((c = getc (fp)) == ' ' || c == EOF)
		    break;
Jim Blandy's avatar
Jim Blandy committed
183

184 185 186
		  d = getc (fp);
		  c = hexchar (c) * 0x10 + hexchar (d);
		  putchar (c);
Jim Blandy's avatar
Jim Blandy committed
187

188 189
		  if ((i&group_by) == group_by)
		    getc (fp);
Jim Blandy's avatar
Jim Blandy committed
190 191
		}

192
	      if (c == ' ')
Jim Blandy's avatar
Jim Blandy committed
193
		{
194 195
		  while ((c = getc (fp)) != '\n' && c != EOF)
		    ;
Jim Blandy's avatar
Jim Blandy committed
196

197 198
		  if (c == EOF)
		    break;
Jim Blandy's avatar
Jim Blandy committed
199
		}
200
	      else
Jim Blandy's avatar
Jim Blandy committed
201
		{
202 203
		  if (i < 16)
		    break;
Jim Blandy's avatar
Jim Blandy committed
204

205 206 207
		  /* Skip 18 bytes.  */
		  if (fread (buf, 1, 18, fp) != 18)
		    break;
Jim Blandy's avatar
Jim Blandy committed
208 209 210
		}
	    }
	}
211
      else
Jim Blandy's avatar
Jim Blandy committed
212
	{
213 214
#ifdef DOS_NT
#if (__DJGPP__ >= 2) || (defined WINDOWSNT)
215 216
          if (!isatty (fileno (fp)))
	    setmode (fileno (fp), O_BINARY);
217
#else
218 219
	  (fp)->_flag &= ~_IOTEXT; /* read binary */
	  _setmode (fileno (fp), O_BINARY);
220
#endif
221 222 223 224 225
#endif
	  address = 0;
	  string[0] = ' ';
	  string[17] = '\0';
	  for (;;)
Jim Blandy's avatar
Jim Blandy committed
226
	    {
227
	      register int i, c = 0;
Jim Blandy's avatar
Jim Blandy committed
228

229
	      for (i=0; i < 16; ++i)
Jim Blandy's avatar
Jim Blandy committed
230
		{
231
		  if ((c = getc (fp)) == EOF)
Jim Blandy's avatar
Jim Blandy committed
232
		    {
233 234
		      if (!i)
			break;
Jim Blandy's avatar
Jim Blandy committed
235

236 237
		      fputs ("  ", stdout);
		      string[i+1] = '\0';
Jim Blandy's avatar
Jim Blandy committed
238
		    }
239
		  else
Jim Blandy's avatar
Jim Blandy committed
240
		    {
241
		      if (!i)
242
			printf ("%08lx: ", address);
Jim Blandy's avatar
Jim Blandy committed
243

244 245 246 247 248
		      if (iso_flag)
			string[i+1] =
			  (c < 0x20 || (c >= 0x7F && c < 0xa0)) ? '.' :c;
		      else
			string[i+1] = (c < 0x20 || c >= 0x7F) ? '.' : c;
Jim Blandy's avatar
Jim Blandy committed
249

250
		      printf ("%02x", c);
Jim Blandy's avatar
Jim Blandy committed
251 252
		    }

253 254
		  if ((i&group_by) == group_by)
		    putchar (' ');
Jim Blandy's avatar
Jim Blandy committed
255 256
		}

257 258
	      if (i)
		puts (string);
Jim Blandy's avatar
Jim Blandy committed
259

260 261
	      if (c == EOF)
		break;
Jim Blandy's avatar
Jim Blandy committed
262

263
	      address += 0x10;
Jim Blandy's avatar
Jim Blandy committed
264 265 266 267

	    }
	}

268 269
      if (fp != stdin)
	fclose (fp);
Jim Blandy's avatar
Jim Blandy committed
270 271

    } while (*argv != NULL);
272
  return EXIT_SUCCESS;
Jim Blandy's avatar
Jim Blandy committed
273 274
}

275
void
276
usage (void)
Jim Blandy's avatar
Jim Blandy committed
277
{
278
  fprintf (stderr, "usage: %s [-de] [-iso]\n", progname);
279
  exit (EXIT_FAILURE);
Jim Blandy's avatar
Jim Blandy committed
280
}
Miles Bader's avatar
Miles Bader committed
281

282 283

/* hexl.c ends here */