1/* Convert files for Emacs Hexl mode. 2 Copyright (C) 1989, 2001, 2002, 2003, 2004, 2005, 3 2006, 2007 Free Software Foundation, Inc. 4 5This file is not considered part of GNU Emacs. 6 7This program is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 2 of the License, or 10(at your option) any later version. 11 12This program is distributed in the hope that it will be useful, 13but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15GNU General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along with this program; if not, write to the Free Software Foundation, 19Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 20 21#ifdef HAVE_CONFIG_H 22#include <config.h> 23#endif 24 25#include <stdio.h> 26#include <ctype.h> 27#ifdef DOS_NT 28#include <fcntl.h> 29#if __DJGPP__ >= 2 30#include <io.h> 31#endif 32#endif 33#ifdef WINDOWSNT 34#include <io.h> 35#endif 36 37#define DEFAULT_GROUPING 0x01 38#define DEFAULT_BASE 16 39 40#undef TRUE 41#undef FALSE 42#define TRUE (1) 43#define FALSE (0) 44 45int base = DEFAULT_BASE, un_flag = FALSE, iso_flag = FALSE, endian = 1; 46int group_by = DEFAULT_GROUPING; 47char *progname; 48 49void usage(); 50 51int 52main (argc, argv) 53 int argc; 54 char *argv[]; 55{ 56 register long address; 57 char string[18]; 58 FILE *fp; 59 60 progname = *argv++; --argc; 61 62 /* 63 ** -hex hex dump 64 ** -oct Octal dump 65 ** -group-by-8-bits 66 ** -group-by-16-bits 67 ** -group-by-32-bits 68 ** -group-by-64-bits 69 ** -iso iso character set. 70 ** -big-endian Big Endian 71 ** -little-endian Little Endian 72 ** -un || -de from hexl format to binary. 73 ** -- End switch list. 74 ** <filename> dump filename 75 ** - (as filename == stdin) 76 */ 77 78 while (*argv && *argv[0] == '-' && (*argv)[1]) 79 { 80 /* A switch! */ 81 if (!strcmp (*argv, "--")) 82 { 83 --argc; argv++; 84 break; 85 } 86 else if (!strcmp (*argv, "-un") || !strcmp (*argv, "-de")) 87 { 88 un_flag = TRUE; 89 --argc; argv++; 90 } 91 else if (!strcmp (*argv, "-hex")) 92 { 93 base = 16; 94 --argc; argv++; 95 } 96 else if (!strcmp (*argv, "-iso")) 97 { 98 iso_flag = TRUE; 99 --argc; argv++; 100 } 101 else if (!strcmp (*argv, "-oct")) 102 { 103 base = 8; 104 --argc; argv++; 105 } 106 else if (!strcmp (*argv, "-big-endian")) 107 { 108 endian = 1; 109 --argc; argv++; 110 } 111 else if (!strcmp (*argv, "-little-endian")) 112 { 113 endian = 0; 114 --argc; argv++; 115 } 116 else if (!strcmp (*argv, "-group-by-8-bits")) 117 { 118 group_by = 0x00; 119 --argc; argv++; 120 } 121 else if (!strcmp (*argv, "-group-by-16-bits")) 122 { 123 group_by = 0x01; 124 --argc; argv++; 125 } 126 else if (!strcmp (*argv, "-group-by-32-bits")) 127 { 128 group_by = 0x03; 129 --argc; argv++; 130 } 131 else if (!strcmp (*argv, "-group-by-64-bits")) 132 { 133 group_by = 0x07; 134 endian = 0; 135 --argc; argv++; 136 } 137 else 138 { 139 fprintf (stderr, "%s: invalid switch: \"%s\".\n", progname, 140 *argv); 141 usage (); 142 } 143 } 144 145 do 146 { 147 if (*argv == NULL) 148 fp = stdin; 149 else 150 { 151 char *filename = *argv++; 152 153 if (!strcmp (filename, "-")) 154 fp = stdin; 155 else if ((fp = fopen (filename, "r")) == NULL) 156 { 157 perror (filename); 158 continue; 159 } 160 } 161 162 if (un_flag) 163 { 164 char buf[18]; 165 166#ifdef DOS_NT 167#if (__DJGPP__ >= 2) || (defined WINDOWSNT) 168 if (!isatty (fileno (stdout))) 169 setmode (fileno (stdout), O_BINARY); 170#else 171 (stdout)->_flag &= ~_IOTEXT; /* print binary */ 172 _setmode (fileno (stdout), O_BINARY); 173#endif 174#endif 175 for (;;) 176 { 177 register int i, c = 0, d; 178 179#define hexchar(x) (isdigit (x) ? x - '0' : x - 'a' + 10) 180 181 fread (buf, 1, 10, fp); /* skip 10 bytes */ 182 183 for (i=0; i < 16; ++i) 184 { 185 if ((c = getc (fp)) == ' ' || c == EOF) 186 break; 187 188 d = getc (fp); 189 c = hexchar (c) * 0x10 + hexchar (d); 190 putchar (c); 191 192 if ((i&group_by) == group_by) 193 getc (fp); 194 } 195 196 if (c == ' ') 197 { 198 while ((c = getc (fp)) != '\n' && c != EOF) 199 ; 200 201 if (c == EOF) 202 break; 203 } 204 else 205 { 206 if (i < 16) 207 break; 208 209 fread (buf, 1, 18, fp); /* skip 18 bytes */ 210 } 211 } 212 } 213 else 214 { 215#ifdef DOS_NT 216#if (__DJGPP__ >= 2) || (defined WINDOWSNT) 217 if (!isatty (fileno (fp))) 218 setmode (fileno (fp), O_BINARY); 219#else 220 (fp)->_flag &= ~_IOTEXT; /* read binary */ 221 _setmode (fileno (fp), O_BINARY); 222#endif 223#endif 224 address = 0; 225 string[0] = ' '; 226 string[17] = '\0'; 227 for (;;) 228 { 229 register int i, c = 0; 230 231 for (i=0; i < 16; ++i) 232 { 233 if ((c = getc (fp)) == EOF) 234 { 235 if (!i) 236 break; 237 238 fputs (" ", stdout); 239 string[i+1] = '\0'; 240 } 241 else 242 { 243 if (!i) 244 printf ("%08lx: ", address); 245 246 if (iso_flag) 247 string[i+1] = 248 (c < 0x20 || (c >= 0x7F && c < 0xa0)) ? '.' :c; 249 else 250 string[i+1] = (c < 0x20 || c >= 0x7F) ? '.' : c; 251 252 printf ("%02x", c); 253 } 254 255 if ((i&group_by) == group_by) 256 putchar (' '); 257 } 258 259 if (i) 260 puts (string); 261 262 if (c == EOF) 263 break; 264 265 address += 0x10; 266 267 } 268 } 269 270 if (fp != stdin) 271 fclose (fp); 272 273 } while (*argv != NULL); 274 return EXIT_SUCCESS; 275} 276 277void 278usage () 279{ 280 fprintf (stderr, "usage: %s [-de] [-iso]\n", progname); 281 exit (EXIT_FAILURE); 282} 283 284/* arch-tag: 20e04fb7-926e-4e48-be86-64fe869ecdaa 285 (do not change this comment) */ 286 287/* hexl.c ends here */ 288