view lib-src/hexl.c @ 22917:00f3497854c4

(quail-translation-keymap): Declare it as variable instead of constant. Bind all keys less than 32 to quail-other-command. Don't bind the key meta-prefix-char and escape. (quail-simple-translation-keymap): Likewise. (quail-conversion-keymap): Bind the key C-h to quail-translation-keymap. (quail-define-package): Fix typo in doc-string. (quail-conversion-str): New variable. (quail-input-method): Bind buffer-undo-list to t. Show Quail guidance buffer if necessary. (quail-delete-region): Move the definintion before the first calling place. (quail-start-translation): Handle the case the arg KEY is nil. Bind echo-keystrokes and help-char. Initialize quail-current-str to "". If input-method-use-echo-area is non-nil, call read-key-sequence with appropriate PROMPT arg. Setup last-command-event by local variable `keyseq'. Generate an event list form quail-current-str. If input-methodd-exit-on-first-char is non-nil, return only the first event. (quail-start-conversion): Likewise. Initialize quail-conversion-str to "". Generate an event list form quail-conversion-str. (quail-update-translation): Expect that the function given by (quail-update-translation-function) returns a new control-flag. Handle the case the length of quail-current-key is 1. Use string-as-unibyte if enable-multibyte-characters is nil. Always assures that quail-current-str is Lisp string. (quail-self-insert-command): Use `or' instead of `unless'. (quail-update-current-translations): Always assures that quail-current-str is Lisp string. (quail-next-translation-block): Update unread-command-events correctly. (quail-abort-translation): Set quail-current-str to nil. (quail-conversion-delete-char): Update quail-conversion-str. (quail-conversion-delete-tail): Likewise. (quail-conversion-backward-delete-char): Likewise. (quail-show-guidance-buf): Show Quail guidance buffer not in echo area if input-method-use-echo-area is non-nil. (quail-show-translations): Bind current-translations locally to quail-current-translations to get this value across different buffers. Handle the case that the length quail-current-key is 0. (quail-translation-help): If this command is invoked repeatedly, scroll the already shown help window. Handle the case that this command is called while converting (not translating). (quail-conversion-help): This function deleted and the functionality is merged to quail-translation-help.
author Kenichi Handa <handa@m17n.org>
date Thu, 06 Aug 1998 05:38:11 +0000
parents 4a529ce5a52e
children d8a417105504
line wrap: on
line source

