1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-29 07:58:28 +00:00
emacs/lib-src/hexl.c

222 lines
4.5 KiB
C
Raw Normal View History

1997-08-13 15:37:10 +00:00
/* Convert files for Emacs Hexl mode.
2023-01-01 10:31:12 +00:00
Copyright (C) 1989, 2001-2023 Free Software Foundation, Inc.
Author: Keith Gabryelski (according to authors.el)
1997-08-13 15:37:10 +00:00
This file is not considered part of GNU Emacs.
This program is free software: you can redistribute it and/or modify
1997-08-13 15:37:10 +00:00
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at
your option) any later version.
1997-08-13 15:37:10 +00:00
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, see <https://www.gnu.org/licenses/>. */
1997-08-13 15:37:10 +00:00
#include <config.h>
#include <inttypes.h>
Limit <config.h>’s includes This follows up on recent problems with the fact that config.h includes stdlib.h etc.; some files need to include stdlib.h later. config.h generally should limit itself to includes that are universally safe; outside of MS-Windows, only stdbool.h makes the cut among the files currently included. So, move the other includes to just the files that need them (Bug#24506). * configure.ac (config_opsysfile): Remove, as this generic hook is no longer needed. * lib-src/etags.c, src/unexmacosx.c, src/w32.c, src/w32notify.c: * src/w32proc.c (_GNU_SOURCE): Remove, as it’s OK for config.h to do this now. * src/conf_post.h: Include <ms-w32.h>, instead of the generic config_opsysfile, for simplicity as this old way of configuring is now done only for the MS-Windows port. Do not include <ms-w32.h> if DEFER_MS_W32_H, for the benefit of the few files that want its effects later. Do not include <alloca.h>, <string.h>, or <stdlib.h>. Other files modified to include these headers as needed, or to not include headers that are no longer needed. * src/lisp.h: Include <alloca.h> and <string.h> here, since some of the inline functions need them. * src/regex.c: Include <alloca.h> if not emacs. (If emacs, we can rely on SAFE_ALLOCA.) There is no longer any need to worry about HAVE_ALLOCA_H. * src/unexmacosx.c: Rely on config.h not including stdlib.h. * src/w32.c, src/w32notify.c, src/w32proc.c (DEFER_MS_W32_H): Define before including <config.h> first, and include <ms-w32.h> after the troublesome headers.
2016-09-30 19:14:04 +00:00
#include <stdlib.h>
#include <string.h>
#include <binary-io.h>
Use unlocked stdio more systematically This can improve performance significantly on stdio-bottlenecked code. E.g., make-docfile is 3x faster on my Fedora 25 x86-64 desktop. * admin/merge-gnulib (GNULIB_MODULES): Add unlocked-io. * lib-src/ebrowse.c, lib-src/emacsclient.c, lib-src/etags.c: * lib-src/hexl.c, lib-src/make-docfile.c, lib-src/movemail.c: * lib-src/profile.c, lib-src/update-game-score.c: Include unlocked-io.h instead of stdio.h, since these programs are single-threaded. * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate. * lib/unlocked-io.h, m4/unlocked-io.m4: New files, copied from Gnulib. * src/charset.c, src/cm.c, src/emacs.c, src/image.c, src/keyboard.c: * src/lread.c, src/term.c: Include sysstdio.h, possibly instead of stdio.h, to define the unlocked functions if the system does not provide them. * src/charset.c, src/lread.c (getc_unlocked): Remove, since sysstdio.h now defines it if needed. * src/cm.c (cmputc, cmcheckmagic): * src/dispnew.c (update_frame, update_frame_with_menu) (update_frame_1, Fsend_string_to_terminal, Fding, bitch_at_user): * src/emacs.c (main, Fdump_emacs): * src/fileio.c (Fdo_auto_save, Fset_binary_mode): * src/image.c (slurp_file, png_read_from_file, png_load_body) (our_stdio_fill_input_buffer): * src/keyboard.c (record_char, kbd_buffer_get_event, handle_interrupt): * src/lread.c (readbyte_from_file): * src/minibuf.c (read_minibuf_noninteractive): * src/print.c (printchar_to_stream, strout) (Fredirect_debugging_output): * src/sysdep.c (reset_sys_modes, procfs_ttyname) (procfs_get_total_memory): * src/term.c (tty_ring_bell, tty_send_additional_strings) (tty_set_terminal_modes, tty_reset_terminal_modes) (tty_update_end, tty_clear_end_of_line, tty_write_glyphs) (tty_write_glyphs_with_face, tty_insert_glyphs) (tty_menu_activate): * src/xfaces.c (Fx_load_color_file): Use unlocked stdio when it should be safe. * src/sysstdio.h (clearerr_unlocked, feof_unlocked, ferror_unlocked) (fflush_unlocked, fgets_unlocked, fputc_unlocked, fputs_unlocked) (fread_unlocked, fwrite_unlocked, getc_unlocked, getchar_unlocked) (putc_unlocked, putchar_unloced): Provide substitutes if not declared.
2017-06-22 18:21:20 +00:00
#include <unlocked-io.h>
1989-05-27 04:15:37 +00:00
static char *progname;
1989-05-27 04:15:37 +00:00
static _Noreturn void
output_error (void)
{
fprintf (stderr, "%s: write error\n", progname);
exit (EXIT_FAILURE);
}
1989-05-27 04:15:37 +00:00
static int
hexchar (int c)
{
return c - ('0' <= c && c <= '9' ? '0' : 'a' - 10);
}
1994-10-12 20:21:51 +00:00
int
main (int argc, char **argv)
1989-05-27 04:15:37 +00:00
{
int status = EXIT_SUCCESS;
int DEFAULT_GROUPING = 0x01;
int group_by = DEFAULT_GROUPING;
bool un_flag = false, iso_flag = false;
progname = *argv++;
/*
** -hex hex dump
** -group-by-8-bits
** -group-by-16-bits
** -group-by-32-bits
** -group-by-64-bits
** -iso iso character set.
** -un || -de from hexl format to binary.
** -- End switch list.
** <filename> dump filename
** - (as filename == stdin)
*/
2001-12-30 22:09:01 +00:00
for (; *argv && *argv[0] == '-' && (*argv)[1]; argv++)
1989-05-27 04:15:37 +00:00
{
/* A switch! */
if (!strcmp (*argv, "--"))
1989-05-27 04:15:37 +00:00
{
argv++;
break;
}
else if (!strcmp (*argv, "-un") || !strcmp (*argv, "-de"))
1989-05-27 04:15:37 +00:00
{
Use bool for boolean, focusing on headers. * configure.ac (PTY_OPEN, GC_MARK_SECONDARY_STACK): Use bool for boolean. * lib-src/emacsclient.c, lib-src/etags.c, lib-src/hexl.c (FALSE, TRUE): Remove. All uses replaced with uncapitalized version. * lib-src/emacsclient.c (message): * lib-src/etags.c (make_tag, pfnote, consider_token, make_C_tag, lang_names): * lib-src/hexl.c (un_flag, iso_flag, endian): * lib-src/pop.c (pop_debug, pop_open, pop_multi_first, pop_multi_next) (pop_trash): Use bool for boolean. * lib-src/etags.c (bool): Remove. * lib-src/etags.c (globals, members, declarations, no_line_directive) (no_duplicates): Use 'int' for boolean values that getopt requires to be 'int'. Formerly, these were 'bool' and 'bool' was 'int', but we can no longer rely on this implementation. * lib-src/pop.h (struct _popserver): Use bool_bf for boolean bit-fields. * lwlib/xlwmenuP.h (XlwMenu_part): Use bool_bf for boolean bit-fields. * src/atimer.h, src/lisp.h, src/syssignal.h, src/syswait.h, src/unexelf.c: No need to include <stdbool.h>, since conf_post.h does it now. * src/buffer.h (BUF_COMPUTE_UNCHANGED, DECODE_POSITION) (BUFFER_CHECK_INDIRECTION, GET_OVERLAYS_AT, PER_BUFFER_VALUE_P) (SET_PER_BUFFER_VALUE_P): * src/ccl.c, src/ccl.h (setup_ccl_program): * src/ccl.h (CHECK_CCL_PROGRAM): * src/character.h (MAKE_CHAR_UNIBYTE, CHECK_CHARACTER_CAR) (CHECK_CHARACTER_CDR, CHAR_STRING_ADVANCE, NEXT_CHAR_BOUNDARY) (PREV_CHAR_BOUNDARY, FETCH_STRING_CHAR_ADVANCE) (FETCH_STRING_CHAR_AS_MULTIBYTE_ADVANCE) (FETCH_STRING_CHAR_ADVANCE_NO_CHECK, FETCH_CHAR_ADVANCE) (FETCH_CHAR_ADVANCE_NO_CHECK, INC_POS, DEC_POS, INC_BOTH) (DEC_BOTH, BUF_INC_POS, BUF_DEC_POS): * src/charset.h (CHECK_CHARSET, CHECK_CHARSET_GET_ID) (CHECK_CHARSET_GET_ATTR, CHECK_CHARSET_GET_CHARSET) (CHARSET_FAST_MAP_SET): * src/coding.c (decode_coding_ccl, encode_coding_ccl): * src/coding.h (CHECK_CODING_SYSTEM, CHECK_CODING_SYSTEM_GET_SPEC) (CHECK_CODING_SYSTEM_GET_ID, SJIS_TO_JIS, SJIS_TO_JIS2) (JIS_TO_SJIS, JIS_TO_SJIS2, ENCODE_FILE, DECODE_FILE) (ENCODE_SYSTEM, DECODE_SYSTEM, ENCODE_UTF_8) (decode_coding_c_string): * src/composite.h (COMPOSITION_DECODE_REFS, COMPOSITION_DECODE_RULE): * src/conf_post.h (has_attribute): * src/dispextern.h (trace_redisplay_p): (INC_TEXT_POS, DEC_TEXT_POS, SET_GLYPH_FROM_GLYPH_CODE) (SET_CHAR_GLYPH, SET_CHAR_GLYPH_FROM_GLYPH) (SET_GLYPH_FROM_CHAR_GLYPH): (WINDOW_WANTS_MODELINE_P, WINDOW_WANTS_HEADER_LINE_P) (FACE_SUITABLE_FOR_ASCII_CHAR_P, FACE_SUITABLE_FOR_CHAR_P) (PRODUCE_GLYPHS, reset_mouse_highlight, in_display_vector_p) (cursor_in_mouse_face_p): * src/dispnew.c (adjust_glyph_matrix, clear_glyph_matrix_rows) (blank_row, prepare_desired_row) (build_frame_matrix_from_leaf_window, make_current) (mirror_make_current, mirrored_line_dance, mirror_line_dance) (update_window, scrolling_window, update_frame_line): * src/disptab.h (GLYPH_FOLLOW_ALIASES): * src/editfns.c (Fformat): * src/font.h (FONT_WEIGHT_SYMBOLIC, FONT_SLANT_SYMBOLIC) (FONT_WIDTH_SYMBOLIC, FONT_WEIGHT_FOR_FACE, FONT_SLANT_FOR_FACE) (FONT_WIDTH_FOR_FACE, FONT_WEIGHT_NAME_NUMERIC) (FONT_SLANT_NAME_NUMERIC, FONT_WIDTH_NAME_NUMERIC) (FONT_SET_STYLE, CHECK_FONT, CHECK_FONT_SPEC, CHECK_FONT_ENTITY) (CHECK_FONT_OBJECT, CHECK_FONT_GET_OBJECT, FONT_ADD_LOG) (FONT_DEFERRED_LOG): * src/frame.h (FRAME_W32_P, FRAME_MSDOS_P, FRAME_WINDOW_P): (FRAME_EXTERNAL_TOOL_BAR, FRAME_EXTERNAL_MENU_BAR, FOR_EACH_FRAME) (FRAME_MOUSE_UPDATE): * src/fringe.c (Fdefine_fringe_bitmap): * src/image.c (x_create_bitmap_from_data, x_create_bitmap_mask) (x_create_bitmap_from_xpm_data, xpm_load_image): * src/intervals.h (INTERVAL_HAS_PARENT, INTERVAL_PARENT) (set_interval_parent, RESET_INTERVAL, COPY_INTERVAL_CACHE) (MERGE_INTERVAL_CACHE): * src/keymap.h (KEYMAPP): * src/lisp.h (eassert, USE_LSB_TAG, CHECK_LISP_OBJECT_TYPE) (STRING_SET_UNIBYTE, STRING_SET_MULTIBYTE, DEFSYM, PSEUDOVECTORP) (CHECK_RANGED_INTEGER, CHECK_TYPE_RANGED_INTEGER) (CHECK_NUMBER_COERCE_MARKER, CHECK_NUMBER_OR_FLOAT_COERCE_MARKER) (DEFVAR_LISP, DEFVAR_LISP_NOPRO, DEFVAR_BOOL, DEFVAR_INT) (DEFVAR_BUFFER_DEFAULTS, DEFVAR_KBOARD, QUIT) (RETURN_UNGCPRO, USE_SAFE_ALLOCA, SAFE_NALLOCA, SAFE_FREE) (SAFE_ALLOCA_LISP, FOR_EACH_ALIST_VALUE, functionp): * src/syntax.h (SYNTAX_ENTRY, SYNTAX_WITH_FLAGS, SYNTAX) (UPDATE_SYNTAX_TABLE_FORWARD, UPDATE_SYNTAX_TABLE_BACKWARD) (SETUP_BUFFER_SYNTAX_TABLE): * src/systime.h (timespec_valid_p): * src/term.c (save_and_enable_current_matrix): * src/window.h (WINDOW_MENU_BAR_P, WINDOW_TOOL_BAR_P): * src/xdisp.c (in_display_vector_p, display_tool_bar_line) (redisplay_internal, try_window_reusing_current_matrix) (sync_frame_with_window_matrix_rows, try_window_id) (display_menu_bar, display_tty_menu_item, display_mode_line) (coords_in_mouse_face_p, cursor_in_mouse_face_p): * src/xmenu.c (xmenu_show): * src/xterm.c (use_xim, x_term_init): * src/xterm.h (XSync, GTK_CHECK_VERSION, use_xim, SET_SCROLL_BAR_X_WIDGET) (struct x_bitmap_record): Use bool for booleans. * src/ccl.c (struct buffer_text): * src/ccl.h (struct ccl_program): * src/charset.h (struct charset): * src/cm.h (struct cm): * src/coding.h (struct iso_2022_spec, struct coding_system): * src/dispextern.h (struct glyph, struct glyph_matrix, struct glyph_row) (struct glyph_string, struct face, struct face_cache) (struct bidi_string_data, struct bidi_it) (struct draw_fringe_bitmap_params, struct it, Mouse_HLInfo) (struct image): * src/editfns.c (Fformat): * src/frame.h (struct frame): * src/fringe.c (struct fringe_bitmap): * src/intervals.h (struct interval): * src/keyboard.h (struct kboard): * src/lisp.h (struct Lisp_Symbol, struct Lisp_Misc_Any, struct Lisp_Marker) (struct Lisp_Overlay, struct Lisp_Save_Value, struct Lisp_Free) (struct Lisp_Buffer_Local_Value, union specbinding): * src/macfont.m (struct macfont_info): * src/process.h (struct Lisp_Process): * src/termchar.h (struct tty_display_info): * src/window.h (struct window): * src/xterm.h (struct x_output): Use bool_bf for boolean bit-fields. * src/ccl.c (setup_ccl_program): Now returns bool instead of -1 or 0. All callers changed. * src/ccl.h (struct ccl_program): Remove unused members private_state, src_multibyte, dst_multibyte, cr_consumed, suppress_error, eight_bit_control. (struct ccl_spec): Remove unused members cr_carryover, eight_bit_carryover. * src/conf_post.h: Include <stdbool.h>. (bool_bf): New type. * src/dispextern.h (TRACE, PREPARE_FACE_FOR_DISPLAY): * src/interval.h (RESET_INTERVAL, COPY_INTERVAL_CACHE, MERGE_INTERVAL_CACHE) Surround statement macro with proper 'do { ... } while (false)' brackets. (SET_MATRIX_ROW_ENABLED_P): Assume 2nd arg is bool. (PRODUCE_GLYPHS): Simplify use of boolean. * src/fileio.c (Fcopy_file): If I is an integer, prefer 'if (I != 0)' to 'if (I)'. * src/lisp.h (UNGCPRO): Return void, not int. (FOR_EACH_TAIL): Use void expression, not int expression. * src/region-cache.c: Reindent. * src/region-cache.h: Copy comments from region-cache.c, to fix incorrect remarks about booleans.
2013-12-14 21:36:44 +00:00
un_flag = true;
set_binary_mode (fileno (stdout), O_BINARY);
}
else if (!strcmp (*argv, "-hex"))
/* Hex is the default and is only base supported. */;
else if (!strcmp (*argv, "-iso"))
iso_flag = true;
else if (!strcmp (*argv, "-group-by-8-bits"))
group_by = 0x00;
else if (!strcmp (*argv, "-group-by-16-bits"))
group_by = 0x01;
else if (!strcmp (*argv, "-group-by-32-bits"))
group_by = 0x03;
else if (!strcmp (*argv, "-group-by-64-bits"))
group_by = 0x07;
else
1989-05-27 04:15:37 +00:00
{
fprintf (stderr, "%s: invalid switch: \"%s\".\n", progname,
*argv);
fprintf (stderr, "usage: %s [-de] [-iso]\n", progname);
return EXIT_FAILURE;
1989-05-27 04:15:37 +00:00
}
}
char const *filename = *argv ? *argv++ : "-";
do
1989-05-27 04:15:37 +00:00
{
FILE *fp;
if (!strcmp (filename, "-"))
{
fp = stdin;
if (!un_flag)
set_binary_mode (fileno (stdin), O_BINARY);
}
else
1989-05-27 04:15:37 +00:00
{
fp = fopen (filename, un_flag ? "r" : "rb");
if (!fp)
{
perror (filename);
status = EXIT_FAILURE;
continue;
}
1989-05-27 04:15:37 +00:00
}
if (un_flag)
1989-05-27 04:15:37 +00:00
{
for (int c; 0 <= (c = getc (fp)); )
1989-05-27 04:15:37 +00:00
{
/* Skip address at start of line. */
if (c != ' ')
continue;
1989-05-27 04:15:37 +00:00
for (int i = 0; i < 16; i++)
1989-05-27 04:15:37 +00:00
{
c = getc (fp);
if (c < 0 || c == ' ')
break;
1989-05-27 04:15:37 +00:00
int hc = hexchar (c);
c = getc (fp);
if (c < 0)
break;
putchar (hc * 0x10 + hexchar (c));
1989-05-27 04:15:37 +00:00
if ((i & group_by) == group_by)
{
c = getc (fp);
if (c < 0)
break;
}
1989-05-27 04:15:37 +00:00
}
while (0 <= c && c != '\n')
c = getc (fp);
if (c < 0)
break;
if (ferror (stdout))
output_error ();
1989-05-27 04:15:37 +00:00
}
}
else
1989-05-27 04:15:37 +00:00
{
int c = 0;
char string[18];
string[0] = ' ';
string[17] = '\0';
for (uintmax_t address = 0; 0 <= c; address += 0x10)
1989-05-27 04:15:37 +00:00
{
int i;
for (i = 0; i < 16; i++)
1989-05-27 04:15:37 +00:00
{
if (0 <= c)
c = getc (fp);
if (c < 0)
1989-05-27 04:15:37 +00:00
{
if (!i)
break;
1989-05-27 04:15:37 +00:00
fputs (" ", stdout);
string[i + 1] = '\0';
1989-05-27 04:15:37 +00:00
}
else
1989-05-27 04:15:37 +00:00
{
if (!i)
printf ("%08"PRIxMAX": ", address);
1989-05-27 04:15:37 +00:00
string[i + 1]
= (c < 0x20 || (0x7F <= c && (!iso_flag || c < 0xa0))
? '.' : c);
1989-05-27 04:15:37 +00:00
printf ("%02x", c + 0u);
1989-05-27 04:15:37 +00:00
}
if ((i & group_by) == group_by)
putchar (' ');
1989-05-27 04:15:37 +00:00
}
if (i)
puts (string);
1989-05-27 04:15:37 +00:00
if (ferror (stdout))
output_error ();
1989-05-27 04:15:37 +00:00
}
}
bool trouble = ferror (fp) != 0;
trouble |= fp != stdin && fclose (fp) != 0;
if (trouble)
{
fprintf (stderr, "%s: read error\n", progname);
status = EXIT_FAILURE;
}
1989-05-27 04:15:37 +00:00
filename = *argv++;
}
while (filename);
1989-05-27 04:15:37 +00:00
if (ferror (stdout) || fclose (stdout) != 0)
output_error ();
return status;
1989-05-27 04:15:37 +00:00
}