/* Convert files for Emacs Hexl mode.
   Copyright (C) 1989 Free Software Foundation, Inc

This file is not considered part of GNU Emacs.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

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
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <ctype.h>
#ifdef DOS_NT
#include <fcntl.h>
#if __DJGPP__ >= 2
#include <io.h>
#endif
#endif
#ifdef WINDOWSNT
#include <io.h>
#endif

#define DEFAULT_GROUPING	0x01
#define DEFAULT_BASE		16

#undef TRUE
#undef FALSE
#define TRUE  (1)
#define FALSE (0)

int base = DEFAULT_BASE, un_flag = FALSE, iso_flag = FALSE, endian = 1;
int group_by = DEFAULT_GROUPING;
char *progname;

void usage();

int
main (argc, argv)
     int argc;
     char *argv[];
{
  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)
   */
    
  while (*argv && *argv[0] == '-' && (*argv)[1])
    {
      /* A switch! */
      if (!strcmp (*argv, "--"))
	{
	  --argc; argv++;
	  break;
	}
      else if (!strcmp (*argv, "-un") || !strcmp (*argv, "-de"))
	{
	  un_flag = TRUE;
	  --argc; argv++;
	}
      else if (!strcmp (*argv, "-hex"))
	{
	  base = 16;
	  --argc; argv++;
	}
      else if (!strcmp (*argv, "-iso"))
	{
	  iso_flag = TRUE;
	  --argc; argv++;
	}
      else if (!strcmp (*argv, "-oct"))
	{
	  base = 8;
	  --argc; argv++;
	}
      else if (!strcmp (*argv, "-big-endian"))
	{
	  endian = 1;
	  --argc; argv++;
	}
      else if (!strcmp (*argv, "-little-endian"))
	{
	  endian = 0;
	  --argc; argv++;
	}
      else if (!strcmp (*argv, "-group-by-8-bits"))
	{
	  group_by = 0x00;
	  --argc; argv++;
	}
      else if (!strcmp (*argv, "-group-by-16-bits"))
	{
	  group_by = 0x01;
	  --argc; argv++;
	}
      else if (!strcmp (*argv, "-group-by-32-bits"))
	{
	  group_by = 0x03;
	  --argc; argv++;
	}
      else if (!strcmp (*argv, "-group-by-64-bits"))
	{
	  group_by = 0x07;
	  endian = 0;
	  --argc; argv++;
	}
      else
	{
	  fprintf (stderr, "%s: invalid switch: \"%s\".\n", progname,
		   *argv);
	  usage ();
	}
    }

  do
    {
      if (*argv == NULL)
	fp = stdin;
      else
	{
	  char *filename = *argv++;

	  if (!strcmp (filename, "-"))
	    fp = stdin;
	  else if ((fp = fopen (filename, "r")) == NULL)
	    {
	      perror (filename);
	      continue;
	    }
	}

      if (un_flag)
	{
	  char buf[18];

#ifdef DOS_NT
#if (__DJGPP__ >= 2) || (defined WINDOWSNT)
          if (!isatty (fileno (stdout)))
	    setmode (fileno (stdout), O_BINARY);
#else
	  (stdout)->_flag &= ~_IOTEXT; /* print binary */
	  _setmode (fileno (stdout), O_BINARY);
#endif
#endif
	  for (;;)
	    {
	      register int i, c, d;

#define hexchar(x) (isdigit (x) ? x - '0' : x - 'a' + 10)

	      fread (buf, 1, 10, fp); /* skip 10 bytes */

	      for (i=0; i < 16; ++i)
		{
		  if ((c = getc (fp)) == ' ' || c == EOF)
		    break;

		  d = getc (fp);
		  c = hexchar (c) * 0x10 + hexchar (d);
		  putchar (c);

		  if ((i&group_by) == group_by)
		    getc (fp);
		}

	      if (c == ' ')
		{
		  while ((c = getc (fp)) != '\n' && c != EOF)
		    ;

		  if (c == EOF)
		    break;
		}
	      else
		{
		  if (i < 16)
		    break;

		  fread (buf, 1, 18, fp); /* skip 18 bytes */
		}
	    }
	}
      else
	{
#ifdef DOS_NT
#if (__DJGPP__ >= 2) || (defined WINDOWSNT)
          if (!isatty (fileno (fp)))
	    setmode (fileno (fp), O_BINARY);
#else
	  (fp)->_flag &= ~_IOTEXT; /* read binary */
	  _setmode (fileno (fp), O_BINARY);
#endif
#endif
	  address = 0;
	  string[0] = ' ';
	  string[17] = '\0';
	  for (;;)
	    {
	      register int i, c;

	      for (i=0; i < 16; ++i)
		{
		  if ((c = getc (fp)) == EOF)
		    {
		      if (!i)
			break;

		      fputs ("  ", stdout);
		      string[i+1] = '\0';
		    }
		  else
		    {
		      if (!i)
			printf ("%08lx: ", address);

		      if (iso_flag)
			string[i+1] =
			  (c < 0x20 || (c >= 0x7F && c < 0xa0)) ? '.' :c;
		      else
			string[i+1] = (c < 0x20 || c >= 0x7F) ? '.' : c;

		      printf ("%02x", c);
		    }

		  if ((i&group_by) == group_by)
		    putchar (' ');
		}

	      if (i)
		puts (string);

	      if (c == EOF)
		break;

	      address += 0x10;

	    }
	}

      if (fp != stdin)
	fclose (fp);

    } while (*argv != NULL);
  return 0;
}

void
usage ()
{
  fprintf (stderr, "usage: %s [-de] [-iso]\n", progname);
  exit (1);
}