diff options
author | nobody <> | 2006-05-12 01:45:11 +0000 |
---|---|---|
committer | nobody <> | 2006-05-12 01:45:11 +0000 |
commit | e8e812a12d4cb20e7229974377daf50c405bcac0 (patch) | |
tree | 34d0f79e6f843572b1072ce8ad56bd46df7e411a | |
parent | 49b5a1f5dc74a0e693a51409252b3d590cc00bbb (diff) | |
download | fsf-binutils-gdb-nickrob-async-20060513-branchpoint.zip fsf-binutils-gdb-nickrob-async-20060513-branchpoint.tar.gz fsf-binutils-gdb-nickrob-async-20060513-branchpoint.tar.bz2 |
This commit was manufactured by cvs2svn to create branch 'nickrob-nickrob-async-20060513-branchpoint
async-20060513-branch'.
Sprout from readline_5_1-import-branch 2006-04-20 20:13:22 UTC nobody 'This commit was manufactured by cvs2svn to create branch 'readline_5_1'
Cherrypick from master 2006-05-12 01:45:10 UTC Ben Elliston <bje@au.ibm.com> ' * config.sub, config.guess: Update from upstream sources.':
ChangeLog
bfd/ChangeLog
bfd/aout-ns32k.c
bfd/aoutf1.h
bfd/aoutx.h
bfd/archive.c
bfd/bfd-in.h
bfd/bfd-in2.h
bfd/coff-arm.c
bfd/coff-or32.c
bfd/coff-rs6000.c
bfd/coff-w65.c
bfd/coffcode.h
bfd/cofflink.c
bfd/cpu-arm.c
bfd/doc/ChangeLog
bfd/doc/bfd.texinfo
bfd/dwarf2.c
bfd/ecoff.c
bfd/ecofflink.c
bfd/elf-eh-frame.c
bfd/elf.c
bfd/elf32-arm.c
bfd/elf32-avr.c
bfd/elf32-dlx.c
bfd/elf32-i370.c
bfd/elf32-m32c.c
bfd/elf32-ppc.c
bfd/elf32-s390.c
bfd/elf32-sh-symbian.c
bfd/elf32-sh64.c
bfd/elf32-v850.c
bfd/elf32-xtensa.c
bfd/elf64-mmix.c
bfd/elf64-ppc.c
bfd/elf64-s390.c
bfd/elfcode.h
bfd/elflink.c
bfd/elfxx-mips.c
bfd/elfxx-sparc.c
bfd/elfxx-target.h
bfd/hash.c
bfd/ieee.c
bfd/ihex.c
bfd/libbfd-in.h
bfd/libbfd.h
bfd/mmo.c
bfd/nlm32-sparc.c
bfd/oasys.c
bfd/opncls.c
bfd/pdp11.c
bfd/reloc.c
bfd/section.c
bfd/som.c
bfd/tekhex.c
bfd/version.h
bfd/vms.c
config.guess
config.sub
configure
configure.in
etc/ChangeLog
etc/texi2pod.pl
gdb/ChangeLog
gdb/MAINTAINERS
gdb/Makefile.in
gdb/NEWS
gdb/breakpoint.c
gdb/config/m32c/m32c.mt
gdb/configure.tgt
gdb/doc/ChangeLog
gdb/doc/Makefile.in
gdb/doc/agentexpr.texi
gdb/doc/gdb.texinfo
gdb/doc/gdbint.texinfo
gdb/doc/observer.texi
gdb/dwarf2-frame.c
gdb/dwarf2-frame.h
gdb/dwarf2read.c
gdb/gdbserver/ChangeLog
gdb/gdbserver/configure.srv
gdb/gdbserver/linux-low.c
gdb/gdbserver/server.c
gdb/gdbserver/target.h
gdb/gnu-nat.c
gdb/hppa-hpux-tdep.c
gdb/linux-fork.c
gdb/linux-nat.c
gdb/linux-thread-db.c
gdb/m32c-tdep.c
gdb/mi/mi-main.c
gdb/mingw-hdep.c
gdb/mips-mdebug-tdep.c
gdb/mips-tdep.c
gdb/ppc-linux-nat.c
gdb/ppcnbsd-tdep.c
gdb/remote.c
gdb/rs6000-tdep.c
gdb/s390-tdep.c
gdb/ser-mingw.c
gdb/serial.c
gdb/serial.h
gdb/symtab.c
gdb/target.c
gdb/target.h
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.asm/asm-source.exp
gdb/testsuite/gdb.asm/m32c.inc
gdb/testsuite/gdb.base/bang.exp
gdb/testsuite/gdb.base/break.exp
gdb/testsuite/gdb.base/del.c
gdb/testsuite/gdb.base/del.exp
gdb/testsuite/gdb.base/help.exp
gdb/testsuite/gdb.base/multi-forks.exp
gdb/testsuite/gdb.base/savedregs.exp
gdb/testsuite/gdb.base/sigbpt.exp
gdb/testsuite/gdb.base/siginfo.exp
gdb/testsuite/gdb.base/sigstep.exp
gdb/testsuite/gdb.cp/m-static.cc
gdb/testsuite/gdb.cp/m-static.h
gdb/testsuite/gdb.mi/mi-basics.exp
gdb/testsuite/gdb.mi/mi-regs.exp
gdb/testsuite/gdb.mi/mi2-basics.exp
gdb/testsuite/gdb.mi/mi2-regs.exp
gdb/testsuite/gdb.mi/var-cmd.c
gdb/varobj.c
gdb/version.in
include/ChangeLog
include/opcode/ChangeLog
include/opcode/arm.h
include/opcode/mips.h
libiberty/ChangeLog
libiberty/floatformat.c
opcodes/ChangeLog
opcodes/arm-dis.c
opcodes/i386-dis.c
opcodes/m68k-dis.c
opcodes/mips-dis.c
opcodes/mips-opc.c
opcodes/mips16-opc.c
readline/CHANGELOG
readline/CHANGES
readline/ChangeLog.gdb
readline/INSTALL
readline/MANIFEST
readline/Makefile.in
readline/README
readline/aclocal.m4
readline/bind.c
readline/callback.c
readline/chardefs.h
readline/complete.c
readline/config.h.in
readline/configure
readline/configure.in
readline/display.c
readline/doc/ChangeLog.gdb
readline/doc/Makefile.in
readline/doc/history.3
readline/doc/inc-hist.texinfo
readline/doc/readline.3
readline/doc/texi2dvi
readline/emacs_keymap.c
readline/examples/ChangeLog.gdb
readline/examples/Makefile.in
readline/examples/histexamp.c
readline/examples/rl.c
readline/examples/rlcat.c
readline/examples/rltest.c
readline/examples/rlversion.c
readline/funmap.c
readline/histexpand.c
readline/histfile.c
readline/history.c
readline/history.h
readline/histsearch.c
readline/input.c
readline/isearch.c
readline/keymaps.c
readline/kill.c
readline/macro.c
readline/mbutil.c
readline/misc.c
readline/nls.c
readline/parens.c
readline/posixdir.h
readline/readline.c
readline/readline.h
readline/rldefs.h
readline/rlmbutil.h
readline/rlprivate.h
readline/rlstdc.h
readline/rltty.c
readline/rltty.h
readline/rltypedefs.h
readline/savestring.c
readline/search.c
readline/shell.c
readline/shlib/Makefile.in
readline/signals.c
readline/support/shlib-install
readline/support/shobj-conf
readline/terminal.c
readline/text.c
readline/tilde.c
readline/tilde.h
readline/undo.c
readline/util.c
readline/vi_keymap.c
readline/vi_mode.c
sim/ChangeLog
sim/MAINTAINERS
sim/Makefile.in
sim/configure
sim/configure.ac
sim/ppc/ChangeLog
sim/ppc/Makefile.in
sim/ppc/configure
sim/ppc/configure.ac
Delete:
readline/acconfig.h
readline/config.h.bot
readline/doc/hist.texinfo
readline/doc/history.pdf
readline/doc/hstech.texinfo
readline/doc/hsuser.texinfo
readline/doc/manvers.texinfo
readline/doc/readline.pdf
readline/doc/rlman.texinfo
readline/doc/rltech.texinfo
readline/doc/rluser.texinfo
readline/doc/rluserman.pdf
readline/doc/rluserman.texinfo
readline/examples/rlfe.c
233 files changed, 15863 insertions, 9999 deletions
@@ -1,3 +1,16 @@ +2006-05-12 Ben Elliston <bje@au.ibm.com> + + * config.sub, config.guess: Update from upstream sources. + +2006-05-04 Steve Ellcey <sje@cup.hp.com> + + * blt, iwidgets, mmalloc: Remove directories. + +2006-05-01 DJ Delorie <dj@redhat.com> + + * configure.in: Restore CFLAGS if GMP isn't present. + * configure: Regenerate. + 2006-04-18 DJ Delorie <dj@redhat.com> * configure.in (m32c): Build libstdc++-v3. Pass flags to @@ -119,7 +132,7 @@ 2006-01-16 Nick Clifton <nickc@redhat.com> - * config.sub, config.guess: Sync from config repository. + * config.sub, config.guess: Sync from config repository. 2006-01-05 Alexandre Oliva <aoliva@redhat.com> diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 1ea6061..c64ae21 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,257 @@ +2006-05-11 Michael Matz <matz@suse.de> + + * elflink.c (match_group_member): Correctly iterate group + members. + +2006-05-11 Paul Brook <paul@codesourcery.com> + + * elf32-arm.c (elf32_arm_reloc_map): Add MOVW and MOVT relocs. + (elf32_arm_final_link_relocate): Handle MOVW and MOVT relocs. + (elf32_arm_gc_sweep_hook, elf32_arm_check_relocs): Ditto. + * reloc.c: Ditto. + * bfd-in2.h: Regenerate. + * libbfd.h: Regenerate. + * libcoff.h: Regenerate. + +2006-05-11 Mike Bland <mbland@google.com> + + * elf.c (_bfd_elf_init_private_section_data): Don't change + section type if already set. + +2006-05-10 Nick Clifton <nickc@redhat.com> + + PR ld/2607 + * elfcode.h (valid_section_index_p): New function: Checks for a + valid section index. Allows indicies in the range SHN_LOPROC to + SHN_HIOS. + (elf_object_p): Use valid_section_index_p. + +2006-05-11 Pedro Alves <pedro_alves@portugalmail.pt> + + * coff-arm.c (ARM_26D, ARM_32, ARM_RVA_32, ARM_SECTION, + ARM_SECREL): Mark WinCE versions of these relocs as partial + inplace. + (coff_arm_relocate_section): Adjust addend for WinCE. + +2006-05-10 Alan Modra <amodra@bigpond.net.au> + + PR 2342 + * elflink.c (_bfd_elf_default_action_discarded): Revert 2006-02-16. + +2006-05-09 Nick Clifton <nickc@redhat.com> + + * coffcode.h (coff_write_relocs): Produce an error message if a an + out-of-range symbol index is detected in a reloc. + +2006-05-09 Ben Elliston <bje@au.ibm.com> + + * elf64-ppc.c (ppc64_elf_finish_dynamic_symbol): Remove unused + local variable `dynobj'. + +2006-05-05 Bjoern Haase <bjoern.m.haase@web.de> + + * elf32-avr.c (elf32_avr_relax_delete_bytes): Iterate over all + of the bfd's sections for the reloc-addend adjustments. + +2006-05-05 Martin Schwidefsky <schwidefsky@de.ibm.com> + + * elf32-s390.c (invalid_tls_insn): Call bfd_set_error. + (elf_s390_relocate_section): Add code to do the GD->LE and + LD->LE TLS linker optimizations if a brasl instruction is used + for the __tls_get_offset function call. + * elf64-s390.c (invalid_tls_insn): Call bfd_set_error. + +2006-05-05 Alan Modra <amodra@bigpond.net.au> + + * elf64-ppc.c (ppc64_elf_tls_optimize): Only optimize + R_PPC64_TPREL64 and R_PPC64_DTPMOD64 relocs when they are in + the .toc and referenced by a TLS code sequence. + (ppc64_elf_edit_toc): Cater for the unlikely situation that + .toc is the first section in a file. + +2006-05-04 Andreas Schwab <schwab@suse.de> + + * aoutf1.h (struct external_sparc_core): Declare c_regs as struct + regs instead of an array of int. + (struct external_solaris_bcp_core): Likewise. + (swapcore_sun3): Use offsetof instead of computing the offset + manually. + (swapcore_sparc): Likewise. Simplify reference to c_regs. + (swapcore_solaris_bcp): Likewise. + +2006-05-04 Daniel Jacobowitz <dan@codesourcery.com> + + * elfxx-mips.c (_bfd_mips_elf_hide_symbol): Adjust handling + for missing GOTs. + +2006-05-04 Daniel Jacobowitz <dan@codesourcery.com> + + * bfd/cpu-arm.c (bfd_is_arm_mapping_symbol_name): Accept more + mapping symbols. + +2006-05-04 Ben Elliston <bje@au.ibm.com> + + * coff-or32.c (bfd_section_from_shdr): Remove unused local + variable `ptr'. + * cofflink.c (process_embedded_commands): Remove unused local + variables `had_read' and `had_shared'. + * ecofflink.c (bfd_ecoff_debug_accumulate): Remove unused local + variable `fdr_adr'. + * ihex.c (ihex_read_section): Remove unused local variable `addr'. + +2006-05-03 Alan Modra <amodra@bigpond.net.au> + + * libbfd-in.h (_bfd_generic_new_section_hook): Declare. + * section.c (bfd_abs_symbol, bfd_com_symbol): Delete. + (bfd_und_symbol, bfd_ind_symbol): Delete. + (BFD_FAKE_SECTION): Remove SYM_PTR param, set symbol_ptr_ptr to + &SEC.symbol. + (STD_SECTION): Adjust. + (_bfd_generic_new_section_hook): New function, extracted from.. + (bfd_section_init): ..here. + (bfd_make_section_old_way): Call new_section_hook for abs, com, + und and ind sections. + * elf.c (_bfd_elf_large_com_section): Adjust. + * aoutx.h (new_section_hook): Call _bfd_generic_new_section_hook. + * pdp11.c (new_section_hook): Likewise. + * coffcode.h (coff_new_section_hook): Likewise. + * ecoff.c (_bfd_ecoff_new_section_hook): Likewise. + * elf.c (_bfd_elf_new_section_hook): Likewise. + * vms.c (vms_new_section_hook): Likwise. + * elf32-arm.c (elf32_arm_new_section_hook): Check used_by_bfd isn't + already set. + * elf32-sh64.c (sh64_elf_new_section_hook): Likewise. + * elf32-xtensa.c (elf_xtensa_new_section_hook): Likewise. + * elf64-mmix.c (mmix_elf_new_section_hook): Likewise. + * elf64-ppc.c (ppc64_elf_new_section_hook): Likewise. + * elfxx-mips.c (_bfd_mips_elf_new_section_hook): Likewise. + * elfxx-sparc.c (_bfd_sparc_elf_new_section_hook): Likewise. + * ieee.c (ieee_new_section_hook): Likewise. Call + _bfd_generic_new_section_hook too. + * mmo.c (mmo_new_section_hook): Likewise. + * oasys.c (oasys_new_section_hook): Likewise. + * som.c (som_new_section_hook): Likewise. + * coff-w65.c (reloc_processing): Don't use bfd_abs_symbol. + * bfd-in2.h: Regenerate. + * libbfd.h: Regenerate. + +2006-05-03 Alan Modra <amodra@bigpond.net.au> + + * hash.c (DEFAULT_SIZE): Revert last change. + (higher_prime_number): Correct test for no larger prime. Don't + abort on error, instead return 0. Depopulate primes[]. + (bfd_hash_lookup): If we overflow size, refuse to grow table. + +2006-05-02 Paul Brook <paul@codesourcery.com> + + * elf32-arm.c (elf32_arm_final_link_relocate): Set thumb funciton bit + for R_ARM_REL32. + +2006-05-02 Ben Elliston <bje@au.ibm.com> + + * archive.c (bfd_generic_archive_p): Remove unused local variable + `fail'. + * dwarf2.c (decode_line_info): Remove unused local variable + `basic_block'. + * elfcode.h (elf_slurp_reloc_table_from_section): Remove unused + local variable `s'. + * tekhex.c (tekhex_write_object_contents): Remove unused local + variable `bytes_written'. + * aout-ns32k.c (MY_swap_std_reloc_out): Remove unused local + variable `r_addend'. + * elf32-dlx.c (dlx_rtype_to_howto): Remove breaks after returns. + * elfxx-mips.c (_bfd_elf_mips_mach): Remove breaks after returns. + (_bfd_ns32k_relocate_contents): Remove break after return. + * elf.c (bfd_section_from_shdr): Remove breaks after returns. + +2006-05-02 Nick Clifton <nickc@redhat.com> + + * elf32-sh-symbian.c: Rename local define DEBUG to SYMBIAN_DEBUG + in order to avoid conflicts with the global DEBUG define. + +2006-05-02 Alan Modra <amodra@bigpond.net.au> + + * dwarf2.c: Formatting. + * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Simplify + output section check. + * elf32-i370.c: Warning fixes inside #ifdef DEBUG. + * elf32-m32c.c: Similarly. + * elf32-ppc.c: Similarly. + * elf32-v850.c: Similarly. + * nlm32-sparc.c: Similarly. + * elfcode.h: Similarly. + (elf_symbol_flags): Delete. + * elflink.c (elf_link_input_bfd): Comment typo. + +2006-05-01 DJ Delorie <dj@redhat.com> + + * bfd-in.h (bfd_hash_table): Add count field. + * bfd-in2.h: Regenerate. + * hash.c (higher_prime_number): New. + (bfd_hash_table_inint_n): Init count field. + (bfd_hash_lookup): Grow table as needed. + +2006-04-27 Kaz Kojima <kkojima@rr.iij4u.or.jp> + + PR binutils/2584 + * tekhex.c (getvalue): Change return type to bfd_boolean and + add the new parameter. Return false if the unexpected character + is found. + (getsym): Likewise. + (first_phase): Change return type to bfd_boolean and return + false if the unexpected character is found. Replace abort + with returning false. + (pass_over): Change return type to bfd_boolean and the type of + the second argument to bfd_boolean (*) (bfd *, int, char *). + Return false if FUNC returns false. + (tekhex_object_p): Return NULL if pass_over fails. + +2006-04-27 Alan Modra <amodra@bigpond.net.au> + + * coff-rs6000.c (xcoff_write_archive_contents_old): Warning fix. + +2006-04-26 H.J. Lu <hongjiu.lu@intel.com> + + PR binutils/2593 + * elf.c (_bfd_elf_new_section_hook): Don't set section ELF type + and flags if its BFD flags have been set. + (_bfd_elf_init_private_section_data): Don't copy the output ELF + section type from input if it has been set to something + different. + +2006-04-25 H.J. Lu <hongjiu.lu@intel.com> + + PR binutils/2467 + * elf.c (_bfd_elf_close_and_cleanup): Check elf_tdata (abfd) + is NULL first. + + * elf32-arm.c (elf32_arm_close_and_cleanup): Check if + abfd->sections is NULL. + (elf32_arm_bfd_free_cached_info): New. + (bfd_elf32_bfd_free_cached_info): Defined. + + * elfxx-target.h (bfd_elfNN_bfd_free_cached_info): Default it + to _bfd_free_cached_info. + + * libbfd-in.h (_bfd_free_cached_info): New. + * libbfd: Regenerated. + + * opncls.c (_bfd_delete_bfd): Check if abfd->memory is NULL. + (_bfd_free_cached_info): New. + +2006-04-21 Alan Modra <amodra@bigpond.net.au> + + * elf.c (assign_file_positions_except_relocs): Move code setting + file position of non-loaded sections.. + (assign_file_positions_for_segments): ..to here. + +2006-04-20 H.J. Lu <hongjiu.lu@intel.com> + + PR ld/2537 + * elf.c (bfd_section_from_shdr): Allow sections reserved for + applications. Issue an error on sections we don't know how + to handle. + 2006-04-19 Alan Modra <amodra@bigpond.net.au> * Makefile.am: Run "make dep-am". @@ -278,6 +532,24 @@ bfd_get_compatible to set the new bfd architecture. Rely on it to detect incompatibilities. +2006-03-23 Michael Matz <matz@suse.de> + + * reloc.c: Add BFD_RELOC_X86_64_GOT64, BFD_RELOC_X86_64_GOTPCREL64, + BFD_RELOC_X86_64_GOTPC64, BFD_RELOC_X86_64_GOTPLT64, + BFD_RELOC_X86_64_PLTOFF64. + * bfd-in2.h: Regenerated. + * libbfd.h: Regenerated. + * elf64-x86-64.c (x86_64_elf_howto_table): Correct comment. + Add howtos for above relocs. + (x86_64_reloc_map): Add mappings for new relocs. + (elf64_x86_64_check_relocs): R_X86_64_GOT64, R_X86_64_GOTPCREL64, + R_X86_64_GOTPLT64 need a got entry. R_X86_64_GOTPLT64 also a PLT + entry. R_X86_64_GOTPC64 needs a .got section. R_X86_64_PLTOFF64 + needs a PLT entry. + (elf64_x86_64_gc_sweep_hook): Reflect changes from + elf64_x86_64_check_relocs for the new relocs. + (elf64_x86_64_relocate_section): Handle new relocs. + 2006-03-22 Bob Wilson <bob.wilson@acm.org> * elf32-xtensa.c (xtensa_read_table_entries): Remove assertion that diff --git a/bfd/aout-ns32k.c b/bfd/aout-ns32k.c index cc9f06d..86cdcd5 100644 --- a/bfd/aout-ns32k.c +++ b/bfd/aout-ns32k.c @@ -274,11 +274,8 @@ MY_swap_std_reloc_out (bfd *abfd, int r_index; asymbol *sym = *(g->sym_ptr_ptr); int r_extern; - unsigned int r_addend; asection *output_section = sym->section->output_section; - r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma; - /* Name was clobbered by aout_write_syms to be symbol index. */ /* If this relocation is relative to a symbol then set the @@ -341,7 +338,6 @@ _bfd_ns32k_relocate_contents (reloc_howto_type *howto, case 2: return _bfd_relocate_contents (howto, input_bfd, relocation, location); - break; default: return bfd_reloc_notsupported; } diff --git a/bfd/aoutf1.h b/bfd/aoutf1.h index cff7b3c..e67190d 100644 --- a/bfd/aoutf1.h +++ b/bfd/aoutf1.h @@ -286,7 +286,7 @@ struct external_sparc_core int c_magic; /* Corefile magic number. */ int c_len; /* Sizeof (struct core). */ #define SPARC_CORE_LEN 432 - int c_regs[19]; /* General purpose registers -- MACHDEP SIZE. */ + struct regs c_regs; /* General purpose registers -- MACHDEP SIZE. */ struct external_exec c_aouthdr; /* A.out header. */ int c_signo; /* Killing signal, if any. */ int c_tsize; /* Text size (bytes). */ @@ -309,7 +309,7 @@ struct external_solaris_bcp_core int c_magic; /* Corefile magic number. */ int c_len; /* Sizeof (struct core). */ #define SOLARIS_BCP_CORE_LEN 456 - int c_regs[19]; /* General purpose registers -- MACHDEP SIZE. */ + struct regs c_regs; /* General purpose registers -- MACHDEP SIZE. */ int c_exdata_vp; /* Exdata structure. */ int c_exdata_tsize; int c_exdata_dsize; @@ -387,7 +387,7 @@ swapcore_sun3 (bfd *abfd, char *ext, struct internal_sunos_core *intcore) intcore->c_magic = H_GET_32 (abfd, &extcore->c_magic); intcore->c_len = H_GET_32 (abfd, &extcore->c_len); - intcore->c_regs_pos = (long) (((struct external_sun3_core *) 0)->c_regs); + intcore->c_regs_pos = offsetof (struct external_sun3_core, c_regs); intcore->c_regs_size = sizeof (extcore->c_regs); #if ARCH_SIZE == 64 aout_64_swap_exec_header_in @@ -401,10 +401,10 @@ swapcore_sun3 (bfd *abfd, char *ext, struct internal_sunos_core *intcore) intcore->c_data_addr = N_DATADDR (intcore->c_aouthdr); intcore->c_ssize = H_GET_32 (abfd, &extcore->c_ssize); memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname)); - intcore->fp_stuff_pos = (long) (((struct external_sun3_core *) 0)->fp_stuff); + intcore->fp_stuff_pos = offsetof (struct external_sun3_core, fp_stuff); /* FP stuff takes up whole rest of struct, except c_ucode. */ intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) - - (file_ptr) (((struct external_sun3_core *) 0)->fp_stuff); + offsetof (struct external_sun3_core, fp_stuff); /* Ucode is the last thing in the struct -- just before the end. */ intcore->c_ucode = H_GET_32 (abfd, (intcore->c_len @@ -422,7 +422,7 @@ swapcore_sparc (bfd *abfd, char *ext, struct internal_sunos_core *intcore) intcore->c_magic = H_GET_32 (abfd, &extcore->c_magic); intcore->c_len = H_GET_32 (abfd, &extcore->c_len); - intcore->c_regs_pos = (long) (((struct external_sparc_core *) 0)->c_regs); + intcore->c_regs_pos = offsetof (struct external_sparc_core, c_regs); intcore->c_regs_size = sizeof (extcore->c_regs); #if ARCH_SIZE == 64 aout_64_swap_exec_header_in @@ -436,10 +436,10 @@ swapcore_sparc (bfd *abfd, char *ext, struct internal_sunos_core *intcore) intcore->c_data_addr = N_DATADDR (intcore->c_aouthdr); intcore->c_ssize = H_GET_32 (abfd, &extcore->c_ssize); memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname)); - intcore->fp_stuff_pos = (long) (((struct external_sparc_core *) 0)->fp_stuff); + intcore->fp_stuff_pos = offsetof (struct external_sparc_core, fp_stuff); /* FP stuff takes up whole rest of struct, except c_ucode. */ intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) - - (file_ptr) (((struct external_sparc_core *) 0)->fp_stuff); + offsetof (struct external_sparc_core, fp_stuff); /* Ucode is the last thing in the struct -- just before the end. */ intcore->c_ucode = H_GET_32 (abfd, (intcore->c_len @@ -462,7 +462,7 @@ swapcore_sparc (bfd *abfd, char *ext, struct internal_sunos_core *intcore) #define SPARC_USRSTACK_SPARC2 ((bfd_vma)0xf8000000) #define SPARC_USRSTACK_SPARC10 ((bfd_vma)0xf0000000) { - bfd_vma sp = H_GET_32 (abfd, &((struct regs *) &extcore->c_regs[0])->r_o6); + bfd_vma sp = H_GET_32 (abfd, &extcore->c_regs.r_o6); if (sp < SPARC_USRSTACK_SPARC10) intcore->c_stacktop = SPARC_USRSTACK_SPARC10; else @@ -480,7 +480,7 @@ swapcore_solaris_bcp (bfd *abfd, char *ext, struct internal_sunos_core *intcore) intcore->c_magic = H_GET_32 (abfd, &extcore->c_magic); intcore->c_len = H_GET_32 (abfd, &extcore->c_len); - intcore->c_regs_pos = (long) (((struct external_solaris_bcp_core *) 0)->c_regs); + intcore->c_regs_pos = offsetof (struct external_solaris_bcp_core, c_regs); intcore->c_regs_size = sizeof (extcore->c_regs); /* The Solaris BCP exdata structure does not contain an a_syms field, @@ -501,10 +501,10 @@ swapcore_solaris_bcp (bfd *abfd, char *ext, struct internal_sunos_core *intcore) intcore->c_ssize = H_GET_32 (abfd, &extcore->c_ssize); memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname)); intcore->fp_stuff_pos = - (long) (((struct external_solaris_bcp_core *) 0)->fp_stuff); + offsetof (struct external_solaris_bcp_core, fp_stuff); /* FP stuff takes up whole rest of struct, except c_ucode. */ intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) - - (file_ptr) (((struct external_solaris_bcp_core *) 0)->fp_stuff); + offsetof (struct external_solaris_bcp_core, fp_stuff); /* Ucode is the last thing in the struct -- just before the end */ intcore->c_ucode = H_GET_32 (abfd, (intcore->c_len @@ -527,7 +527,7 @@ swapcore_solaris_bcp (bfd *abfd, char *ext, struct internal_sunos_core *intcore) #define SPARC_USRSTACK_SPARC2 ((bfd_vma)0xf8000000) #define SPARC_USRSTACK_SPARC10 ((bfd_vma)0xf0000000) { - bfd_vma sp = H_GET_32 (abfd, &((struct regs *) &extcore->c_regs[0])->r_o6); + bfd_vma sp = H_GET_32 (abfd, &extcore->c_regs.r_o6); if (sp < SPARC_USRSTACK_SPARC10) intcore->c_stacktop = SPARC_USRSTACK_SPARC10; else diff --git a/bfd/aoutx.h b/bfd/aoutx.h index 7dce072..663d49d 100644 --- a/bfd/aoutx.h +++ b/bfd/aoutx.h @@ -1193,26 +1193,21 @@ NAME (aout, new_section_hook) (bfd *abfd, asection *newsect) { obj_textsec (abfd)= newsect; newsect->target_index = N_TEXT; - return TRUE; } - - if (obj_datasec (abfd) == NULL && !strcmp (newsect->name, ".data")) + else if (obj_datasec (abfd) == NULL && !strcmp (newsect->name, ".data")) { obj_datasec (abfd) = newsect; newsect->target_index = N_DATA; - return TRUE; } - - if (obj_bsssec (abfd) == NULL && !strcmp (newsect->name, ".bss")) + else if (obj_bsssec (abfd) == NULL && !strcmp (newsect->name, ".bss")) { obj_bsssec (abfd) = newsect; newsect->target_index = N_BSS; - return TRUE; } } /* We allow more than three sections internally. */ - return TRUE; + return _bfd_generic_new_section_hook (abfd, newsect); } bfd_boolean diff --git a/bfd/archive.c b/bfd/archive.c index 5a12f01..d6930fb 100644 --- a/bfd/archive.c +++ b/bfd/archive.c @@ -666,10 +666,7 @@ bfd_generic_archive_p (bfd *abfd) first = bfd_openr_next_archived_file (abfd, NULL); if (first != NULL) { - bfd_boolean fail; - first->target_defaulted = FALSE; - fail = FALSE; if (bfd_check_format (first, bfd_object) && first->xvec != abfd->xvec) { diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index 9daa578..5c2f05d 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -376,6 +376,8 @@ struct bfd_hash_table struct bfd_hash_entry **table; /* The number of slots in the hash table. */ unsigned int size; + /* The number of entries in the hash table. */ + unsigned int count; /* The size of elements. */ unsigned int entsize; /* A function used to create new elements in the hash table. The diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 63fb521..5ba74d2 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -383,6 +383,8 @@ struct bfd_hash_table struct bfd_hash_entry **table; /* The number of slots in the hash table. */ unsigned int size; + /* The number of entries in the hash table. */ + unsigned int count; /* The size of elements. */ unsigned int entsize; /* A function used to create new elements in the hash table. The @@ -1465,11 +1467,6 @@ extern asection bfd_ind_section; || ((SEC) == bfd_com_section_ptr) \ || ((SEC) == bfd_ind_section_ptr)) -extern const struct bfd_symbol * const bfd_abs_symbol; -extern const struct bfd_symbol * const bfd_com_symbol; -extern const struct bfd_symbol * const bfd_und_symbol; -extern const struct bfd_symbol * const bfd_ind_symbol; - /* Macros to handle insertion and deletion of a bfd's sections. These only handle the list pointers, ie. do not adjust section_count, target_index etc. */ @@ -1560,7 +1557,7 @@ extern const struct bfd_symbol * const bfd_ind_symbol; #define bfd_section_removed_from_list(ABFD, S) \ ((S)->next == NULL ? (ABFD)->section_last != (S) : (S)->next->prev != (S)) -#define BFD_FAKE_SECTION(SEC, FLAGS, SYM, SYM_PTR, NAME, IDX) \ +#define BFD_FAKE_SECTION(SEC, FLAGS, SYM, NAME, IDX) \ /* name, id, index, next, prev, flags, user_set_vma, */ \ { NAME, IDX, 0, NULL, NULL, FLAGS, 0, \ \ @@ -1591,11 +1588,8 @@ extern const struct bfd_symbol * const bfd_ind_symbol; /* target_index, used_by_bfd, constructor_chain, owner, */ \ 0, NULL, NULL, NULL, \ \ - /* symbol, */ \ - (struct bfd_symbol *) SYM, \ - \ - /* symbol_ptr_ptr, */ \ - (struct bfd_symbol **) SYM_PTR, \ + /* symbol, symbol_ptr_ptr, */ \ + (struct bfd_symbol *) SYM, &SEC.symbol, \ \ /* map_head, map_tail */ \ { NULL }, { NULL } \ @@ -2903,6 +2897,16 @@ pc-relative or some form of GOT-indirect relocation. */ /* 31-bit PC relative address. */ BFD_RELOC_ARM_PREL31, +/* Low and High halfword relocations for MOVW and MOVT instructions. */ + BFD_RELOC_ARM_MOVW, + BFD_RELOC_ARM_MOVT, + BFD_RELOC_ARM_MOVW_PCREL, + BFD_RELOC_ARM_MOVT_PCREL, + BFD_RELOC_ARM_THUMB_MOVW, + BFD_RELOC_ARM_THUMB_MOVT, + BFD_RELOC_ARM_THUMB_MOVW_PCREL, + BFD_RELOC_ARM_THUMB_MOVT_PCREL, + /* Relocations for setting up GOTs and PLTs for shared libraries. */ BFD_RELOC_ARM_JUMP_SLOT, BFD_RELOC_ARM_GLOB_DAT, diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c index 6b83dc7..c5b4765 100644 --- a/bfd/coff-arm.c +++ b/bfd/coff-arm.c @@ -220,7 +220,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] = complain_overflow_dont, aoutarm_fix_pcrel_26_done, "ARM_26D", - FALSE, + TRUE, /* partial_inplace. */ 0x00ffffff, 0x0, PCRELOFFSET), @@ -233,7 +233,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] = complain_overflow_bitfield, coff_arm_reloc, "ARM_32", - FALSE, + TRUE, /* partial_inplace. */ 0xffffffff, 0xffffffff, PCRELOFFSET), @@ -246,7 +246,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] = complain_overflow_bitfield, coff_arm_reloc, "ARM_RVA32", - FALSE, + TRUE, /* partial_inplace. */ 0xffffffff, 0xffffffff, PCRELOFFSET), @@ -294,7 +294,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] = complain_overflow_bitfield, coff_arm_reloc, "ARM_SECTION", - FALSE, + TRUE, /* partial_inplace. */ 0x0000ffff, 0x0000ffff, PCRELOFFSET), @@ -307,7 +307,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] = complain_overflow_bitfield, coff_arm_reloc, "ARM_SECREL", - FALSE, + TRUE, /* partial_inplace. */ 0xffffffff, 0xffffffff, PCRELOFFSET), @@ -1209,12 +1209,14 @@ coff_arm_relocate_section (bfd *output_bfd, generation of bl's instruction offset. */ addend -= 8; #endif - howto = &fake_arm26_reloc; + howto = & fake_arm26_reloc; } #ifdef ARM_WINCE /* MS ARM-CE makes the reloc relative to the opcode's pc, not the next opcode's pc, so is off by one. */ + if (howto->pc_relative && !info->relocatable) + addend -= 8; #endif /* If we are doing a relocatable link, then we can just ignore diff --git a/bfd/coff-or32.c b/bfd/coff-or32.c index c8f0fe0..dc4114b 100644 --- a/bfd/coff-or32.c +++ b/bfd/coff-or32.c @@ -317,11 +317,7 @@ reloc_processing (relent,reloc, symbols, abfd, section) } else { - asymbol *ptr; relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx]; - - ptr = *(relent->sym_ptr_ptr); - relent->addend = 0; relent->address-= section->vma; diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c index 220edf8..951587f 100644 --- a/bfd/coff-rs6000.c +++ b/bfd/coff-rs6000.c @@ -1,5 +1,5 @@ /* BFD back-end for IBM RS/6000 "XCOFF" files. - Copyright 1990-1999, 2000, 2001, 2002, 2003, 2004, 2005 + Copyright 1990-1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. FIXME: Can someone provide a transliteration of this name into ASCII? Using the following chars caused a compiler warning on HIUX (so I replaced @@ -2083,7 +2083,7 @@ xcoff_write_archive_contents_old (abfd) char decbuf[XCOFFARMAG_ELEMENT_SIZE + 1]; memset (&fhdr, 0, sizeof fhdr); - strncpy (fhdr.magic, XCOFFARMAG, SXCOFFARMAG); + (void) strncpy (fhdr.magic, XCOFFARMAG, SXCOFFARMAG); sprintf (fhdr.firstmemoff, "%d", SIZEOF_AR_FILE_HDR); sprintf (fhdr.freeoff, "%d", 0); diff --git a/bfd/coff-w65.c b/bfd/coff-w65.c index 7a1cfb7..e4e304b 100644 --- a/bfd/coff-w65.c +++ b/bfd/coff-w65.c @@ -1,6 +1,6 @@ /* BFD back-end for WDC 65816 COFF binaries. - Copyright 1995, 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005 - Free Software Foundation, Inc. + Copyright 1995, 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + 2006 Free Software Foundation, Inc. Written by Steve Chamberlain, <sac@cygnus.com>. This file is part of BFD, the Binary File Descriptor library. @@ -105,7 +105,7 @@ reloc_processing (relent, reloc, symbols, abfd, section) if (((int) reloc->r_symndx) > 0) relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx]; else - relent->sym_ptr_ptr = (asymbol **)&(bfd_abs_symbol); + relent->sym_ptr_ptr = (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr; relent->addend = reloc->r_offset; diff --git a/bfd/coffcode.h b/bfd/coffcode.h index aaf79c1..badb214 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -1,6 +1,6 @@ /* Support for the generic parts of most COFF variants, for BFD. Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005 + 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. Written by Cygnus Support. @@ -1560,6 +1560,10 @@ coff_new_section_hook (bfd * abfd, asection * section) section->alignment_power = bfd_xcoff_data_align_power (abfd); #endif + /* Set up the section symbol. */ + if (!_bfd_generic_new_section_hook (abfd, section)) + return FALSE; + /* Allocate aux records for section symbols, to store size and related info. @@ -2528,11 +2532,15 @@ coff_write_relocs (bfd * abfd, int first_undef) else { n.r_symndx = get_index ((*(q->sym_ptr_ptr))); - /* Take notice if the symbol reloc points to a symbol - we don't have in our symbol table. What should we - do for this?? */ + /* Check to see if the symbol reloc points to a symbol + we don't have in our symbol table. */ if (n.r_symndx > obj_conv_table_size (abfd)) - abort (); + { + bfd_set_error (bfd_error_bad_value); + _bfd_error_handler (_("%B: reloc against a non-existant symbol index: %ld"), + abfd, n.r_symndx); + return FALSE; + } } } diff --git a/bfd/cofflink.c b/bfd/cofflink.c index a1f6684..c17701c 100644 --- a/bfd/cofflink.c +++ b/bfd/cofflink.c @@ -1239,9 +1239,7 @@ process_embedded_commands (bfd *output_bfd, asection *asec; int loop = 1; int had_write = 0; - int had_read = 0; int had_exec= 0; - int had_shared= 0; s += 5; s = get_name (s, &name); @@ -1255,10 +1253,8 @@ process_embedded_commands (bfd *output_bfd, had_write = 1; break; case 'R': - had_read = 1; break; case 'S': - had_shared = 1; break; case 'X': had_exec = 1; diff --git a/bfd/cpu-arm.c b/bfd/cpu-arm.c index a28a1f9..0f0da06 100644 --- a/bfd/cpu-arm.c +++ b/bfd/cpu-arm.c @@ -405,11 +405,11 @@ bfd_boolean bfd_is_arm_mapping_symbol_name (const char * name) { /* The ARM compiler outputs several obsolete forms. Recognize them - in addition to the standard $a, $t and $d. */ + in addition to the standard $a, $t and $d. We are somewhat loose + in what we accept here, since the full set is not documented. */ return (name != NULL) && (name[0] == '$') - && ((name[1] == 'a') || (name[1] == 't') || (name[1] == 'd') - || (name[1] == 'm') || (name[1] == 'f') || (name[1] == 'p')) + && (name[1] >= 'a' && name[1] <= 'z') && (name[2] == 0 || name[2] == '.'); } diff --git a/bfd/doc/ChangeLog b/bfd/doc/ChangeLog index d00fd99..de91f67 100644 --- a/bfd/doc/ChangeLog +++ b/bfd/doc/ChangeLog @@ -1,3 +1,7 @@ +2006-05-11 Carlos O'Donell <carlos@codesourcery.com> + + * bfd.texinfo: Rename "Index" to "BFD Index" + 2006-04-06 Carlos O'Donell <carlos@codesourcery.com> * Makefile.am: Add install-html and install-html-am targets. diff --git a/bfd/doc/bfd.texinfo b/bfd/doc/bfd.texinfo index 94dd23a..975a6ed 100644 --- a/bfd/doc/bfd.texinfo +++ b/bfd/doc/bfd.texinfo @@ -98,7 +98,7 @@ This file documents the binary file descriptor library libbfd. * BFD front end:: BFD front end * BFD back ends:: BFD back ends * GNU Free Documentation License:: GNU Free Documentation License -* Index:: Index +* BFD Index:: BFD Index @end menu @node Overview, BFD front end, Top, Top @@ -324,11 +324,11 @@ All of BFD lives in one directory. @node mmo, , elf, BFD back ends @include mmo.texi -@node GNU Free Documentation License, Index, BFD back ends, Top +@node GNU Free Documentation License, BFD Index, BFD back ends, Top @include fdl.texi -@node Index, , GNU Free Documentation License, Top -@unnumbered Index +@node BFD Index, , GNU Free Documentation License, Top +@unnumbered BFD Index @printindex cp @tex diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c index ae68d18..b55f2fa 100644 --- a/bfd/dwarf2.c +++ b/bfd/dwarf2.c @@ -1117,7 +1117,6 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash) unsigned int line = 1; unsigned int column = 0; int is_stmt = lh.default_is_stmt; - int basic_block = 0; int end_sequence = 0; /* eraxxon@alumni.rice.edu: Against the DWARF2 specs, some compilers generate address sequences that are wildly out of @@ -1142,7 +1141,6 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash) line += lh.line_base + (adj_opcode % lh.line_range); /* Append row to matrix using current values. */ add_line_info (table, address, filename, line, column, 0); - basic_block = 1; if (address < low_pc) low_pc = address; if (address > high_pc) @@ -1214,7 +1212,6 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash) break; case DW_LNS_copy: add_line_info (table, address, filename, line, column, 0); - basic_block = 0; if (address < low_pc) low_pc = address; if (address > high_pc) @@ -1250,7 +1247,6 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash) is_stmt = (!is_stmt); break; case DW_LNS_set_basic_block: - basic_block = 1; break; case DW_LNS_const_add_pc: address += lh.minimum_instruction_length @@ -1625,7 +1621,7 @@ read_rangelist (struct comp_unit *unit, struct arange *arange, bfd_uint64_t offs if (low_pc == -1UL && high_pc != -1UL) base_address = high_pc; else - arange_add (unit->abfd, arange, base_address + low_pc, base_address + high_pc); + arange_add (unit->abfd, arange, base_address + low_pc, base_address + high_pc); } } diff --git a/bfd/ecoff.c b/bfd/ecoff.c index 75e1cc2..0416c23 100644 --- a/bfd/ecoff.c +++ b/bfd/ecoff.c @@ -140,8 +140,7 @@ _bfd_ecoff_mkobject_hook (bfd *abfd, void * filehdr, void * aouthdr) /* Initialize a new section. */ bfd_boolean -_bfd_ecoff_new_section_hook (bfd *abfd ATTRIBUTE_UNUSED, - asection *section) +_bfd_ecoff_new_section_hook (bfd *abfd, asection *section) { unsigned int i; static struct @@ -181,7 +180,7 @@ _bfd_ecoff_new_section_hook (bfd *abfd ATTRIBUTE_UNUSED, uncertain about .init on some systems and I don't know how shared libraries work. */ - return TRUE; + return _bfd_generic_new_section_hook (abfd, section); } /* Determine the machine architecture and type. This is called from diff --git a/bfd/ecofflink.c b/bfd/ecofflink.c index 4246e94..d3d79b4 100644 --- a/bfd/ecofflink.c +++ b/bfd/ecofflink.c @@ -782,7 +782,6 @@ bfd_ecoff_debug_accumulate (handle, output_bfd, output_debug, output_swap, fdr_ptr += fdr_add, i++) { FDR fdr; - bfd_vma fdr_adr; bfd_byte *sym_out; bfd_byte *lraw_src; bfd_byte *lraw_end; @@ -799,8 +798,6 @@ bfd_ecoff_debug_accumulate (handle, output_bfd, output_debug, output_swap, else (*input_swap->swap_fdr_in) (input_bfd, (PTR) fdr_ptr, &fdr); - fdr_adr = fdr.adr; - /* FIXME: It is conceivable that this FDR points to the .init or .fini section, in which case this will not do the right thing. */ diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c index ab0b995..4f9ed4a 100644 --- a/bfd/elf-eh-frame.c +++ b/bfd/elf-eh-frame.c @@ -390,8 +390,7 @@ _bfd_elf_discard_section_eh_frame return FALSE; } - if ((sec->output_section != NULL - && bfd_is_abs_section (sec->output_section))) + if (bfd_is_abs_section (sec->output_section)) { /* At least one of the sections is being discarded from the link, so we should just ignore them. */ @@ -2113,13 +2113,11 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex) elf_dynversym (abfd) = shindex; elf_tdata (abfd)->dynversym_hdr = *hdr; return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); - break; case SHT_GNU_verneed: elf_dynverref (abfd) = shindex; elf_tdata (abfd)->dynverref_hdr = *hdr; return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); - break; case SHT_SHLIB: return TRUE; @@ -2159,8 +2157,43 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex) default: /* Check for any processor-specific section types. */ - return bed->elf_backend_section_from_shdr (abfd, hdr, name, - shindex); + if (bed->elf_backend_section_from_shdr (abfd, hdr, name, shindex)) + return TRUE; + + if (hdr->sh_type >= SHT_LOUSER && hdr->sh_type <= SHT_HIUSER) + { + if ((hdr->sh_flags & SHF_ALLOC) != 0) + /* FIXME: How to properly handle allocated section reserved + for applications? */ + (*_bfd_error_handler) + (_("%B: don't know how to handle allocated, application " + "specific section `%s' [0x%8x]"), + abfd, name, hdr->sh_type); + else + /* Allow sections reserved for applications. */ + return _bfd_elf_make_section_from_shdr (abfd, hdr, name, + shindex); + } + else if (hdr->sh_type >= SHT_LOPROC + && hdr->sh_type <= SHT_HIPROC) + /* FIXME: We should handle this section. */ + (*_bfd_error_handler) + (_("%B: don't know how to handle processor specific section " + "`%s' [0x%8x]"), + abfd, name, hdr->sh_type); + else if (hdr->sh_type >= SHT_LOOS && hdr->sh_type <= SHT_HIOS) + /* FIXME: We should handle this section. */ + (*_bfd_error_handler) + (_("%B: don't know how to handle OS specific section " + "`%s' [0x%8x]"), + abfd, name, hdr->sh_type); + else + /* FIXME: We should handle this section. */ + (*_bfd_error_handler) + (_("%B: don't know how to handle section `%s' [0x%8x]"), + abfd, name, hdr->sh_type); + + return FALSE; } return TRUE; @@ -2452,10 +2485,13 @@ _bfd_elf_new_section_hook (bfd *abfd, asection *sec) bed = get_elf_backend_data (abfd); sec->use_rela_p = bed->default_use_rela_p; - /* When we read a file, we don't need section type and flags unless - it is a linker created section. They will be overridden in - _bfd_elf_make_section_from_shdr anyway. */ - if (abfd->direction != read_direction + /* When we read a file, we don't need to set ELF section type and + flags. They will be overridden in _bfd_elf_make_section_from_shdr + anyway. We will set ELF section type and flags for all linker + created sections. If user specifies BFD section flags, we will + set ELF section type and flags based on BFD section flags in + elf_fake_sections. */ + if ((!sec->flags && abfd->direction != read_direction) || (sec->flags & SEC_LINKER_CREATED) != 0) { ssect = (*bed->get_sec_type_attr) (abfd, sec); @@ -2466,7 +2502,7 @@ _bfd_elf_new_section_hook (bfd *abfd, asection *sec) } } - return TRUE; + return _bfd_generic_new_section_hook (abfd, sec); } /* Create a new bfd section from an ELF program header. @@ -4084,6 +4120,10 @@ assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info) bfd_vma filehdr_vaddr, filehdr_paddr; bfd_vma phdrs_vaddr, phdrs_paddr; Elf_Internal_Phdr *p; + Elf_Internal_Shdr **i_shdrpp; + Elf_Internal_Shdr **hdrpp; + unsigned int i; + unsigned int num_sec; if (elf_tdata (abfd)->segment_map == NULL) { @@ -4101,7 +4141,6 @@ assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info) m = m->next) { unsigned int new_count; - unsigned int i; new_count = 0; for (i = 0; i < m->count; i ++) @@ -4175,7 +4214,6 @@ assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info) m != NULL; m = m->next, p++) { - unsigned int i; asection **secpp; /* If elf_segment_map is not from map_sections_to_segments, the @@ -4500,6 +4538,51 @@ assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info) } } + /* Assign file positions for the other sections. */ + i_shdrpp = elf_elfsections (abfd); + num_sec = elf_numsections (abfd); + for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++) + { + struct elf_obj_tdata *tdata = elf_tdata (abfd); + Elf_Internal_Shdr *hdr; + + hdr = *hdrpp; + if (hdr->bfd_section != NULL + && hdr->bfd_section->filepos != 0) + hdr->sh_offset = hdr->bfd_section->filepos; + else if ((hdr->sh_flags & SHF_ALLOC) != 0) + { + ((*_bfd_error_handler) + (_("%B: warning: allocated section `%s' not in segment"), + abfd, + (hdr->bfd_section == NULL + ? "*unknown*" + : hdr->bfd_section->name))); + if ((abfd->flags & D_PAGED) != 0) + off += vma_page_aligned_bias (hdr->sh_addr, off, + bed->maxpagesize); + else + off += vma_page_aligned_bias (hdr->sh_addr, off, + hdr->sh_addralign); + off = _bfd_elf_assign_file_position_for_section (hdr, off, + FALSE); + } + else if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA) + && hdr->bfd_section == NULL) + || hdr == i_shdrpp[tdata->symtab_section] + || hdr == i_shdrpp[tdata->symtab_shndx_section] + || hdr == i_shdrpp[tdata->strtab_section]) + hdr->sh_offset = -1; + else + off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE); + + if (i == SHN_LORESERVE - 1) + { + i += SHN_HIRESERVE + 1 - SHN_LORESERVE; + hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE; + } + } + /* Now that we have set the section file positions, we can set up the file positions for the non PT_LOAD segments. */ for (m = elf_tdata (abfd)->segment_map, p = phdrs; @@ -4515,7 +4598,6 @@ assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info) PT_LOAD segment, so it will not be processed above. */ if (p->p_type == PT_DYNAMIC && m->sections[0]->filepos == 0) { - unsigned int i; Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd); i = 1; @@ -4718,16 +4800,16 @@ static bfd_boolean assign_file_positions_except_relocs (bfd *abfd, struct bfd_link_info *link_info) { - struct elf_obj_tdata * const tdata = elf_tdata (abfd); - Elf_Internal_Ehdr * const i_ehdrp = elf_elfheader (abfd); - Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd); - unsigned int num_sec = elf_numsections (abfd); + struct elf_obj_tdata *tdata = elf_tdata (abfd); + Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd); file_ptr off; const struct elf_backend_data *bed = get_elf_backend_data (abfd); if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 && bfd_get_format (abfd) != bfd_core) { + Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd); + unsigned int num_sec = elf_numsections (abfd); Elf_Internal_Shdr **hdrpp; unsigned int i; @@ -4762,57 +4844,12 @@ assign_file_positions_except_relocs (bfd *abfd, } else { - unsigned int i; - Elf_Internal_Shdr **hdrpp; - /* Assign file positions for the loaded sections based on the assignment of sections to segments. */ if (! assign_file_positions_for_segments (abfd, link_info)) return FALSE; - /* Assign file positions for the other sections. */ - - off = elf_tdata (abfd)->next_file_pos; - for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++) - { - Elf_Internal_Shdr *hdr; - - hdr = *hdrpp; - if (hdr->bfd_section != NULL - && hdr->bfd_section->filepos != 0) - hdr->sh_offset = hdr->bfd_section->filepos; - else if ((hdr->sh_flags & SHF_ALLOC) != 0) - { - ((*_bfd_error_handler) - (_("%B: warning: allocated section `%s' not in segment"), - abfd, - (hdr->bfd_section == NULL - ? "*unknown*" - : hdr->bfd_section->name))); - if ((abfd->flags & D_PAGED) != 0) - off += vma_page_aligned_bias (hdr->sh_addr, off, - bed->maxpagesize); - else - off += vma_page_aligned_bias (hdr->sh_addr, off, - hdr->sh_addralign); - off = _bfd_elf_assign_file_position_for_section (hdr, off, - FALSE); - } - else if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA) - && hdr->bfd_section == NULL) - || hdr == i_shdrpp[tdata->symtab_section] - || hdr == i_shdrpp[tdata->symtab_shndx_section] - || hdr == i_shdrpp[tdata->strtab_section]) - hdr->sh_offset = -1; - else - off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE); - - if (i == SHN_LORESERVE - 1) - { - i += SHN_HIRESERVE + 1 - SHN_LORESERVE; - hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE; - } - } + off = tdata->next_file_pos; } /* Place the section headers. */ @@ -4820,7 +4857,7 @@ assign_file_positions_except_relocs (bfd *abfd, i_ehdrp->e_shoff = off; off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize; - elf_tdata (abfd)->next_file_pos = off; + tdata->next_file_pos = off; return TRUE; } @@ -5870,9 +5907,12 @@ _bfd_elf_init_private_section_data (bfd *ibfd, || obfd->xvec->flavour != bfd_target_elf_flavour) return TRUE; - /* FIXME: What if the output ELF section type has been set to - something different? */ - if (elf_section_type (osec) == SHT_NULL) + /* Don't copy the output ELF section type from input if the + output BFD section flags has been set to something different. + elf_fake_sections will set ELF section type based on BFD + section flags. */ + if (osec->flags == isec->flags + || (osec->flags == 0 && elf_section_type (osec) == SHT_NULL)) elf_section_type (osec) = elf_section_type (isec); /* Set things up for objcopy and relocatable link. The output @@ -7171,7 +7211,7 @@ _bfd_elf_close_and_cleanup (bfd *abfd) { if (bfd_get_format (abfd) == bfd_object) { - if (elf_shstrtab (abfd) != NULL) + if (elf_tdata (abfd) != NULL && elf_shstrtab (abfd) != NULL) _bfd_elf_strtab_free (elf_shstrtab (abfd)); _bfd_dwarf2_cleanup_debug_info (abfd); } @@ -8721,8 +8761,7 @@ done: /* It is only used by x86-64 so far. */ asection _bfd_elf_large_com_section = BFD_FAKE_SECTION (_bfd_elf_large_com_section, - SEC_IS_COMMON, NULL, NULL, "LARGE_COMMON", - 0); + SEC_IS_COMMON, NULL, "LARGE_COMMON", 0); /* Return TRUE if 2 section types are compatible. */ diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index ca33121..e0a5abe 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -1366,6 +1366,14 @@ static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] = {BFD_RELOC_ARM_TLS_LE32, R_ARM_TLS_LE32}, {BFD_RELOC_VTABLE_INHERIT, R_ARM_GNU_VTINHERIT}, {BFD_RELOC_VTABLE_ENTRY, R_ARM_GNU_VTENTRY}, + {BFD_RELOC_ARM_MOVW, R_ARM_MOVW_ABS_NC}, + {BFD_RELOC_ARM_MOVT, R_ARM_MOVT_ABS}, + {BFD_RELOC_ARM_MOVW_PCREL, R_ARM_MOVW_PREL_NC}, + {BFD_RELOC_ARM_MOVT_PCREL, R_ARM_MOVT_PREL}, + {BFD_RELOC_ARM_THUMB_MOVW, R_ARM_THM_MOVW_ABS_NC}, + {BFD_RELOC_ARM_THUMB_MOVT, R_ARM_THM_MOVT_ABS}, + {BFD_RELOC_ARM_THUMB_MOVW_PCREL, R_ARM_THM_MOVW_PREL_NC}, + {BFD_RELOC_ARM_THUMB_MOVT_PCREL, R_ARM_THM_MOVT_PREL}, }; static reloc_howto_type * @@ -3274,9 +3282,11 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, break; case R_ARM_REL32: + value += addend; + if (sym_flags == STT_ARM_TFUNC) + value |= 1; value -= (input_section->output_section->vma + input_section->output_offset + rel->r_offset); - value += addend; break; case R_ARM_PREL31: @@ -4078,6 +4088,76 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, } return bfd_reloc_ok; + case R_ARM_MOVW_ABS_NC: + case R_ARM_MOVT_ABS: + case R_ARM_MOVW_PREL_NC: + case R_ARM_MOVT_PREL: + { + bfd_vma insn = bfd_get_32 (input_bfd, hit_data); + + if (globals->use_rel) + { + addend = ((insn >> 4) & 0xf000) | (insn & 0xfff); + signed_addend = (addend ^ 0x10000) - 0x10000; + } + value += signed_addend; + if (sym_flags == STT_ARM_TFUNC) + value |= 1; + + if (r_type == R_ARM_MOVW_PREL_NC || r_type == R_ARM_MOVT_PREL) + value -= (input_section->output_section->vma + + input_section->output_offset + rel->r_offset); + + if (r_type == R_ARM_MOVT_ABS || r_type == R_ARM_MOVT_PREL) + value >>= 16; + + insn &= 0xfff0f000; + insn |= value & 0xfff; + insn |= (value & 0xf000) << 4; + bfd_put_32 (input_bfd, insn, hit_data); + } + return bfd_reloc_ok; + + case R_ARM_THM_MOVW_ABS_NC: + case R_ARM_THM_MOVT_ABS: + case R_ARM_THM_MOVW_PREL_NC: + case R_ARM_THM_MOVT_PREL: + { + bfd_vma insn; + + insn = bfd_get_16 (input_bfd, hit_data) << 16; + insn |= bfd_get_16 (input_bfd, hit_data + 2); + + if (globals->use_rel) + { + addend = ((insn >> 4) & 0xf000) + | ((insn >> 15) & 0x0800) + | ((insn >> 4) & 0x0700) + | (insn & 0x00ff); + signed_addend = (addend ^ 0x10000) - 0x10000; + } + value += signed_addend; + if (sym_flags == STT_ARM_TFUNC) + value |= 1; + + if (r_type == R_ARM_THM_MOVW_PREL_NC || r_type == R_ARM_THM_MOVT_PREL) + value -= (input_section->output_section->vma + + input_section->output_offset + rel->r_offset); + + if (r_type == R_ARM_THM_MOVT_ABS || r_type == R_ARM_THM_MOVT_PREL) + value >>= 16; + + insn &= 0xfbf08f00; + insn |= (value & 0xf000) << 4; + insn |= (value & 0x0800) << 15; + insn |= (value & 0x0700) << 4; + insn |= (value & 0x00ff); + + bfd_put_16 (input_bfd, insn >> 16, hit_data); + bfd_put_16 (input_bfd, insn & 0xffff, hit_data + 2); + } + return bfd_reloc_ok; + default: return bfd_reloc_notsupported; } @@ -5649,6 +5729,14 @@ elf32_arm_gc_sweep_hook (bfd * abfd, case R_ARM_JUMP24: case R_ARM_PREL31: case R_ARM_THM_CALL: + case R_ARM_MOVW_ABS_NC: + case R_ARM_MOVT_ABS: + case R_ARM_MOVW_PREL_NC: + case R_ARM_MOVT_PREL: + case R_ARM_THM_MOVW_ABS_NC: + case R_ARM_THM_MOVT_ABS: + case R_ARM_THM_MOVW_PREL_NC: + case R_ARM_THM_MOVT_PREL: /* Should the interworking branches be here also? */ if (h != NULL) @@ -5859,6 +5947,14 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_ARM_JUMP24: case R_ARM_PREL31: case R_ARM_THM_CALL: + case R_ARM_MOVW_ABS_NC: + case R_ARM_MOVT_ABS: + case R_ARM_MOVW_PREL_NC: + case R_ARM_MOVT_PREL: + case R_ARM_THM_MOVW_ABS_NC: + case R_ARM_THM_MOVT_ABS: + case R_ARM_THM_MOVW_PREL_NC: + case R_ARM_THM_MOVT_PREL: /* Should the interworking branches be listed here? */ if (h != NULL) { @@ -5875,12 +5971,7 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info, refers to is in a different object. We can't tell for sure yet, because something later might force the symbol local. */ - if (r_type == R_ARM_PC24 - || r_type == R_ARM_CALL - || r_type == R_ARM_JUMP24 - || r_type == R_ARM_PREL31 - || r_type == R_ARM_PLT32 - || r_type == R_ARM_THM_CALL) + if (r_type != R_ARM_ABS32 && r_type != R_ARM_REL32) h->needs_plt = 1; /* If we create a PLT entry, this relocation will reference @@ -7820,13 +7911,16 @@ elf32_arm_output_symbol_hook (struct bfd_link_info *info, static bfd_boolean elf32_arm_new_section_hook (bfd *abfd, asection *sec) { - _arm_elf_section_data *sdata; - bfd_size_type amt = sizeof (*sdata); + if (!sec->used_by_bfd) + { + _arm_elf_section_data *sdata; + bfd_size_type amt = sizeof (*sdata); - sdata = bfd_zalloc (abfd, amt); - if (sdata == NULL) - return FALSE; - sec->used_by_bfd = sdata; + sdata = bfd_zalloc (abfd, amt); + if (sdata == NULL) + return FALSE; + sec->used_by_bfd = sdata; + } record_section_with_arm_elf_section_data (sec); @@ -7936,11 +8030,25 @@ unrecord_section_via_map_over_sections (bfd * abfd ATTRIBUTE_UNUSED, static bfd_boolean elf32_arm_close_and_cleanup (bfd * abfd) { - bfd_map_over_sections (abfd, unrecord_section_via_map_over_sections, NULL); + if (abfd->sections) + bfd_map_over_sections (abfd, + unrecord_section_via_map_over_sections, + NULL); return _bfd_elf_close_and_cleanup (abfd); } +static bfd_boolean +elf32_arm_bfd_free_cached_info (bfd * abfd) +{ + if (abfd->sections) + bfd_map_over_sections (abfd, + unrecord_section_via_map_over_sections, + NULL); + + return _bfd_free_cached_info (abfd); +} + /* Display STT_ARM_TFUNC symbols as functions. */ static void @@ -8100,6 +8208,7 @@ const struct elf_size_info elf32_arm_size_info = { #define bfd_elf32_new_section_hook elf32_arm_new_section_hook #define bfd_elf32_bfd_is_target_special_symbol elf32_arm_is_target_special_symbol #define bfd_elf32_close_and_cleanup elf32_arm_close_and_cleanup +#define bfd_elf32_bfd_free_cached_info elf32_arm_bfd_free_cached_info #define bfd_elf32_bfd_final_link elf32_arm_bfd_final_link #define elf_backend_get_symbol_type elf32_arm_get_symbol_type diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c index ec42bb3..e5f09c6 100644 --- a/bfd/elf32-avr.c +++ b/bfd/elf32-avr.c @@ -433,6 +433,7 @@ struct avr_reloc_map unsigned int avr_pc_wrap_around = 0x10000000; /* Calculates the effective distance of a pc relative jump/call. */ + static int avr_relative_distance_considering_wrap_around (unsigned int distance) { @@ -455,10 +456,8 @@ bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, for (i = 0; i < sizeof (avr_reloc_map) / sizeof (struct avr_reloc_map); i++) - { - if (avr_reloc_map[i].bfd_reloc_val == code) - return &elf_avr_howto_table[avr_reloc_map[i].elf_reloc_val]; - } + if (avr_reloc_map[i].bfd_reloc_val == code) + return &elf_avr_howto_table[avr_reloc_map[i].elf_reloc_val]; return NULL; } @@ -1049,9 +1048,9 @@ elf32_avr_object_p (bfd *abfd) static bfd_boolean elf32_avr_relax_delete_bytes (bfd *abfd, - asection *sec, + asection *sec, bfd_vma addr, - int count) + int count) { Elf_Internal_Shdr *symtab_hdr; unsigned int sec_shndx; @@ -1085,10 +1084,9 @@ elf32_avr_relax_delete_bytes (bfd *abfd, (size_t) (toaddr - addr - count)); sec->size -= count; - /* Adjust all the relocs. */ + /* Adjust all the reloc addresses. */ for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++) { - bfd_vma symval; bfd_vma old_reloc_address; bfd_vma shrinked_insn_address; @@ -1111,69 +1109,91 @@ elf32_avr_relax_delete_bytes (bfd *abfd, irel->r_offset -= count; } - /* The reloc's own addresses are now ok. However, we need to readjust - the reloc's addend if two conditions are met: - 1.) the reloc is relative to a symbol in this section that - is located in front of the shrinked instruction - 2.) symbol plus addend end up behind the shrinked instruction. - - This should happen only for local symbols that are progmem related. */ - - /* Read this BFD's local symbols if we haven't done so already. */ - if (isymbuf == NULL && symtab_hdr->sh_info != 0) - { - isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; - if (isymbuf == NULL) - isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, - symtab_hdr->sh_info, 0, - NULL, NULL, NULL); - if (isymbuf == NULL) - return FALSE; - } - - /* Get the value of the symbol referred to by the reloc. */ - if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) - { - /* A local symbol. */ - Elf_Internal_Sym *isym; - asection *sym_sec; + } - isym = isymbuf + ELF32_R_SYM (irel->r_info); - sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); - symval = isym->st_value; - /* If the reloc is absolute, it will not have - a symbol or section associated with it. */ - if (sym_sec) - { - symval += sym_sec->output_section->vma - + sym_sec->output_offset; - - if (DEBUG_RELAX) - printf ("Checking if the relocation's " - "addend needs corrections.\n" - "Address of anchor symbol: 0x%x \n" - "Address of relocation target: 0x%x \n" - "Address of relaxed insn: 0x%x \n", - (unsigned int) symval, - (unsigned int) (symval + irel->r_addend), - (unsigned int) shrinked_insn_address); - - if (symval <= shrinked_insn_address - && (symval + irel->r_addend) > shrinked_insn_address) - { - irel->r_addend -= count; + /* The reloc's own addresses are now ok. However, we need to readjust + the reloc's addend, i.e. the reloc's value if two conditions are met: + 1.) the reloc is relative to a symbol in this section that + is located in front of the shrinked instruction + 2.) symbol plus addend end up behind the shrinked instruction. + + The most common case where this happens are relocs relative to + the section-start symbol. + + This step needs to be done for all of the sections of the bfd. */ + + { + struct bfd_section *isec; + + for (isec = abfd->sections; isec; isec = isec->next) + { + bfd_vma symval; + bfd_vma shrinked_insn_address; + + shrinked_insn_address = (sec->output_section->vma + + sec->output_offset + addr - count); + + irelend = elf_section_data (isec)->relocs + isec->reloc_count; + for (irel = elf_section_data (isec)->relocs; + irel < irelend; + irel++) + { + /* Read this BFD's local symbols if we haven't done + so already. */ + if (isymbuf == NULL && symtab_hdr->sh_info != 0) + { + isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, + NULL, NULL, NULL); + if (isymbuf == NULL) + return FALSE; + } + + /* Get the value of the symbol referred to by the reloc. */ + if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) + { + /* A local symbol. */ + Elf_Internal_Sym *isym; + asection *sym_sec; + + isym = isymbuf + ELF32_R_SYM (irel->r_info); + sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); + symval = isym->st_value; + /* If the reloc is absolute, it will not have + a symbol or section associated with it. */ + if (sym_sec == sec) + { + symval += sym_sec->output_section->vma + + sym_sec->output_offset; if (DEBUG_RELAX) - printf ("Anchor symbol and relocation target bracket " - "shrinked insn address.\n" - "Need for new addend : 0x%x\n", - (unsigned int) irel->r_addend); + printf ("Checking if the relocation's " + "addend needs corrections.\n" + "Address of anchor symbol: 0x%x \n" + "Address of relocation target: 0x%x \n" + "Address of relaxed insn: 0x%x \n", + (unsigned int) symval, + (unsigned int) (symval + irel->r_addend), + (unsigned int) shrinked_insn_address); + + if (symval <= shrinked_insn_address + && (symval + irel->r_addend) > shrinked_insn_address) + { + irel->r_addend -= count; + + if (DEBUG_RELAX) + printf ("Relocation's addend needed to be fixed \n"); + } } - } - /* else ... Reference symbol is absolute. No adjustment needed. */ - } - /* else ... Reference symbol is extern. No need for adjusting the addend. */ - } + /* else...Reference symbol is absolute. No adjustment needed. */ + } + /* else...Reference symbol is extern. No need for adjusting + the addend. */ + } + } + } /* Adjust the local symbols defined in this section. */ isym = (Elf_Internal_Sym *) symtab_hdr->contents; diff --git a/bfd/elf32-dlx.c b/bfd/elf32-dlx.c index ae42baf..b1f6257 100644 --- a/bfd/elf32-dlx.c +++ b/bfd/elf32-dlx.c @@ -512,21 +512,15 @@ dlx_rtype_to_howto (unsigned int r_type) { case R_DLX_RELOC_16_PCREL: return & elf_dlx_gnu_rel16_s2; - break; case R_DLX_RELOC_26_PCREL: return & elf_dlx_gnu_rel26_s2; - break; case R_DLX_RELOC_16_HI: return & elf_dlx_reloc_16_hi; - break; case R_DLX_RELOC_16_LO: return & elf_dlx_reloc_16_lo; - break; - default: BFD_ASSERT (r_type < (unsigned int) R_DLX_max); return & dlx_elf_howto_table[r_type]; - break; } } diff --git a/bfd/elf32-i370.c b/bfd/elf32-i370.c index d9e6fbf..218aa23 100644 --- a/bfd/elf32-i370.c +++ b/bfd/elf32-i370.c @@ -1,6 +1,6 @@ /* i370-specific support for 32-bit ELF - Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005 - Free Software Foundation, Inc. + Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, + 2005, 2006 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support. Hacked by Linas Vepstas for i370 linas@linas.org @@ -567,7 +567,7 @@ i370_elf_adjust_dynindx (struct elf_link_hash_entry *h, void * cparg) #ifdef DEBUG fprintf (stderr, - "i370_elf_adjust_dynindx called, h->dynindx = %d, *cp = %d\n", + "i370_elf_adjust_dynindx called, h->dynindx = %ld, *cp = %d\n", h->dynindx, *cp); #endif @@ -1296,7 +1296,7 @@ i370_elf_relocate_section (bfd *output_bfd, #ifdef DEBUG if (indx <= 0) { - printf ("indx=%d section=%s flags=%08x name=%s\n", + printf ("indx=%ld section=%s flags=%08x name=%s\n", indx, osec->name, osec->flags, h->root.root.string); } diff --git a/bfd/elf32-m32c.c b/bfd/elf32-m32c.c index 5e9f3ab..4320461 100644 --- a/bfd/elf32-m32c.c +++ b/bfd/elf32-m32c.c @@ -40,7 +40,8 @@ static bfd_boolean m32c_elf_check_relocs (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *); static bfd_boolean m32c_elf_relax_delete_bytes (bfd *, asection *, bfd_vma, int); #ifdef DEBUG -static char * m32c_get_reloc (long reloc); +char * m32c_get_reloc (long reloc); +void dump_symtab (bfd *, void *, void *); #endif static bfd_boolean m32c_elf_relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info, bfd_boolean *again); @@ -936,7 +937,7 @@ m32c_elf_object_p (bfd *abfd) #ifdef DEBUG -static void +void dump_symtab (bfd * abfd, void *internal_syms, void *external_syms) { size_t locsymcount; @@ -977,7 +978,6 @@ dump_symtab (bfd * abfd, void *internal_syms, void *external_syms) { case STT_FUNC: st_info_str = "STT_FUNC"; case STT_SECTION: st_info_str = "STT_SECTION"; - case STT_SRELC: st_info_str = "STT_SRELC"; case STT_FILE: st_info_str = "STT_FILE"; case STT_OBJECT: st_info_str = "STT_OBJECT"; case STT_TLS: st_info_str = "STT_TLS"; @@ -1022,7 +1022,7 @@ dump_symtab (bfd * abfd, void *internal_syms, void *external_syms) free (external_syms); } -static char * +char * m32c_get_reloc (long reloc) { if (0 <= reloc && reloc < R_M32C_max) diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 6a2d517..9ee2bcd 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -6293,7 +6293,7 @@ ppc_elf_relocate_section (bfd *output_bfd, BFD_ASSERT (indx > 0); #ifdef DEBUG if (indx <= 0) - printf ("indx=%d section=%s flags=%08x name=%s\n", + printf ("indx=%ld section=%s flags=%08x name=%s\n", indx, osec->name, osec->flags, h->root.root.string); #endif diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c index eb8e172..9d7004e 100644 --- a/bfd/elf32-s390.c +++ b/bfd/elf32-s390.c @@ -2268,6 +2268,7 @@ invalid_tls_insn (input_bfd, input_section, rel) input_section, (long) rel->r_offset, howto->name); + bfd_set_error (bfd_error_bad_value); } /* Relocate a 390 ELF section. */ @@ -2982,16 +2983,44 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, unsigned int insn; insn = bfd_get_32 (input_bfd, contents + rel->r_offset); - if ((insn & 0xff000fff) != 0x4d000000) + if ((insn & 0xff000fff) != 0x4d000000 && + (insn & 0xffff0000) != 0xc0e50000) invalid_tls_insn (input_bfd, input_section, rel); if (!info->shared && (h == NULL || h->dynindx == -1)) - /* GD->LE transition. - bas %r14,0(%rx,%r13) -> bc 0,0 */ - insn = 0x47000000; + { + if ((insn & 0xff000000) == 0x4d000000) + { + /* GD->LE transition. + bas %r14,0(%rx,%r13) -> bc 0,0 */ + insn = 0x47000000; + } + else + { + /* GD->LE transition. + brasl %r14,_tls_get_addr@plt -> brcl 0,. */ + insn = 0xc0040000; + bfd_put_16 (output_bfd, 0x0000, + contents + rel->r_offset + 4); + } + } else - /* GD->IE transition. - bas %r14,0(%rx,%r13) -> l %r2,0(%r2,%r12) */ - insn = 0x5822c000; + { + if ((insn & 0xff000000) == 0x4d000000) + { + /* GD->IE transition. + bas %r14,0(%rx,%r13) -> l %r2,0(%r2,%r12) */ + insn = 0x5822c000; + } + else + { + /* GD->IE transition. + brasl %r14,__tls_get_addr@plt -> + l %r2,0(%r2,%r12) ; bcr 0,0 */ + insn = 0x5822c000; + bfd_put_16 (output_bfd, 0x0700, + contents + rel->r_offset + 4); + } + } bfd_put_32 (output_bfd, insn, contents + rel->r_offset); } else if (r_type == R_390_TLS_LDCALL) @@ -3001,11 +3030,23 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, unsigned int insn; insn = bfd_get_32 (input_bfd, contents + rel->r_offset); - if ((insn & 0xff000fff) != 0x4d000000) + if ((insn & 0xff000fff) != 0x4d000000 && + (insn & 0xffff0000) != 0xc0e50000) invalid_tls_insn (input_bfd, input_section, rel); - /* LD->LE transition. - bas %r14,0(%rx,%r13) -> bc 0,0 */ - insn = 0x47000000; + if ((insn & 0xff000000) == 0x4d000000) + { + /* LD->LE transition. + bas %r14,0(%rx,%r13) -> bc 0,0 */ + insn = 0x47000000; + } + else + { + /* LD->LE transition. + brasl %r14,__tls_get_addr@plt -> brcl 0,. */ + insn = 0xc0040000; + bfd_put_16 (output_bfd, 0x0000, + contents + rel->r_offset + 4); + } bfd_put_32 (output_bfd, insn, contents + rel->r_offset); } } diff --git a/bfd/elf32-sh-symbian.c b/bfd/elf32-sh-symbian.c index 477cf24..9ca0564 100644 --- a/bfd/elf32-sh-symbian.c +++ b/bfd/elf32-sh-symbian.c @@ -26,8 +26,8 @@ #include "elf32-sh.c" -//#define DEBUG 1 -#define DEBUG 0 +//#define SYMBIAN_DEBUG 1 +#define SYMBIAN_DEBUG 0 #define DIRECTIVE_HEADER "#<SYMEDIT>#\n" #define DIRECTIVE_IMPORT "IMPORT " @@ -36,7 +36,7 @@ /* Macro to advance 's' until either it reaches 'e' or the character pointed to by 's' is equal to 'c'. If 'e' is - reached and DEBUG is enabled then the error message 'm' + reached and SYMBIAN_DEBUG is enabled then the error message 'm' is displayed. */ #define SKIP_UNTIL(s,e,c,m) \ do \ @@ -45,7 +45,7 @@ ++ s; \ if (s >= e) \ { \ - if (DEBUG) \ + if (SYMBIAN_DEBUG) \ fprintf (stderr, "Corrupt directive: %s\n", m); \ result = FALSE; \ } \ @@ -63,7 +63,7 @@ ++ s; \ if (s >= e) \ { \ - if (DEBUG) \ + if (SYMBIAN_DEBUG) \ fprintf (stderr, "Corrupt directive: %s\n", m); \ result = FALSE; \ } \ @@ -74,7 +74,7 @@ /* Macro to advance 's' until either it reaches 'e' or the character pointed to by 's' is not equal to 'c'. If 'e' - is reached and DEBUG is enabled then the error message + is reached and SYMBIAN_DEBUG is enabled then the error message 'm' is displayed. */ #define SKIP_WHILE(s,e,c,m) \ do \ @@ -83,7 +83,7 @@ ++ s; \ if (s >= e) \ { \ - if (DEBUG) \ + if (SYMBIAN_DEBUG) \ fprintf (stderr, "Corrupt directive: %s\n", m); \ result = FALSE; \ } \ @@ -114,7 +114,7 @@ sh_symbian_import_as (struct bfd_link_info *info, bfd * abfd, struct elf_link_hash_entry * new_hash; symbol_rename * node; - if (DEBUG) + if (SYMBIAN_DEBUG) fprintf (stderr, "IMPORT '%s' AS '%s'\n", current_name, new_name); for (node = rename_list; node; node = node->next) @@ -132,14 +132,14 @@ sh_symbian_import_as (struct bfd_link_info *info, bfd * abfd, if ((node = bfd_malloc (sizeof * node)) == NULL) { - if (DEBUG) + if (SYMBIAN_DEBUG) fprintf (stderr, "IMPORT AS: No mem for new rename node\n"); return FALSE; } if ((node->current_name = bfd_malloc (strlen (current_name) + 1)) == NULL) { - if (DEBUG) + if (SYMBIAN_DEBUG) fprintf (stderr, "IMPORT AS: No mem for current name field in rename node\n"); free (node); return FALSE; @@ -149,7 +149,7 @@ sh_symbian_import_as (struct bfd_link_info *info, bfd * abfd, if ((node->new_name = bfd_malloc (strlen (new_name) + 1)) == NULL) { - if (DEBUG) + if (SYMBIAN_DEBUG) fprintf (stderr, "IMPORT AS: No mem for new name field in rename node\n"); free (node->current_name); free (node); @@ -175,7 +175,7 @@ sh_symbian_import_as (struct bfd_link_info *info, bfd * abfd, static bfd_boolean sh_symbian_import (bfd * abfd ATTRIBUTE_UNUSED, char * name) { - if (DEBUG) + if (SYMBIAN_DEBUG) fprintf (stderr, "IMPORT '%s'\n", name); /* XXX: Generate an import somehow ? */ @@ -186,7 +186,7 @@ sh_symbian_import (bfd * abfd ATTRIBUTE_UNUSED, char * name) static bfd_boolean sh_symbian_export (bfd * abfd ATTRIBUTE_UNUSED, char * name) { - if (DEBUG) + if (SYMBIAN_DEBUG) fprintf (stderr, "EXPORT '%s'\n", name); /* XXX: Generate an export somehow ? */ @@ -266,7 +266,7 @@ sh_symbian_process_embedded_commands (struct bfd_link_info *info, bfd * abfd, if (strncmp (s, DIRECTIVE_AS, strlen (DIRECTIVE_AS))) { /* Skip the new-line at the end of the name. */ - if (DEBUG && name_end_char != '\n') + if (SYMBIAN_DEBUG && name_end_char != '\n') fprintf (stderr, "IMPORT: No newline at end of directive\n"); else s ++; @@ -276,7 +276,7 @@ sh_symbian_process_embedded_commands (struct bfd_link_info *info, bfd * abfd, /* Skip past the NUL character. */ if (* s ++ != 0) { - if (DEBUG) + if (SYMBIAN_DEBUG) fprintf (stderr, "IMPORT: No NUL at end of directive\n"); } } @@ -300,7 +300,7 @@ sh_symbian_process_embedded_commands (struct bfd_link_info *info, bfd * abfd, SKIP_WHILE (s, e, ' ', "IMPORT AS: Current name just followed by spaces"); /* Skip past the newline character. */ if (* s ++ != '\n') - if (DEBUG) + if (SYMBIAN_DEBUG) fprintf (stderr, "IMPORT AS: No newline at end of directive\n"); /* Terminate the current name after having performed the skips. */ @@ -311,7 +311,7 @@ sh_symbian_process_embedded_commands (struct bfd_link_info *info, bfd * abfd, /* The next character should be a NUL. */ if (* s != 0) { - if (DEBUG) + if (SYMBIAN_DEBUG) fprintf (stderr, "IMPORT AS: Junk at end of directive\n"); result = FALSE; } @@ -355,7 +355,7 @@ sh_symbian_process_embedded_commands (struct bfd_link_info *info, bfd * abfd, /* The next character should be a NUL. */ if (* s != 0) { - if (DEBUG) + if (SYMBIAN_DEBUG) fprintf (stderr, "EXPORT: Junk at end of directive\n"); result = FALSE; } @@ -373,7 +373,7 @@ sh_symbian_process_embedded_commands (struct bfd_link_info *info, bfd * abfd, if (! result) { - if (DEBUG) + if (SYMBIAN_DEBUG) fprintf (stderr, "offset into .directive section: %ld\n", (long) (directive - (char *) contents)); @@ -464,7 +464,7 @@ sh_symbian_relocate_section (bfd * output_bfd, if (ptr->current_hash == NULL) { - if (DEBUG) + if (SYMBIAN_DEBUG) fprintf (stderr, "IMPORT AS: current symbol '%s' does not exist\n", ptr->current_name); continue; } @@ -511,7 +511,7 @@ sh_symbian_relocate_section (bfd * output_bfd, if (new_hash->dynindx == -1) new_hash->def_regular = 1; - if (DEBUG) + if (SYMBIAN_DEBUG) fprintf (stderr, "Created new symbol %s\n", ptr->new_name); } @@ -521,7 +521,7 @@ sh_symbian_relocate_section (bfd * output_bfd, if (* h == new_hash) { ptr->new_symndx = h - sym_hashes + num_local_syms; - if (DEBUG) + if (SYMBIAN_DEBUG) fprintf (stderr, "Converted new hash to index of %ld\n", ptr->new_symndx); break; } @@ -539,7 +539,7 @@ sh_symbian_relocate_section (bfd * output_bfd, new_sym_hashes = bfd_alloc (input_bfd, num_global_syms * sizeof * sym_hashes); if (new_sym_hashes == NULL) { - if (DEBUG) + if (SYMBIAN_DEBUG) fprintf (stderr, "Out of memory extending hash table\n"); continue; } @@ -551,7 +551,7 @@ sh_symbian_relocate_section (bfd * output_bfd, ptr->new_symndx = num_global_syms - 1 + num_local_syms; - if (DEBUG) + if (SYMBIAN_DEBUG) fprintf (stderr, "Extended symbol hash table to insert new symbol as index %ld\n", ptr->new_symndx); } @@ -601,7 +601,7 @@ sh_symbian_relocate_section (bfd * output_bfd, if (h == ptr->current_hash) { BFD_ASSERT (ptr->new_symndx); - if (DEBUG) + if (SYMBIAN_DEBUG) fprintf (stderr, "convert reloc %lx from using index %ld to using index %ld\n", (long) rel->r_info, (long) ELF32_R_SYM (rel->r_info), ptr->new_symndx); rel->r_info = ELF32_R_INFO (ptr->new_symndx, r_type); diff --git a/bfd/elf32-sh64.c b/bfd/elf32-sh64.c index afafcfd..219f753 100644 --- a/bfd/elf32-sh64.c +++ b/bfd/elf32-sh64.c @@ -1,5 +1,5 @@ /* SuperH SH64-specific support for 32-bit ELF - Copyright 2000, 2001, 2002, 2003, 2004, 2005 + Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -115,13 +115,16 @@ static void sh64_find_section_for_address static bfd_boolean sh64_elf_new_section_hook (bfd *abfd, asection *sec) { - struct _sh64_elf_section_data *sdata; - bfd_size_type amt = sizeof (*sdata); + if (!sec->used_by_bfd) + { + struct _sh64_elf_section_data *sdata; + bfd_size_type amt = sizeof (*sdata); - sdata = (struct _sh64_elf_section_data *) bfd_zalloc (abfd, amt); - if (sdata == NULL) - return FALSE; - sec->used_by_bfd = sdata; + sdata = bfd_zalloc (abfd, amt); + if (sdata == NULL) + return FALSE; + sec->used_by_bfd = sdata; + } return _bfd_elf_new_section_hook (abfd, sec); } diff --git a/bfd/elf32-v850.c b/bfd/elf32-v850.c index e2c29ee..e3f1240 100644 --- a/bfd/elf32-v850.c +++ b/bfd/elf32-v850.c @@ -1,6 +1,6 @@ /* V850-specific support for 32-bit ELF - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 - Free Software Foundation, Inc. + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + 2006 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -33,6 +33,8 @@ /* Sign-extend a 24-bit number. */ #define SEXT24(x) ((((x) & 0xffffff) ^ 0x800000) - 0x800000) +static reloc_howto_type v850_elf_howto_table[]; + /* Look through the relocs for a section during the first phase, and allocate space in the global offset table or procedure linkage table. */ diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index 7a41d62..c7f3829 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -1,5 +1,5 @@ /* Xtensa-specific support for 32-bit ELF. - Copyright 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -5007,13 +5007,16 @@ struct elf_xtensa_section_data static bfd_boolean elf_xtensa_new_section_hook (bfd *abfd, asection *sec) { - struct elf_xtensa_section_data *sdata; - bfd_size_type amt = sizeof (*sdata); + if (!sec->used_by_bfd) + { + struct elf_xtensa_section_data *sdata; + bfd_size_type amt = sizeof (*sdata); - sdata = (struct elf_xtensa_section_data *) bfd_zalloc (abfd, amt); - if (sdata == NULL) - return FALSE; - sec->used_by_bfd = (void *) sdata; + sdata = bfd_zalloc (abfd, amt); + if (sdata == NULL) + return FALSE; + sec->used_by_bfd = sdata; + } return _bfd_elf_new_section_hook (abfd, sec); } diff --git a/bfd/elf64-mmix.c b/bfd/elf64-mmix.c index 6f88fe1..d8dfc56 100644 --- a/bfd/elf64-mmix.c +++ b/bfd/elf64-mmix.c @@ -1,5 +1,6 @@ /* MMIX-specific support for 64-bit ELF. - Copyright 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. Contributed by Hans-Peter Nilsson <hp@bitrange.com> This file is part of BFD, the Binary File Descriptor library. @@ -860,13 +861,16 @@ mmix_elf_new_section_hook (abfd, sec) bfd *abfd; asection *sec; { - struct _mmix_elf_section_data *sdata; - bfd_size_type amt = sizeof (*sdata); + if (!sec->used_by_bfd) + { + struct _mmix_elf_section_data *sdata; + bfd_size_type amt = sizeof (*sdata); - sdata = (struct _mmix_elf_section_data *) bfd_zalloc (abfd, amt); - if (sdata == NULL) - return FALSE; - sec->used_by_bfd = (PTR) sdata; + sdata = bfd_zalloc (abfd, amt); + if (sdata == NULL) + return FALSE; + sec->used_by_bfd = sdata; + } return _bfd_elf_new_section_hook (abfd, sec); } diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index fc8c182..1697d53 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -2550,13 +2550,16 @@ struct _ppc64_elf_section_data static bfd_boolean ppc64_elf_new_section_hook (bfd *abfd, asection *sec) { - struct _ppc64_elf_section_data *sdata; - bfd_size_type amt = sizeof (*sdata); + if (!sec->used_by_bfd) + { + struct _ppc64_elf_section_data *sdata; + bfd_size_type amt = sizeof (*sdata); - sdata = bfd_zalloc (abfd, amt); - if (sdata == NULL) - return FALSE; - sec->used_by_bfd = sdata; + sdata = bfd_zalloc (abfd, amt); + if (sdata == NULL) + return FALSE; + sec->used_by_bfd = sdata; + } return _bfd_elf_new_section_hook (abfd, sec); } @@ -6696,12 +6699,22 @@ ppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) { Elf_Internal_Sym *locsyms = NULL; + asection *toc = bfd_get_section_by_name (ibfd, ".toc"); + unsigned char *toc_ref = NULL; - for (sec = ibfd->sections; sec != NULL; sec = sec->next) + /* Look at all the sections for this file, with TOC last. */ + for (sec = (ibfd->sections == toc && toc && toc->next ? toc->next + : ibfd->sections); + sec != NULL; + sec = (sec == toc ? NULL + : sec->next == NULL ? toc + : sec->next == toc && toc->next ? toc->next + : sec->next)) if (sec->has_tls_reloc && !bfd_is_abs_section (sec->output_section)) { Elf_Internal_Rela *relstart, *rel, *relend; int expecting_tls_get_addr; + long toc_ref_index = 0; /* Read the relocations. */ relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL, @@ -6730,6 +6743,8 @@ ppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) err_free_rel: if (elf_section_data (sec)->relocs != relstart) free (relstart); + if (toc_ref != NULL) + free (toc_ref); if (locsyms != NULL && (elf_tdata (ibfd)->symtab_hdr.contents != (unsigned char *) locsyms)) @@ -6837,8 +6852,12 @@ ppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) rel - 1, ibfd); if (retval == 0) goto err_free_rel; - if (toc_tls != NULL) - expecting_tls_get_addr = retval > 1; + if (retval > 1 && toc_tls != NULL) + { + expecting_tls_get_addr = 1; + if (toc_ref != NULL) + toc_ref[toc_ref_index] = 1; + } } if (expecting_tls_get_addr) @@ -6856,8 +6875,40 @@ ppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) expecting_tls_get_addr = 0; continue; + case R_PPC64_TOC16: + case R_PPC64_TOC16_LO: + case R_PPC64_TLS: + expecting_tls_get_addr = 0; + if (sym_sec == toc && toc != NULL) + { + /* Mark this toc entry as referenced by a TLS + code sequence. We can do that now in the + case of R_PPC64_TLS, and after checking for + tls_get_addr for the TOC16 relocs. */ + if (toc_ref == NULL) + { + toc_ref = bfd_zmalloc (toc->size / 8); + if (toc_ref == NULL) + goto err_free_rel; + } + if (h != NULL) + value = h->root.u.def.value; + else + value = sym->st_value; + value += rel->r_addend; + BFD_ASSERT (value < toc->size && value % 8 == 0); + toc_ref_index = value / 8; + if (r_type == R_PPC64_TLS) + toc_ref[toc_ref_index] = 1; + } + continue; + case R_PPC64_TPREL64: expecting_tls_get_addr = 0; + if (sec != toc + || toc_ref == NULL + || !toc_ref[rel->r_offset / 8]) + continue; if (ok_tprel) { /* IE -> LE */ @@ -6870,6 +6921,10 @@ ppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) case R_PPC64_DTPMOD64: expecting_tls_get_addr = 0; + if (sec != toc + || toc_ref == NULL + || !toc_ref[rel->r_offset / 8]) + continue; if (rel + 1 < relend && (rel[1].r_info == ELF64_R_INFO (r_symndx, R_PPC64_DTPREL64)) @@ -6948,6 +7003,9 @@ ppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) free (relstart); } + if (toc_ref != NULL) + free (toc_ref); + if (locsyms != NULL && (elf_tdata (ibfd)->symtab_hdr.contents != (unsigned char *) locsyms)) @@ -7143,13 +7201,14 @@ ppc64_elf_edit_toc (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) return FALSE; } - /* Now check all kept sections that might reference the toc. */ - for (sec = ibfd->sections; + /* Now check all kept sections that might reference the toc. + Check the toc itself last. */ + for (sec = (ibfd->sections == toc && toc->next ? toc->next + : ibfd->sections); sec != NULL; - /* Check the toc itself last. */ sec = (sec == toc ? NULL - : sec->next == toc && sec->next->next ? sec->next->next : sec->next == NULL ? toc + : sec->next == toc && toc->next ? toc->next : sec->next)) { int repeat; @@ -11043,13 +11102,11 @@ ppc64_elf_finish_dynamic_symbol (bfd *output_bfd, Elf_Internal_Sym *sym) { struct ppc_link_hash_table *htab; - bfd *dynobj; struct plt_entry *ent; Elf_Internal_Rela rela; bfd_byte *loc; htab = ppc_hash_table (info); - dynobj = htab->elf.dynobj; for (ent = h->plt.plist; ent != NULL; ent = ent->next) if (ent->plt.offset != (bfd_vma) -1) diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index 1fe0c6c..bb20397 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -2240,6 +2240,7 @@ invalid_tls_insn (input_bfd, input_section, rel) input_section, (long) rel->r_offset, howto->name); + bfd_set_error (bfd_error_bad_value); } /* Relocate a 390 ELF section. */ diff --git a/bfd/elfcode.h b/bfd/elfcode.h index 9bb66e1..b783295 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -1,6 +1,6 @@ /* ELF executable support for BFD. Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. Written by Fred Fish @ Cygnus Support, from information published in "UNIX System V Release 4, Programmers Guide: ANSI C and @@ -139,10 +139,11 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. #define LOG_FILE_ALIGN 2 #endif -#ifdef DEBUG +#if DEBUG & 2 static void elf_debug_section (int, Elf_Internal_Shdr *); +#endif +#if DEBUG & 1 static void elf_debug_file (Elf_Internal_Ehdr *); -static char *elf_symbol_flags (flagword); #endif /* Structure swapping routines */ @@ -458,6 +459,25 @@ elf_file_p (Elf_External_Ehdr *x_ehdrp) && (x_ehdrp->e_ident[EI_MAG3] == ELFMAG3)); } +/* Determines if a given section index is valid. */ + +static inline bfd_boolean +valid_section_index_p (unsigned index, unsigned num_sections) +{ + /* Note: We allow SHN_UNDEF as a valid section index. */ + if (index < SHN_LORESERVE || index > SHN_HIRESERVE) + return index < num_sections; + + /* We disallow the use of reserved indcies, except for those + with OS or Application specific meaning. The test make use + of the knowledge that: + SHN_LORESERVE == SHN_LOPROC + and + SHN_HIPROC == SHN_LOOS - 1 */ + /* XXX - Should we allow SHN_XINDEX as a valid index here ? */ + return (index >= SHN_LOPROC && index <= SHN_HIOS); +} + /* Check to see if the file associated with ABFD matches the target vector that ABFD points to. @@ -545,7 +565,7 @@ elf_object_p (bfd *abfd) if (i_ehdrp->e_shoff == 0 && i_ehdrp->e_type == ET_REL) goto got_wrong_format_error; - /* As a simple sanity check, verify that the what BFD thinks is the + /* As a simple sanity check, verify that what BFD thinks is the size of each section header table entry actually matches the size recorded in the file, but only if there are any sections. */ if (i_ehdrp->e_shentsize != sizeof (x_shdr) && i_ehdrp->e_shnum != 0) @@ -711,17 +731,13 @@ elf_object_p (bfd *abfd) elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex); /* Sanity check sh_link and sh_info. */ - if (i_shdrp[shindex].sh_link >= num_sec - || (i_shdrp[shindex].sh_link >= SHN_LORESERVE - && i_shdrp[shindex].sh_link <= SHN_HIRESERVE)) + if (! valid_section_index_p (i_shdrp[shindex].sh_link, num_sec)) goto got_wrong_format_error; if (((i_shdrp[shindex].sh_flags & SHF_INFO_LINK) || i_shdrp[shindex].sh_type == SHT_RELA || i_shdrp[shindex].sh_type == SHT_REL) - && (i_shdrp[shindex].sh_info >= num_sec - || (i_shdrp[shindex].sh_info >= SHN_LORESERVE - && i_shdrp[shindex].sh_info <= SHN_HIRESERVE))) + && ! valid_section_index_p (i_shdrp[shindex].sh_info, num_sec)) goto got_wrong_format_error; /* If the section is loaded, but not page aligned, clear @@ -739,9 +755,7 @@ elf_object_p (bfd *abfd) /* A further sanity check. */ if (i_ehdrp->e_shnum != 0) { - if (i_ehdrp->e_shstrndx >= elf_numsections (abfd) - || (i_ehdrp->e_shstrndx >= SHN_LORESERVE - && i_ehdrp->e_shstrndx <= SHN_HIRESERVE)) + if (! valid_section_index_p (i_ehdrp->e_shstrndx, elf_numsections (abfd))) { /* PR 2257: We used to just goto got_wrong_format_error here @@ -1349,10 +1363,8 @@ elf_slurp_reloc_table_from_section (bfd *abfd, } else { - asymbol **ps, *s; - + asymbol **ps; ps = symbols + ELF_R_SYM (rela.r_info) - 1; - s = *ps; relent->sym_ptr_ptr = ps; } @@ -1450,7 +1462,7 @@ elf_slurp_reloc_table (bfd *abfd, return TRUE; } -#ifdef DEBUG +#if DEBUG & 2 static void elf_debug_section (int num, Elf_Internal_Shdr *hdr) { @@ -1476,7 +1488,9 @@ elf_debug_section (int num, Elf_Internal_Shdr *hdr) (long) hdr->sh_entsize); fflush (stderr); } +#endif +#if DEBUG & 1 static void elf_debug_file (Elf_Internal_Ehdr *ehdrp) { @@ -1488,77 +1502,6 @@ elf_debug_file (Elf_Internal_Ehdr *ehdrp) fprintf (stderr, "e_shnum = %ld\n", (long) ehdrp->e_shnum); fprintf (stderr, "e_shentsize = %ld\n", (long) ehdrp->e_shentsize); } - -static char * -elf_symbol_flags (flagword flags) -{ - static char buffer[1024]; - - buffer[0] = '\0'; - if (flags & BSF_LOCAL) - strcat (buffer, " local"); - - if (flags & BSF_GLOBAL) - strcat (buffer, " global"); - - if (flags & BSF_DEBUGGING) - strcat (buffer, " debug"); - - if (flags & BSF_FUNCTION) - strcat (buffer, " function"); - - if (flags & BSF_KEEP) - strcat (buffer, " keep"); - - if (flags & BSF_KEEP_G) - strcat (buffer, " keep_g"); - - if (flags & BSF_WEAK) - strcat (buffer, " weak"); - - if (flags & BSF_SECTION_SYM) - strcat (buffer, " section-sym"); - - if (flags & BSF_OLD_COMMON) - strcat (buffer, " old-common"); - - if (flags & BSF_NOT_AT_END) - strcat (buffer, " not-at-end"); - - if (flags & BSF_CONSTRUCTOR) - strcat (buffer, " constructor"); - - if (flags & BSF_WARNING) - strcat (buffer, " warning"); - - if (flags & BSF_INDIRECT) - strcat (buffer, " indirect"); - - if (flags & BSF_FILE) - strcat (buffer, " file"); - - if (flags & DYNAMIC) - strcat (buffer, " dynamic"); - - if (flags & ~(BSF_LOCAL - | BSF_GLOBAL - | BSF_DEBUGGING - | BSF_FUNCTION - | BSF_KEEP - | BSF_KEEP_G - | BSF_WEAK - | BSF_SECTION_SYM - | BSF_OLD_COMMON - | BSF_NOT_AT_END - | BSF_CONSTRUCTOR - | BSF_WARNING - | BSF_INDIRECT - | BSF_FILE - | BSF_DYNAMIC)) - strcat (buffer, " unknown-bits"); - - return buffer; -} #endif /* Create a new BFD as if by bfd_openr. Rather than opening a file, diff --git a/bfd/elflink.c b/bfd/elflink.c index 0900220..a1632cc 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -6758,7 +6758,7 @@ unsigned int _bfd_elf_default_action_discarded (asection *sec) { if (sec->flags & SEC_DEBUGGING) - return 0; + return PRETEND; if (strcmp (".eh_frame", sec->name) == 0) return 0; @@ -6782,6 +6782,7 @@ match_group_member (asection *sec, asection *group) if (bfd_elf_match_symbols_in_sections (s, sec)) return s; + s = elf_next_in_group (s); if (s == first) break; } @@ -7250,7 +7251,7 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd) /* This is a reloc for a deleted entry or somesuch. Turn it into an R_*_NONE reloc, at the same offset as the last reloc. elf_eh_frame.c and - elf_bfd_discard_info rely on reloc offsets + bfd_elf_discard_info rely on reloc offsets being ordered. */ irela->r_offset = last_offset; irela->r_info = 0; diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 4e27a53..e86f712 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -826,13 +826,16 @@ mips_elf_link_hash_newfunc (struct bfd_hash_entry *entry, bfd_boolean _bfd_mips_elf_new_section_hook (bfd *abfd, asection *sec) { - struct _mips_elf_section_data *sdata; - bfd_size_type amt = sizeof (*sdata); + if (!sec->used_by_bfd) + { + struct _mips_elf_section_data *sdata; + bfd_size_type amt = sizeof (*sdata); - sdata = bfd_zalloc (abfd, amt); - if (sdata == NULL) - return FALSE; - sec->used_by_bfd = sdata; + sdata = bfd_zalloc (abfd, amt); + if (sdata == NULL) + return FALSE; + sec->used_by_bfd = sdata; + } return _bfd_elf_new_section_hook (abfd, sec); } @@ -4955,39 +4958,30 @@ _bfd_elf_mips_mach (flagword flags) default: case E_MIPS_ARCH_1: return bfd_mach_mips3000; - break; case E_MIPS_ARCH_2: return bfd_mach_mips6000; - break; case E_MIPS_ARCH_3: return bfd_mach_mips4000; - break; case E_MIPS_ARCH_4: return bfd_mach_mips8000; - break; case E_MIPS_ARCH_5: return bfd_mach_mips5; - break; case E_MIPS_ARCH_32: return bfd_mach_mipsisa32; - break; case E_MIPS_ARCH_64: return bfd_mach_mipsisa64; - break; case E_MIPS_ARCH_32R2: return bfd_mach_mipsisa32r2; - break; case E_MIPS_ARCH_64R2: return bfd_mach_mipsisa64r2; - break; } } @@ -9386,7 +9380,7 @@ _bfd_mips_elf_hide_symbol (struct bfd_link_info *info, dynobj = elf_hash_table (info)->dynobj; if (dynobj != NULL && force_local && h->root.type != STT_TLS - && (got = mips_elf_got_section (dynobj, FALSE)) != NULL + && (got = mips_elf_got_section (dynobj, TRUE)) != NULL && (g = mips_elf_section_data (got)->u.got_info) != NULL) { if (g->next) diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c index ef7ff48..73e8eb2 100644 --- a/bfd/elfxx-sparc.c +++ b/bfd/elfxx-sparc.c @@ -2434,13 +2434,16 @@ _bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd, bfd_boolean _bfd_sparc_elf_new_section_hook (bfd *abfd, asection *sec) { - struct _bfd_sparc_elf_section_data *sdata; - bfd_size_type amt = sizeof (*sdata); + if (!sec->used_by_bfd) + { + struct _bfd_sparc_elf_section_data *sdata; + bfd_size_type amt = sizeof (*sdata); - sdata = (struct _bfd_sparc_elf_section_data *) bfd_zalloc (abfd, amt); - if (sdata == NULL) - return FALSE; - sec->used_by_bfd = (PTR) sdata; + sdata = bfd_zalloc (abfd, amt); + if (sdata == NULL) + return FALSE; + sec->used_by_bfd = sdata; + } return _bfd_elf_new_section_hook (abfd, sec); } diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index 503726d..14a693a 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -29,7 +29,9 @@ #ifndef bfd_elfNN_close_and_cleanup #define bfd_elfNN_close_and_cleanup _bfd_elf_close_and_cleanup #endif -#define bfd_elfNN_bfd_free_cached_info _bfd_generic_bfd_free_cached_info +#ifndef bfd_elfNN_bfd_free_cached_info +#define bfd_elfNN_bfd_free_cached_info _bfd_free_cached_info +#endif #ifndef bfd_elfNN_get_section_contents #define bfd_elfNN_get_section_contents _bfd_generic_get_section_contents #endif @@ -299,6 +299,58 @@ SUBSUBSECTION /* The default number of entries to use when creating a hash table. */ #define DEFAULT_SIZE 4051 + +/* The following function returns a nearest prime number which is + greater than N, and near a power of two. Copied from libiberty. + Returns zero for ridiculously large N to signify an error. */ + +static unsigned long +higher_prime_number (unsigned long n) +{ + /* These are primes that are near, but slightly smaller than, a + power of two. */ + static const unsigned long primes[] = { + (unsigned long) 127, + (unsigned long) 2039, + (unsigned long) 32749, + (unsigned long) 65521, + (unsigned long) 131071, + (unsigned long) 262139, + (unsigned long) 524287, + (unsigned long) 1048573, + (unsigned long) 2097143, + (unsigned long) 4194301, + (unsigned long) 8388593, + (unsigned long) 16777213, + (unsigned long) 33554393, + (unsigned long) 67108859, + (unsigned long) 134217689, + (unsigned long) 268435399, + (unsigned long) 536870909, + (unsigned long) 1073741789, + (unsigned long) 2147483647, + /* 4294967291L */ + ((unsigned long) 2147483647) + ((unsigned long) 2147483644), + }; + + const unsigned long *low = &primes[0]; + const unsigned long *high = &primes[sizeof (primes) / sizeof (primes[0])]; + + while (low != high) + { + const unsigned long *mid = low + (high - low) / 2; + if (n >= *mid) + low = mid + 1; + else + high = mid; + } + + if (n >= *low) + return 0; + + return *low; +} + static size_t bfd_default_hash_table_size = DEFAULT_SIZE; /* Create a new hash table, given a number of entries. */ @@ -330,6 +382,7 @@ bfd_hash_table_init_n (struct bfd_hash_table *table, memset ((void *) table->table, 0, alloc); table->size = size; table->entsize = entsize; + table->count = 0; table->newfunc = newfunc; return TRUE; } @@ -402,6 +455,7 @@ bfd_hash_lookup (struct bfd_hash_table *table, if (copy) { char *new; + table->count ++; new = objalloc_alloc ((struct objalloc *) table->memory, len + 1); if (!new) @@ -417,6 +471,45 @@ bfd_hash_lookup (struct bfd_hash_table *table, hashp->next = table->table[index]; table->table[index] = hashp; + if (table->count > table->size * 3 / 4) + { + unsigned long newsize = higher_prime_number (table->size); + struct bfd_hash_entry **newtable; + unsigned int hi; + unsigned long alloc = newsize * sizeof (struct bfd_hash_entry *); + + /* If we can't find a higher prime, or we can't possibly alloc + that much memory, don't try to grow the table. */ + if (newsize == 0 || alloc / sizeof (struct bfd_hash_entry *) != newsize) + { + /* Lie. Stops us trying to grow again for a while. */ + table->count = 0; + return hashp; + } + + newtable = ((struct bfd_hash_entry **) + objalloc_alloc ((struct objalloc *) table->memory, alloc)); + memset ((PTR) newtable, 0, alloc); + + for (hi = 0; hi < table->size; hi ++) + while (table->table[hi]) + { + struct bfd_hash_entry *chain = table->table[hi]; + struct bfd_hash_entry *chain_end = chain; + int index; + + while (chain_end->next && chain_end->next->hash == chain->hash) + chain_end = chain_end->next; + + table->table[hi] = chain_end->next; + index = chain->hash % newsize; + chain_end->next = newtable[index]; + newtable[index] = chain; + } + table->table = newtable; + table->size = newsize; + } + return hashp; } @@ -2014,12 +2014,15 @@ ieee_print_symbol (bfd *abfd, static bfd_boolean ieee_new_section_hook (bfd *abfd, asection *newsect) { - newsect->used_by_bfd = bfd_alloc (abfd, (bfd_size_type) sizeof (ieee_per_section_type)); if (!newsect->used_by_bfd) - return FALSE; + { + newsect->used_by_bfd = bfd_alloc (abfd, sizeof (ieee_per_section_type)); + if (!newsect->used_by_bfd) + return FALSE; + } ieee_per_section (newsect)->data = NULL; ieee_per_section (newsect)->section = newsect; - return TRUE; + return _bfd_generic_new_section_hook (abfd, newsect); } static long @@ -553,7 +553,6 @@ ihex_read_section (bfd *abfd, asection *section, bfd_byte *contents) { char hdr[8]; unsigned int len; - bfd_vma addr; unsigned int type; unsigned int i; @@ -568,7 +567,6 @@ ihex_read_section (bfd *abfd, asection *section, bfd_byte *contents) goto error_return; len = HEX2 (hdr); - addr = HEX4 (hdr + 2); type = HEX2 (hdr + 6); /* We should only see type 0 records here. */ diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h index ee2484f..ab11d2f 100644 --- a/bfd/libbfd-in.h +++ b/bfd/libbfd-in.h @@ -155,6 +155,8 @@ bfd * _bfd_new_bfd (void); void _bfd_delete_bfd (bfd *); +bfd_boolean _bfd_free_cached_info + (bfd *); bfd_boolean bfd_false (bfd *ignore); @@ -215,8 +217,8 @@ int bfd_generic_stat_arch_elt #define _bfd_generic_close_and_cleanup bfd_true #define _bfd_generic_bfd_free_cached_info bfd_true -#define _bfd_generic_new_section_hook \ - ((bfd_boolean (*) (bfd *, asection *)) bfd_true) +extern bfd_boolean _bfd_generic_new_section_hook + (bfd *, asection *); extern bfd_boolean _bfd_generic_get_section_contents (bfd *, asection *, void *, file_ptr, bfd_size_type); extern bfd_boolean _bfd_generic_get_section_contents_in_window diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 2a590a3..34b0f4f 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -160,6 +160,8 @@ bfd * _bfd_new_bfd (void); void _bfd_delete_bfd (bfd *); +bfd_boolean _bfd_free_cached_info + (bfd *); bfd_boolean bfd_false (bfd *ignore); @@ -220,8 +222,8 @@ int bfd_generic_stat_arch_elt #define _bfd_generic_close_and_cleanup bfd_true #define _bfd_generic_bfd_free_cached_info bfd_true -#define _bfd_generic_new_section_hook \ - ((bfd_boolean (*) (bfd *, asection *)) bfd_true) +extern bfd_boolean _bfd_generic_new_section_hook + (bfd *, asection *); extern bfd_boolean _bfd_generic_get_section_contents (bfd *, asection *, void *, file_ptr, bfd_size_type); extern bfd_boolean _bfd_generic_get_section_contents_in_window @@ -1206,6 +1208,14 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_ARM_SBREL32", "BFD_RELOC_ARM_TARGET2", "BFD_RELOC_ARM_PREL31", + "BFD_RELOC_ARM_MOVW", + "BFD_RELOC_ARM_MOVT", + "BFD_RELOC_ARM_MOVW_PCREL", + "BFD_RELOC_ARM_MOVT_PCREL", + "BFD_RELOC_ARM_THUMB_MOVW", + "BFD_RELOC_ARM_THUMB_MOVT", + "BFD_RELOC_ARM_THUMB_MOVW_PCREL", + "BFD_RELOC_ARM_THUMB_MOVT_PCREL", "BFD_RELOC_ARM_JUMP_SLOT", "BFD_RELOC_ARM_GLOB_DAT", "BFD_RELOC_ARM_GOT32", @@ -1,5 +1,5 @@ /* BFD back-end for mmo objects (MMIX-specific object-format). - Copyright 2001, 2002, 2003, 2004, 2005 + Copyright 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. Written by Hans-Peter Nilsson (hp@bitrange.com). Infrastructure and other bits originally copied from srec.c and @@ -2007,19 +2007,21 @@ mmo_scan (bfd *abfd) we point out the shape of allocated section contents. */ static bfd_boolean -mmo_new_section_hook (bfd *abfd ATTRIBUTE_UNUSED, asection *newsect) +mmo_new_section_hook (bfd *abfd, asection *newsect) { - /* We zero-fill all fields and assume NULL is represented by an all - zero-bit pattern. */ - newsect->used_by_bfd = - bfd_zalloc (abfd, sizeof (struct mmo_section_data_struct)); - if (!newsect->used_by_bfd) - return FALSE; + { + /* We zero-fill all fields and assume NULL is represented by an all + zero-bit pattern. */ + newsect->used_by_bfd + = bfd_zalloc (abfd, sizeof (struct mmo_section_data_struct)); + if (!newsect->used_by_bfd) + return FALSE; + } /* Always align to at least 32-bit words. */ newsect->alignment_power = 2; - return TRUE; + return _bfd_generic_new_section_hook (abfd, newsect); } /* We already have section contents loaded for sections that have diff --git a/bfd/nlm32-sparc.c b/bfd/nlm32-sparc.c index e647ad0..701a6d8 100644 --- a/bfd/nlm32-sparc.c +++ b/bfd/nlm32-sparc.c @@ -1,5 +1,5 @@ /* Support for 32-bit SPARC NLM (NetWare Loadable Module) - Copyright 1993, 1994, 1999, 2000, 2001, 2002, 2003, 2004, 2005 + Copyright 1993, 1994, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -123,8 +123,9 @@ nlm_sparc_read_reloc (bfd *abfd, } #ifdef DEBUG - fprintf (stderr, "%s: address = %08lx, addend = %08lx, type = %d, howto = %08lx\n", - __FUNCTION__, rel->address, rel->addend, type, rel->howto); + fprintf (stderr, "%s: address = %08lx, addend = %08lx, type = %u, howto = %p\n", + __FUNCTION__, (unsigned long) rel->address, + (unsigned long) rel->addend, type, rel->howto); #endif return TRUE; @@ -176,8 +177,9 @@ nlm_sparc_write_reloc (bfd * abfd, asection * sec, arelent * rel) val = bfd_get_section_vma (abfd, sec) + rel->address; #ifdef DEBUG - fprintf (stderr, "%s: val = %08lx, addend = %08lx, type = %d\n", - __FUNCTION__, val, rel->addend, rel->howto->type); + fprintf (stderr, "%s: val = %08lx, addend = %08lx, type = %u\n", + __FUNCTION__, (unsigned long) val, (unsigned long) rel->addend, + rel->howto->type); #endif bfd_put_32 (abfd, val, tmp_reloc.offset); bfd_put_32 (abfd, rel->addend, tmp_reloc.addend); @@ -280,8 +282,8 @@ nlm_sparc_write_import (bfd * abfd, asection * sec, arelent * rel) base = 0; #ifdef DEBUG - fprintf (stderr, "%s: <%x, 1>\n\t", - __FUNCTION__, base + (*rel->sym_ptr_ptr)->value); + fprintf (stderr, "%s: <%lx, 1>\n\t", + __FUNCTION__, (unsigned long) (base + (*rel->sym_ptr_ptr)->value)); #endif bfd_put_32 (abfd, base + (*rel->sym_ptr_ptr)->value, temp); if (bfd_bwrite (temp, (bfd_size_type) 4, abfd) != 4) @@ -330,8 +332,8 @@ nlm_sparc_write_export (bfd * abfd, asymbol * sym, bfd_vma value) bfd_byte temp[4]; #ifdef DEBUG - fprintf (stderr, "%s: <%x, %d, %s>\n", - __FUNCTION__, value, strlen (sym->name), sym->name); + fprintf (stderr, "%s: <%lx, %u, %s>\n", + __FUNCTION__, (unsigned long) value, strlen (sym->name), sym->name); #endif bfd_put_32 (abfd, value, temp); len = strlen (sym->name); diff --git a/bfd/oasys.c b/bfd/oasys.c index 74d2c31..e51cde6 100644 --- a/bfd/oasys.c +++ b/bfd/oasys.c @@ -1,6 +1,6 @@ /* BFD back-end for oasys objects. Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001, - 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. Written by Steve Chamberlain of Cygnus Support, <sac@cygnus.com>. This file is part of BFD, the Binary File Descriptor library. @@ -685,9 +685,13 @@ oasys_print_symbol (bfd *abfd, void * afile, asymbol *symbol, bfd_print_symbol_t static bfd_boolean oasys_new_section_hook (bfd *abfd, asection *newsect) { - newsect->used_by_bfd = bfd_alloc (abfd, (bfd_size_type) sizeof (oasys_per_section_type)); if (!newsect->used_by_bfd) - return FALSE; + { + newsect->used_by_bfd + = bfd_alloc (abfd, (bfd_size_type) sizeof (oasys_per_section_type)); + if (!newsect->used_by_bfd) + return FALSE; + } oasys_per_section (newsect)->data = NULL; oasys_per_section (newsect)->section = newsect; oasys_per_section (newsect)->offset = 0; @@ -697,7 +701,7 @@ oasys_new_section_hook (bfd *abfd, asection *newsect) /* Turn the section string into an index. */ sscanf (newsect->name, "%u", &newsect->target_index); - return TRUE; + return _bfd_generic_new_section_hook (abfd, newsect); } diff --git a/bfd/opncls.c b/bfd/opncls.c index b02b137..7e62d06 100644 --- a/bfd/opncls.c +++ b/bfd/opncls.c @@ -115,11 +115,35 @@ _bfd_new_bfd_contained_in (bfd *obfd) void _bfd_delete_bfd (bfd *abfd) { - bfd_hash_table_free (&abfd->section_htab); - objalloc_free ((struct objalloc *) abfd->memory); + if (abfd->memory) + { + bfd_hash_table_free (&abfd->section_htab); + objalloc_free ((struct objalloc *) abfd->memory); + } free (abfd); } +/* Free objalloc memory. */ + +bfd_boolean +_bfd_free_cached_info (bfd *abfd) +{ + if (abfd->memory) + { + bfd_hash_table_free (&abfd->section_htab); + objalloc_free ((struct objalloc *) abfd->memory); + + abfd->sections = NULL; + abfd->section_last = NULL; + abfd->outsymbols = NULL; + abfd->tdata.any = NULL; + abfd->usrdata = NULL; + abfd->memory = NULL; + } + + return TRUE; +} + /* SECTION Opening and closing BFDs diff --git a/bfd/pdp11.c b/bfd/pdp11.c index 37f960f..b3b4f07 100644 --- a/bfd/pdp11.c +++ b/bfd/pdp11.c @@ -1111,32 +1111,27 @@ NAME (aout, new_section_hook) (bfd *abfd, asection *newsect) if (bfd_get_format (abfd) == bfd_object) { if (obj_textsec (abfd) == NULL - && ! strcmp (newsect->name, ".text")) + && !strcmp (newsect->name, ".text")) { obj_textsec(abfd)= newsect; newsect->target_index = N_TEXT; - return TRUE; } - - if (obj_datasec (abfd) == NULL - && ! strcmp (newsect->name, ".data")) - { - obj_datasec (abfd) = newsect; - newsect->target_index = N_DATA; - return TRUE; - } - - if (obj_bsssec (abfd) == NULL - && !strcmp (newsect->name, ".bss")) - { - obj_bsssec (abfd) = newsect; - newsect->target_index = N_BSS; - return TRUE; - } - } + else if (obj_datasec (abfd) == NULL + && !strcmp (newsect->name, ".data")) + { + obj_datasec (abfd) = newsect; + newsect->target_index = N_DATA; + } + else if (obj_bsssec (abfd) == NULL + && !strcmp (newsect->name, ".bss")) + { + obj_bsssec (abfd) = newsect; + newsect->target_index = N_BSS; + } + } /* We allow more than three sections internally. */ - return TRUE; + return _bfd_generic_new_section_hook (abfd, newsect); } bfd_boolean diff --git a/bfd/reloc.c b/bfd/reloc.c index f1d09a5..6adc7fb 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -2701,6 +2701,24 @@ ENUM BFD_RELOC_ARM_PREL31 ENUMDOC 31-bit PC relative address. +ENUM + BFD_RELOC_ARM_MOVW +ENUMX + BFD_RELOC_ARM_MOVT +ENUMX + BFD_RELOC_ARM_MOVW_PCREL +ENUMX + BFD_RELOC_ARM_MOVT_PCREL +ENUMX + BFD_RELOC_ARM_THUMB_MOVW +ENUMX + BFD_RELOC_ARM_THUMB_MOVT +ENUMX + BFD_RELOC_ARM_THUMB_MOVW_PCREL +ENUMX + BFD_RELOC_ARM_THUMB_MOVT_PCREL +ENUMDOC + Low and High halfword relocations for MOVW and MOVT instructions. ENUM BFD_RELOC_ARM_JUMP_SLOT diff --git a/bfd/section.c b/bfd/section.c index f870e6b..2b5f7f8 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -540,11 +540,6 @@ CODE_FRAGMENT . || ((SEC) == bfd_com_section_ptr) \ . || ((SEC) == bfd_ind_section_ptr)) . -.extern const struct bfd_symbol * const bfd_abs_symbol; -.extern const struct bfd_symbol * const bfd_com_symbol; -.extern const struct bfd_symbol * const bfd_und_symbol; -.extern const struct bfd_symbol * const bfd_ind_symbol; -. .{* Macros to handle insertion and deletion of a bfd's sections. These . only handle the list pointers, ie. do not adjust section_count, . target_index etc. *} @@ -635,7 +630,7 @@ CODE_FRAGMENT .#define bfd_section_removed_from_list(ABFD, S) \ . ((S)->next == NULL ? (ABFD)->section_last != (S) : (S)->next->prev != (S)) . -.#define BFD_FAKE_SECTION(SEC, FLAGS, SYM, SYM_PTR, NAME, IDX) \ +.#define BFD_FAKE_SECTION(SEC, FLAGS, SYM, NAME, IDX) \ . {* name, id, index, next, prev, flags, user_set_vma, *} \ . { NAME, IDX, 0, NULL, NULL, FLAGS, 0, \ . \ @@ -666,11 +661,8 @@ CODE_FRAGMENT . {* target_index, used_by_bfd, constructor_chain, owner, *} \ . 0, NULL, NULL, NULL, \ . \ -. {* symbol, *} \ -. (struct bfd_symbol *) SYM, \ -. \ -. {* symbol_ptr_ptr, *} \ -. (struct bfd_symbol **) SYM_PTR, \ +. {* symbol, symbol_ptr_ptr, *} \ +. (struct bfd_symbol *) SYM, &SEC.symbol, \ . \ . {* map_head, map_tail *} \ . { NULL }, { NULL } \ @@ -701,16 +693,14 @@ static const asymbol global_syms[] = GLOBAL_SYM_INIT (BFD_IND_SECTION_NAME, &bfd_ind_section) }; -#define STD_SECTION(SEC, FLAGS, SYM, NAME, IDX) \ - const asymbol * const SYM = (asymbol *) &global_syms[IDX]; \ - asection SEC = BFD_FAKE_SECTION(SEC, FLAGS, &global_syms[IDX], &SYM, \ +#define STD_SECTION(SEC, FLAGS, NAME, IDX) \ + asection SEC = BFD_FAKE_SECTION(SEC, FLAGS, &global_syms[IDX], \ NAME, IDX) -STD_SECTION (bfd_com_section, SEC_IS_COMMON, bfd_com_symbol, - BFD_COM_SECTION_NAME, 0); -STD_SECTION (bfd_und_section, 0, bfd_und_symbol, BFD_UND_SECTION_NAME, 1); -STD_SECTION (bfd_abs_section, 0, bfd_abs_symbol, BFD_ABS_SECTION_NAME, 2); -STD_SECTION (bfd_ind_section, 0, bfd_ind_symbol, BFD_IND_SECTION_NAME, 3); +STD_SECTION (bfd_com_section, SEC_IS_COMMON, BFD_COM_SECTION_NAME, 0); +STD_SECTION (bfd_und_section, 0, BFD_UND_SECTION_NAME, 1); +STD_SECTION (bfd_abs_section, 0, BFD_ABS_SECTION_NAME, 2); +STD_SECTION (bfd_ind_section, 0, BFD_IND_SECTION_NAME, 3); #undef STD_SECTION /* Initialize an entry in the section hash table. */ @@ -743,23 +733,16 @@ bfd_section_hash_newfunc (struct bfd_hash_entry *entry, ((struct section_hash_entry *) \ bfd_hash_lookup ((table), (string), (create), (copy))) -/* Initializes a new section. NEWSECT->NAME is already set. */ +/* Create a symbol whose only job is to point to this section. This + is useful for things like relocs which are relative to the base + of a section. */ -static asection * -bfd_section_init (bfd *abfd, asection *newsect) +bfd_boolean +_bfd_generic_new_section_hook (bfd *abfd, asection *newsect) { - static int section_id = 0x10; /* id 0 to 3 used by STD_SECTION. */ - - newsect->id = section_id; - newsect->index = abfd->section_count; - newsect->owner = abfd; - - /* Create a symbol whose only job is to point to this section. This - is useful for things like relocs which are relative to the base - of a section. */ newsect->symbol = bfd_make_empty_symbol (abfd); if (newsect->symbol == NULL) - return NULL; + return FALSE; newsect->symbol->name = newsect->name; newsect->symbol->value = 0; @@ -767,6 +750,19 @@ bfd_section_init (bfd *abfd, asection *newsect) newsect->symbol->flags = BSF_SECTION_SYM; newsect->symbol_ptr_ptr = &newsect->symbol; + return TRUE; +} + +/* Initializes a new section. NEWSECT->NAME is already set. */ + +static asection * +bfd_section_init (bfd *abfd, asection *newsect) +{ + static int section_id = 0x10; /* id 0 to 3 used by STD_SECTION. */ + + newsect->id = section_id; + newsect->index = abfd->section_count; + newsect->owner = abfd; if (! BFD_SEND (abfd, _new_section_hook, (abfd, newsect))) return NULL; @@ -964,7 +960,6 @@ DESCRIPTION asection * bfd_make_section_old_way (bfd *abfd, const char *name) { - struct section_hash_entry *sh; asection *newsect; if (abfd->output_has_begun) @@ -974,30 +969,38 @@ bfd_make_section_old_way (bfd *abfd, const char *name) } if (strcmp (name, BFD_ABS_SECTION_NAME) == 0) - return bfd_abs_section_ptr; - - if (strcmp (name, BFD_COM_SECTION_NAME) == 0) - return bfd_com_section_ptr; - - if (strcmp (name, BFD_UND_SECTION_NAME) == 0) - return bfd_und_section_ptr; + newsect = bfd_abs_section_ptr; + else if (strcmp (name, BFD_COM_SECTION_NAME) == 0) + newsect = bfd_com_section_ptr; + else if (strcmp (name, BFD_UND_SECTION_NAME) == 0) + newsect = bfd_und_section_ptr; + else if (strcmp (name, BFD_IND_SECTION_NAME) == 0) + newsect = bfd_ind_section_ptr; + else + { + struct section_hash_entry *sh; - if (strcmp (name, BFD_IND_SECTION_NAME) == 0) - return bfd_ind_section_ptr; + sh = section_hash_lookup (&abfd->section_htab, name, TRUE, FALSE); + if (sh == NULL) + return NULL; - sh = section_hash_lookup (&abfd->section_htab, name, TRUE, FALSE); - if (sh == NULL) - return NULL; + newsect = &sh->section; + if (newsect->name != NULL) + { + /* Section already exists. */ + return newsect; + } - newsect = &sh->section; - if (newsect->name != NULL) - { - /* Section already exists. */ - return newsect; + newsect->name = name; + return bfd_section_init (abfd, newsect); } - newsect->name = name; - return bfd_section_init (abfd, newsect); + /* Call new_section_hook when "creating" the standard abs, com, und + and ind sections to tack on format specific section data. + Also, create a proper section symbol. */ + if (! BFD_SEND (abfd, _new_section_hook, (abfd, newsect))) + return NULL; + return newsect; } /* @@ -1,6 +1,6 @@ /* bfd back-end for HP PA-RISC SOM objects. Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005 + 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. Contributed by the Center for Software Science at the @@ -4959,15 +4959,18 @@ extern const bfd_target som_vec; static bfd_boolean som_new_section_hook (bfd *abfd, asection *newsect) { - bfd_size_type amt = sizeof (struct som_section_data_struct); - - newsect->used_by_bfd = bfd_zalloc (abfd, amt); if (!newsect->used_by_bfd) - return FALSE; + { + bfd_size_type amt = sizeof (struct som_section_data_struct); + + newsect->used_by_bfd = bfd_zalloc (abfd, amt); + if (!newsect->used_by_bfd) + return FALSE; + } newsect->alignment_power = 3; /* We allow more than three sections internally. */ - return TRUE; + return _bfd_generic_new_section_hook (abfd, newsect); } /* Copy any private info we understand from the input symbol diff --git a/bfd/tekhex.c b/bfd/tekhex.c index 559f21a..e40c866 100644 --- a/bfd/tekhex.c +++ b/bfd/tekhex.c @@ -264,36 +264,50 @@ typedef struct tekhex_data_struct #define enda(x) (x->vma + x->size) -static bfd_vma -getvalue (char **srcp) +static bfd_boolean +getvalue (char **srcp, bfd_vma *valuep) { char *src = *srcp; bfd_vma value = 0; - unsigned int len = hex_value(*src++); + unsigned int len; + + if (!ISHEX (*src)) + return FALSE; + len = hex_value (*src++); if (len == 0) len = 16; while (len--) - value = value << 4 | hex_value(*src++); + { + if (!ISHEX (*src)) + return FALSE; + value = value << 4 | hex_value (*src++); + } *srcp = src; - return value; + *valuep = value; + return TRUE; } -static unsigned int -getsym (char *dstp, char **srcp) +static bfd_boolean +getsym (char *dstp, char **srcp, unsigned int *lenp) { char *src = *srcp; unsigned int i; - unsigned int len = hex_value(*src++); + unsigned int len; + + if (!ISHEX (*src)) + return FALSE; + len = hex_value (*src++); if (len == 0) len = 16; for (i = 0; i < len; i++) dstp[i] = src[i]; dstp[i] = 0; *srcp = src + i; - return len; + *lenp = len; + return TRUE; } static struct data_struct * @@ -333,11 +347,12 @@ insert_byte (bfd *abfd, int value, bfd_vma addr) /* The first pass is to find the names of all the sections, and see how big the data is. */ -static void +static bfd_boolean first_phase (bfd *abfd, int type, char *src) { asection *section = bfd_abs_section_ptr; unsigned int len; + bfd_vma val; char sym[17]; /* A symbol can only be 16chars long. */ switch (type) @@ -345,7 +360,10 @@ first_phase (bfd *abfd, int type, char *src) case '6': /* Data record - read it and store it. */ { - bfd_vma addr = getvalue (&src); + bfd_vma addr; + + if (!getvalue (&src, &addr)) + return FALSE; while (*src) { @@ -355,17 +373,18 @@ first_phase (bfd *abfd, int type, char *src) } } - return; + return TRUE; case '3': /* Symbol record, read the segment. */ - len = getsym (sym, &src); + if (!getsym (sym, &src, &len)) + return FALSE; section = bfd_get_section_by_name (abfd, sym); if (section == NULL) { char *n = bfd_alloc (abfd, (bfd_size_type) len + 1); if (!n) - abort (); /* FIXME. */ + return FALSE; memcpy (n, sym, len + 1); section = bfd_make_section (abfd, n); } @@ -375,8 +394,11 @@ first_phase (bfd *abfd, int type, char *src) { case '1': /* Section range. */ src++; - section->vma = getvalue (&src); - section->size = getvalue (&src) - section->vma; + if (!getvalue (&src, §ion->vma)) + return FALSE; + if (!getvalue (&src, &val)) + return FALSE; + section->size = val - section->vma; section->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC; break; case '0': @@ -393,35 +415,42 @@ first_phase (bfd *abfd, int type, char *src) char stype = (*src); if (!new) - abort (); /* FIXME. */ + return FALSE; new->symbol.the_bfd = abfd; src++; abfd->symcount++; abfd->flags |= HAS_SYMS; new->prev = abfd->tdata.tekhex_data->symbols; abfd->tdata.tekhex_data->symbols = new; - len = getsym (sym, &src); + if (!getsym (sym, &src, &len)) + return FALSE; new->symbol.name = bfd_alloc (abfd, (bfd_size_type) len + 1); if (!new->symbol.name) - abort (); /* FIXME. */ + return FALSE; memcpy ((char *) (new->symbol.name), sym, len + 1); new->symbol.section = section; if (stype <= '4') new->symbol.flags = (BSF_GLOBAL | BSF_EXPORT); else new->symbol.flags = BSF_LOCAL; - new->symbol.value = getvalue (&src) - section->vma; + if (!getvalue (&src, &val)) + return FALSE; + new->symbol.value = val - section->vma; } + default: + return FALSE; } } } + + return TRUE; } /* Pass over a tekhex, calling one of the above functions on each record. */ -static void -pass_over (bfd *abfd, void (*func) (bfd *, int, char *)) +static bfd_boolean +pass_over (bfd *abfd, bfd_boolean (*func) (bfd *, int, char *)) { unsigned int chars_on_line; bfd_boolean eof = FALSE; @@ -462,8 +491,11 @@ pass_over (bfd *abfd, void (*func) (bfd *, int, char *)) /* Put a null at the end. */ src[chars_on_line] = 0; - func (abfd, type, src); + if (!func (abfd, type, src)) + return FALSE; } + + return TRUE; } static long @@ -524,7 +556,9 @@ tekhex_object_p (bfd *abfd) tekhex_mkobject (abfd); - pass_over (abfd, first_phase); + if (!pass_over (abfd, first_phase)) + return NULL; + return abfd->xvec; } @@ -717,7 +751,6 @@ out (bfd *abfd, int type, char *start, char *end) static bfd_boolean tekhex_write_object_contents (bfd *abfd) { - int bytes_written; char buffer[100]; asymbol **p; asection *s; @@ -725,8 +758,6 @@ tekhex_write_object_contents (bfd *abfd) tekhex_init (); - bytes_written = 0; - /* And the raw data. */ for (d = abfd->tdata.tekhex_data->data; d != NULL; diff --git a/bfd/version.h b/bfd/version.h index 8957708..4f0f1d5 100644 --- a/bfd/version.h +++ b/bfd/version.h @@ -1,3 +1,3 @@ -#define BFD_VERSION_DATE 20060420 +#define BFD_VERSION_DATE 20060512 #define BFD_VERSION @bfd_version@ #define BFD_VERSION_STRING @bfd_version_string@ @@ -487,7 +487,7 @@ vms_new_section_hook (bfd * abfd, asection *section) vms_debug (7, "%d: %s\n", section->index, section->name); #endif - return TRUE; + return _bfd_generic_new_section_hook (abfd, section); } /* Read the contents of a section. diff --git a/config.guess b/config.guess index 17690ae..7149b1b 100755 --- a/config.guess +++ b/config.guess @@ -1,9 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. -timestamp='2006-01-02' +timestamp='2006-04-26' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -106,7 +107,7 @@ set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; @@ -770,6 +771,8 @@ EOF case ${UNAME_MACHINE} in pc98) echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac @@ -788,7 +791,10 @@ EOF echo ${UNAME_MACHINE}-pc-pw32 exit ;; x86:Interix*:[345]*) - echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T:Interix*:[345]*) + echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks @@ -859,7 +865,11 @@ EOF #endif #endif EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '/^CPU/{s: ::g;p;}'`" + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; mips64:Linux:*:*) @@ -878,7 +888,11 @@ EOF #endif #endif EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '/^CPU/{s: ::g;p;}'`" + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) @@ -975,7 +989,7 @@ EOF LIBC=gnulibc1 # endif #else - #if defined(__INTEL_COMPILER) || defined(__PGI) + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__sun) LIBC=gnu #else LIBC=gnuaout @@ -985,7 +999,11 @@ EOF LIBC=dietlibc #endif EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '/^LIBC/{s: ::g;p;}'`" + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" test x"${LIBC}" != x && { echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit @@ -1,9 +1,10 @@ #! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. -timestamp='2006-01-02' +timestamp='2006-05-12' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -248,7 +249,8 @@ case $basic_machine in | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ - | m32r | m32rle | m68000 | m68k | m88k | maxq | mb | microblaze | mcore \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ @@ -268,16 +270,17 @@ case $basic_machine in | mn10200 | mn10300 \ | mt \ | msp430 \ + | nios | nios2 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ - | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b \ - | strongarm \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ @@ -285,9 +288,6 @@ case $basic_machine in | z8k) basic_machine=$basic_machine-unknown ;; - m32c) - basic_machine=$basic_machine-unknown - ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown @@ -328,7 +328,7 @@ case $basic_machine in | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ - | m32r-* | m32rle-* \ + | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ @@ -350,17 +350,18 @@ case $basic_machine in | mmix-* \ | mt-* \ | msp430-* \ + | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tron-* \ @@ -371,8 +372,6 @@ case $basic_machine in | ymp-* \ | z8k-*) ;; - m32c-*) - ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) @@ -1126,7 +1125,7 @@ case $basic_machine in sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; - sparc | sparcv8 | sparcv9 | sparcv9b) + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) @@ -2360,8 +2360,8 @@ else fi rm -f conftest* LIBS="$saved_LIBS" - CFLAGS="$saved_CFLAGS" fi +CFLAGS="$saved_CFLAGS" # Flags needed for both GMP and/or MPFR diff --git a/configure.in b/configure.in index cdfa7d8..e3e3500 100644 --- a/configure.in +++ b/configure.in @@ -1142,8 +1142,8 @@ if test x"$have_gmp" = xyes; then #include <mpfr.h>], [mpfr_t n; mpfr_init(n);], [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no]); have_gmp=no]) LIBS="$saved_LIBS" - CFLAGS="$saved_CFLAGS" fi +CFLAGS="$saved_CFLAGS" # Flags needed for both GMP and/or MPFR AC_SUBST(gmplibs) diff --git a/etc/ChangeLog b/etc/ChangeLog index 0d2b80c..09d002f 100644 --- a/etc/ChangeLog +++ b/etc/ChangeLog @@ -1,3 +1,7 @@ +2006-05-02 Daniel Jacobowitz <dan@codesourcery.com> + + * texi2pod.pl: Handle -I. + 2006-04-06 Carlos O'Donell <carlos@codesourcery.com> * Makefile.in: Add install-html target. Add htmldir, diff --git a/etc/texi2pod.pl b/etc/texi2pod.pl index 9696a12..57d1d5b 100644 --- a/etc/texi2pod.pl +++ b/etc/texi2pod.pl @@ -36,6 +36,7 @@ $shift = ""; $fnno = 1; $inf = ""; $ibase = ""; +@ipath = (); while ($_ = shift) { if (/^-D(.*)$/) { @@ -51,6 +52,13 @@ while ($_ = shift) { die "flags may only contain letters, digits, hyphens, dashes and underscores\n" unless $flag =~ /^[a-zA-Z0-9_-]+$/; $defs{$flag} = $value; + } elsif (/^-I(.*)$/) { + if ($1 ne "") { + $flag = $1; + } else { + $flag = shift; + } + push (@ipath, $flag); } elsif (/^-/) { usage(); } else { @@ -229,10 +237,12 @@ while(<$inf>) { $inf = gensym(); $file = postprocess($1); - # Try cwd and $ibase. - open($inf, "<" . $file) - or open($inf, "<" . $ibase . "/" . $file) - or die "cannot open $file or $ibase/$file: $!\n"; + # Try cwd and $ibase, then explicit -I paths. + $done = 0; + foreach $path (".", $ibase, @ipath) { + open($inf, "<" . $path . "/" . $file) and ($done = 1, last); + } + die "cannot find $file" if !$done; next; }; diff --git a/gdb/ChangeLog b/gdb/ChangeLog index dcb436b..6842b6b 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,210 @@ +2006-05-11 Alfred M. Szmidt <ams@gnu.org> + + * gnu-nat.c (inf_validate_procs): Don't use lvalue in assignments. + +2006-05-11 Fred Fish <fnf@specifix.com> + + * symtab.c (skip_prologue_using_sal): Handle single line functions + like "foo(){}", which may optimize down to a single return inst. + +2006-05-10 Steve Ellcey <sje@cup.hp.com> + + * hppa-hpux-tdep.c (initialize_hp_cxx_exception_support): Remove + message. + +2006-05-09 Andreas Schwab <schwab@suse.de> + + * dwarf2-frame.c (struct dwarf2_fde): Add eh_frame_p. + (execute_cfa_program): Add parameter eh_frame_p. Call + dwarf2_frame_eh_frame_regnum when true. + (dwarf2_frame_cache): Pass eh_frame_p from fde to + execute_cfa_program. + (decode_frame_entry_1): Call dwarf2_frame_eh_frame_regnum when + processing .eh_frame. Copy eh_frame_p to the new fde. + (struct dwarf2_frame_ops): Add eh_frame_regnum. + (dwarf2_frame_set_eh_frame_regnum): Define. + (dwarf2_frame_eh_frame_regnum): Define. + + * dwarf2-frame.h (dwarf2_frame_set_eh_frame_regnum): Declare. + (dwarf2_frame_eh_frame_regnum): Declare. + +2006-05-06 David S. Miller <davem@sunset.davemloft.net> + + * linux-nat.c (linux_nat_do_thread_registers): Check for + NULL collect_regset method. + +2006-05-06 Ulrich Weigand <uweigand@de.ibm.com> + + * s390-tdep.c (s390_collect_regset): New function. + (s390_gregset, s390x_gregset, s390_fpregset): Add it. + +2006-05-06 Nick Roberts <nickrob@snap.net.nz> + + * dwarf2read.c: Make LOC_OPTIMIZED_OUT the default value for a + symbol. + +2006-05-05 Ulrich Weigand <uweigand@de.ibm.com> + + * linux-nat.c (exit_lwp): Fix NULL pointer access. + (linux_nat_handle_extended): New parameter STOPPING. + (wait_lwp): Call it with STOPPING equals 1. + (linux_nat_wait): Call it with STOPPING equals 0. + +2006-05-05 Ulrich Weigand <uweigand@de.ibm.com> + + * linux-nat.c (linux_nat_wait): Do not short-cut reporting + of 'uninteresting' signals when single-stepping. + +2006-05-05 Daniel Jacobowitz <dan@codesourcery.com> + + * MAINTAINERS: Move NEWS to the documentation entry. + +2006-05-05 David S. Miller <davem@sunset.davemloft.net> + + * linux-nat.c (linux_nat_do_thread_registers): Use the + regset_from_core_section infrastructure if the target + supports it. + * Makefile.in: Update dependencies. + * linux-thread-db.c (thread_db_store_registers): Use + regcache_raw_collect. + +2006-05-05: Paul Gilliam <pgilliam@us.ibm.com> + + * ppc-linux-nat.c: Clean up types for ptrace. + Replace (CORE_ADDR) with (uintptr_t) to avoid the size difference + between a CORE_ADDR and a void* on ppc64 systems compiled for 32-bits. + +2006-05-05 Daniel Jacobowitz <dan@codesourcery.com> + + * remote.c (remote_disconnect): Add TARGET argument. + * target.c (debug_to_disconnect): Delete. + (update_current_target): Do not inherit to_disconnect. + (target_disconnect): Search for a target to implement to_disconnect. + (setup_target_debug): Do not reference to_disconnect. + * target.h (struct target_ops): Add target argument to + to_disconnect. + +2006-05-06 Fred Fish <fnf@specifix.com> + + * mips-tdep.c (mips_o64_push_dummy_call): Left shift big endian + structs or unions independent of ABI register size. + +2006-05-06 Fred Fish <fnf@specifix.com> + + * mips-tdep.c (mips_o64_return_value): Replace stub that always + returned RETURN_VALUE_STRUCT_CONVENTION with a real function. + +2006-05-05 Daniel Jacobowitz <dan@codesourcery.com> + + * mi/mi-main.c (captured_mi_execute_command): Check the return + value of -interpreter-exec. + +2006-05-03 Vladimir Prus <ghost@cs.msu.su> + + * varobj.c (c_value_of_variable): Ignore top-level references. + (Committed by Jim Blandy.) + +2006-04-30 Mark Kettenis <kettenis@gnu.org> + + * breakpoint.c (insert_single_step_breakpoint): Make a failure to + insert a single-step breakpoint an error instead of a warning. + +2006-05-01 Nathan J. Williams <nathanw@wasabisystems.com> + + * ppcnbsd-tdep.c (ppcnbsd_return_value): Change type of last two + arguments from void * to gdb_byte *. + +2006-04-26 Michael Snyder <msnyder@redhat.com> + + * linux-fork.c (_initialize_linux_fork): Rename "delete-fork" + command to "delete fork" (no hyphen), compatible with other + "delete" commands. + (info_forks_command): Accept a fork ID argument, for info + on a single fork. Report if no matching forks. + +2006-04-25 Mark Kettenis <kettenis@gnu.org> + + * breakpoint.c (remove_single_step_breakpoints): Bail out early if + no breakpoints are inserted. + + From Masaki MURANAKA <monaka@monami-software.com>: + * mips-mdebug-tdep.c (mips_mdebug_frame_prev_register): Change + type of last argument to `gdb_byte *' + +2006-04-25 Jim Blandy <jimb@codesourcery.com> + + Add support for 'target remote |' on MinGW. + * ser-mingw.c (struct pipe_state): New structure. + (make_pipe_state, free_pipe_state, cleanup_pipe_state) + (pipe_windows_open, pipe_windows_close, pipe_windows_read) + (pipe_windows_write, pipe_wait_handle): New functions. + (_initialize_ser_windows): Register a "pipe" interface based on + them. + +2006-04-24 Daniel Jacobowitz <dan@codesourcery.com> + + * ser-mingw.c: Include <conio.h>. + (struct ser_console_state, struct net_windows_state): Add exit_select, + have_stopped, thread. + (pipe_select_thread, console_select_thread) + (net_windows_select_thread): Don't create a local state copy or + close stop_select. Exit on exit_select instead of stop_select. Set + have_stopped. + (console_select_thread): Don't report control keypresses as pending + input. + (pipe_select_thread): Allow stop_select to interrupt sleeping. + (set_console_wait_handle): Create exit_select and have_stopped. + Save the thread handle. Check _kbhit before starting a thread. + (ser_console_done_wait_handle): New. + (ser_console_close): Close new handles. Wait for the thread to + exit. + (new_windows_select_thread): Assert that an event occurred. + (net_windows_wait_handle): Check for pending input before starting + a thread. + (net_windows_done_wait_handle): New. + (net_windows_open): Create exit_select and have_stopped. + Save the thread handle. + (net_windows_close): Close new handles. Wait for the thread to + exit. + (_intiialize_ser_windows): Register done_wait_handle methods. + + * serial.c [USE_WIN32API] (serial_done_wait_handle): New. + * serial.h [USE_WIN32API] (struct serial_ops): Add done_wait_handle. + [USE_WIN32API] (serial_done_wait_handle): New prototype. + * mingw-hdep.c (gdb_select): Use serial_done_wait_handle. + +2006-04-23 Andreas Schwab <schwab@suse.de> + + * rs6000-tdep.c: Include "reggroups.h" only once. + * Makefile.in (rs6000-tdep.o): Update dependencies. + +2006-04-21 Frederic Riss <frederic.riss@st.com> + + * dwarf2read.c (dwarf2_start_subfile): Change prototype to accept + compilation directory as last argument. + Always pass comp_dir as second argument to start_subfile and prepend + dirname to the filename when necessary. + Remove now superfluous search for pre-existing subfile. + (dwarf_decode_lines): Pass the compilation directory to + dwarf2_start_subfile. + +2006-04-20 Michael Snyder <msnyder@redhat.com> + + * 2006-03-22 Jim Blandy <jimb@redhat.com> + Add support for the Renesas M32C and M16C. + + * configure.tgt (m32c-*-*): New entry. + * config/m32c/m32c.mt: New file. + * m32c-tdep.c: New file. + * Makefile.in (elf_m32c_h): New variable. + (m32c-tdep.o): New rule. + * NEWS: Mention new target. + * MAINTAINERS: Designate Jim Blandy as responsible maintainer. + +2006-04-20 Michael Snyder <msnyder@redhat.com> + + * remote.c: Fix spelling error in comment. + 2006-04-20 Daniel Jacobowitz <dan@codesourcery.com> * m68klinux-tdep.c (m68k_linux_sigtramp_frame_prev_register): diff --git a/gdb/MAINTAINERS b/gdb/MAINTAINERS index dbd2f93..4ed438a 100644 --- a/gdb/MAINTAINERS +++ b/gdb/MAINTAINERS @@ -266,6 +266,9 @@ the native maintainer when resolving ABI issues. ia64 --target=ia64-linux-gnu ,-Werror (--target=ia64-elf broken) + m32c --target=m32c-elf ,-Werror + Jim Blandy, jimb@codesourcery.com + m32r --target=m32r-elf ,-Werror m68hc11 --target=m68hc11-elf ,-Werror , @@ -351,6 +354,7 @@ language support shared libs Kevin Buettner kevinb@redhat.com documentation Eli Zaretskii eliz@gnu.org + (including NEWS) testsuite gdbtk (gdb.gdbtk) Keith Seitz keiths@redhat.com threads (gdb.threads) Michael Snyder msnyder@redhat.com @@ -372,8 +376,6 @@ Makefile.in, configure* ALL mmalloc/ ALL Host maintainers -NEWS ALL - sim/ See sim/MAINTAINERS readline/ Master version: ftp://ftp.cwru.edu/pub/bash/ diff --git a/gdb/Makefile.in b/gdb/Makefile.in index beab57c..a8b58a1 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -582,6 +582,7 @@ elf_sh_h = $(INCLUDE_DIR)/elf/sh.h elf_arm_h = $(INCLUDE_DIR)/elf/arm.h $(elf_reloc_macros_h) elf_bfd_h = $(BFD_SRC)/elf-bfd.h elf_frv_h = $(INCLUDE_DIR)/elf/frv.h $(elf_reloc_macros_h) +elf_m32c_h = $(INCLUDE_DIR)/elf/m32c.h $(elf_reloc_macros_h) libaout_h = $(BFD_SRC)/libaout.h libiberty_h = $(INCLUDE_DIR)/libiberty.h libbfd_h = $(BFD_SRC)/libbfd.h @@ -598,6 +599,7 @@ gdb_callback_h = $(INCLUDE_DIR)/gdb/callback.h gdb_sim_arm_h = $(INCLUDE_DIR)/gdb/sim-arm.h gdb_sim_d10v_h = $(INCLUDE_DIR)/gdb/sim-d10v.h gdb_sim_frv_h = $(INCLUDE_DIR)/gdb/sim-frv.h +gdb_sim_m32c_h = $(INCLUDE_DIR)/gdb/sim-m32c.h gdb_sim_ppc_h = $(INCLUDE_DIR)/gdb/sim-ppc.h gdb_sim_sh_h = $(INCLUDE_DIR)/gdb/sim-sh.h splay_tree_h = $(INCLUDE_DIR)/splay-tree.h @@ -2196,8 +2198,8 @@ linux-fork.o: linux-fork.c $(defs_h) $(inferior_h) $(regcache_h) $(gdbcmd_h) \ $(linux_nat_h) linux-nat.o: linux-nat.c $(defs_h) $(inferior_h) $(target_h) $(gdb_string_h) \ $(gdb_wait_h) $(gdb_assert_h) $(linux_nat_h) $(gdbthread_h) \ - $(gdbcmd_h) $(regcache_h) $(inf_ptrace_h) $(auxv_h) $(elf_bfd_h) \ - $(gregset_h) $(gdbcore_h) $(gdbthread_h) $(gdb_stat_h) \ + $(gdbcmd_h) $(regcache_h) $(regset_h) $(inf_ptrace_h) $(auxv_h) \ + $(elf_bfd_h) $(gregset_h) $(gdbcore_h) $(gdbthread_h) $(gdb_stat_h) \ $(linux_fork_h) linux-thread-db.o: linux-thread-db.c $(defs_h) $(gdb_assert_h) \ $(gdb_proc_service_h) $(gdb_thread_db_h) $(bfd_h) $(exceptions_h) \ @@ -2215,6 +2217,11 @@ m2-typeprint.o: m2-typeprint.c $(defs_h) $(bfd_h) $(symtab_h) $(gdbtypes_h) \ $(expression_h) $(value_h) $(gdbcore_h) $(target_h) $(m2_lang_h) m2-valprint.o: m2-valprint.c $(defs_h) $(symtab_h) $(gdbtypes_h) \ $(m2_lang_h) $(c_lang_h) +m32c-tdep.o: m32c-tdep.c $(defs_h) $(gdb_assert_h) $(elf_bfd_h) \ + $(elf_m32c_h) $(gdb_sim_m32c_h) $(dis_asm_h) $(gdbtypes_h) \ + $(regcache_h) $(arch_utils_h) $(frame_h) $(frame_unwind_h) \ + $(dwarf2_frame_h) $(dwarf2expr_h) $(symtab_h) $(gdbcore_h) \ + $(value_h) $(reggroups_h) $(prologue_value_h) $(target_h) m32r-linux-nat.o: m32r-linux-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \ $(regcache_h) $(linux_nat_h) $(gdb_assert_h) $(gdb_string_h) \ $(gregset_h) $(m32r_tdep_h) $(target_h) @@ -2508,7 +2515,7 @@ rs6000-tdep.o: rs6000-tdep.c $(defs_h) $(frame_h) $(inferior_h) $(symtab_h) \ $(reggroups_h) $(libbfd_h) $(coff_internal_h) $(libcoff_h) \ $(coff_xcoff_h) $(libxcoff_h) $(elf_bfd_h) $(solib_svr4_h) \ $(ppc_tdep_h) $(gdb_assert_h) $(dis_asm_h) $(trad_frame_h) \ - $(frame_unwind_h) $(frame_base_h) $(reggroups_h) $(rs6000_tdep_h) + $(frame_unwind_h) $(frame_base_h) $(rs6000_tdep_h) rs6000-aix-tdep.o: rs6000-aix-tdep.c $(defs_h) $(osabi_h) $(rs6000_tdep_h) s390-nat.o: s390-nat.c $(defs_h) $(tm_h) $(regcache_h) $(inferior_h) \ $(s390_tdep_h) $(target_h) $(linux_nat_h) @@ -3,6 +3,12 @@ *** Changes since GDB 6.4 +* New targets + +Renesas M32C/M16C m32c-elf + +Morpho Technologies ms1 ms1-elf + * New commands init-if-undefined Initialize a convenience variable, but diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 130b684..fd231de 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -7717,7 +7717,7 @@ insert_single_step_breakpoint (CORE_ADDR next_pc) *bpt_p = deprecated_insert_raw_breakpoint (next_pc); if (*bpt_p == NULL) - warning (_("Could not insert single-step breakpoint at 0x%s"), + error (_("Could not insert single-step breakpoint at 0x%s"), paddr_nz (next_pc)); } diff --git a/gdb/config/m32c/m32c.mt b/gdb/config/m32c/m32c.mt new file mode 100644 index 0000000..2a404d4 --- /dev/null +++ b/gdb/config/m32c/m32c.mt @@ -0,0 +1,7 @@ +# Target: Renesas M32C family +TDEPFILES = m32c-tdep.o prologue-value.o + +# There may also be a SID / CGEN simulator for this, but we do have DJ +# Delorie's mini-sim. +SIM_OBS = remote-sim.o +SIM = ../sim/m32c/libsim.a diff --git a/gdb/configure.tgt b/gdb/configure.tgt index 4092fe1..f6e1ad8 100644 --- a/gdb/configure.tgt +++ b/gdb/configure.tgt @@ -107,6 +107,8 @@ ia64*-*-*) gdb_target=ia64 ;; iq2000-*-*) gdb_target=iq2000 ;; +m32c-*-*) gdb_target=m32c ;; + m32r*-*-linux*) gdb_target=linux ;; m32r*-*-*) gdb_target=m32r ;; diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 66ff9d7..f759123 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,34 @@ +2006-05-10 Daniel Jacobowitz <dan@codesourcery.com> + + * agentexpr.texi: Add a copyright and license notice. + * observer.texi: Likewise, with GPL clause for function prototypes. + Remove trailing whitespace. + +2006-05-05 Jim Blandy <jimb@codesourcery.com> + + * gdb.texinfo (General Query Packets): Document conventions for + terminating packet names, and their violations. + +2006-05-05 Daniel Jacobowitz <dan@codesourcery.com> + + * Makefile.in (GDB_DOC_SOURCE_INCLUDES): Update for readline 5.1. + * gdb.texinfo: Likewise. + +2006-05-05 Daniel Jacobowitz <dan@codesourcery.com> + + * gdb.texinfo (Remote Configuration): Remove "set remotedebug" + and "show remotedebug". + (Debugging Output): Add additional index entries. + +2006-04-27 Michael Snyder <msnyder@redhat.com> + + * gdb.texinfo (delete-fork): Command renamed to "delete fork". + +2006-04-22 Andrew Cagney <cagney@redhat.com> + + * gdb.texinfo (Contributors): Credit frame unwinder contributors. + * gdbint.texinfo (Algorithms): Fix errors in frame documentation. + 2006-04-18 Daniel Jacobowitz <dan@codesourcery.com> * gdbint.texinfo (x86 Watchpoints, Target Conditionals): Update insert diff --git a/gdb/doc/Makefile.in b/gdb/doc/Makefile.in index 22782f6..13792e1 100644 --- a/gdb/doc/Makefile.in +++ b/gdb/doc/Makefile.in @@ -101,7 +101,7 @@ GDB_DOC_SOURCE_INCLUDES = \ $(srcdir)/fdl.texi \ $(srcdir)/gpl.texi \ $(srcdir)/agentexpr.texi \ - $(READLINE_DIR)/rluser.texinfo \ + $(READLINE_DIR)/rluser.texi \ $(READLINE_DIR)/inc-hist.texinfo GDB_DOC_BUILD_INCLUDES = \ gdb-cfg.texi \ diff --git a/gdb/doc/agentexpr.texi b/gdb/doc/agentexpr.texi index c40259d..c1eefbc 100644 --- a/gdb/doc/agentexpr.texi +++ b/gdb/doc/agentexpr.texi @@ -5,6 +5,13 @@ @c @setchapternewpage off @c %**end of header +@c This file is part of the GDB manual. +@c +@c Copyright (C) 2003, 2004, 2005, 2006 +@c Free Software Foundation, Inc. +@c +@c See the file gdb.texinfo for copying conditions. + @c Revision: $Id$ @node Agent Expressions diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 790c58d..e2b986a 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -484,6 +484,19 @@ Sakamoto, Yoshinori Sato, Michael Snyder, Andreas Schwab, Jason Thorpe, Corinna Vinschen, Ulrich Weigand, and Elena Zannoni, helped with the migration of old architectures to this new framework. +Andrew Cagney completely re-designed and re-implemented @value{GDBN}'s +unwinder framework, this consisting of a fresh new design featuring +frame IDs, independent frame sniffers, and the sentinel frame. Mark +Kettenis implemented the @sc{dwarf 2} unwinder, Jeff Johnston the +libunwind unwinder, and Andrew Cagney the dummy, sentinel, tramp, and +trad unwinders. The architecture specific changes, each involving a +complete rewrite of the architecture's frame code, were carried out by +Jim Blandy, Joel Brobecker, Kevin Buettner, Andrew Cagney, Stephane +Carrez, Randolph Chung, Orjan Friberg, Richard Henderson, Daniel +Jacobowitz, Jeff Johnston, Mark Kettenis, Theodore A. Roth, Kei +Sakamoto, Yoshinori Sato, Michael Snyder, Corinna Vinschen, and Ulrich +Weigand. + @node Sample Session @chapter A Sample @value{GDBN} Session @@ -2563,7 +2576,7 @@ as shown in the first field of the @samp{info forks} display. To quit debugging one of the forked processes, you can either detach from it by using the @w{@code{detach-fork}} command (allowing it to run independently), or delete (and kill) it using the -@w{@code{delete-fork}} command. +@w{@code{delete fork}} command. @table @code @kindex detach-fork @var{fork-id} @@ -2572,8 +2585,8 @@ Detach from the process identified by @value{GDBN} fork number @var{fork-id}, and remove it from the fork list. The process will be allowed to run independently. -@kindex delete-fork @var{fork-id} -@item delete-fork @var{fork-id} +@kindex delete fork @var{fork-id} +@item delete fork @var{fork-id} Kill the process identified by @value{GDBN} fork number @var{fork-id}, and remove it from the fork list. @@ -2662,8 +2675,8 @@ are not affected by restoring a checkpoint. In general, a checkpoint only restores things that reside in the program being debugged, not in the debugger. -@kindex delete-checkpoint @var{checkpoint-id} -@item delete-checkpoint @var{checkpoint-id} +@kindex delete checkpoint @var{checkpoint-id} +@item delete checkpoint @var{checkpoint-id} Delete the previously-saved checkpoint identified by @var{checkpoint-id}. @end table @@ -12439,17 +12452,6 @@ expect to see @samp{Ctrl-C} as the interrupt signal. Show whether @value{GDBN} sends @code{BREAK} or @samp{Ctrl-C} to interrupt the remote program. -@item set remotedebug -@cindex debug remote protocol -@cindex remote protocol debugging -@cindex display remote packets -Control the debugging of the remote protocol. When enabled, each -packet sent to or received from the remote target is displayed. The -defaults is off. - -@item show remotedebug -Show the current setting of the remote protocol debugging. - @item set remotedevice @var{device} @cindex serial port name Set the name of the serial port through which to communicate to the @@ -15934,6 +15936,9 @@ Displays the current state of displaying @value{GDBN} C@t{++} overload debugging info. @cindex packets, reporting on stdout @cindex serial connections, debugging +@cindex debug remote protocol +@cindex remote protocol debugging +@cindex display remote packets @item set debug remote Turns on or off display of reports on all packets sent back and forth across the serial line to the remote machine. The info is printed on the @@ -21662,7 +21667,7 @@ things without first using the debugger to find the facts. @c inc-hist.texinfo @c Use -I with makeinfo to point to the appropriate directory, @c environment var TEXINPUTS with TeX. -@include rluser.texinfo +@include rluser.texi @include inc-hist.texinfo @@ -23093,9 +23098,14 @@ the Acme Corporation might begin with @samp{qacme.foo} (for querying foos) or @samp{Qacme.bar} (for setting bars). @end itemize -A query or set packet may optionally be followed by a @samp{,} or -@samp{;} separated list. Stubs must be careful to match the full -packet name, in case packet names have common prefixes. +The name of a query or set packet should be separated from any +parameters by a @samp{:}; the parameters themselves should be +separated by @samp{,} or @samp{;}. Stubs must be careful to match the +full packet name, in case packet names have common prefixes. New +packets should not begin with @samp{qP} or @samp{qL}@footnote{The +@samp{qP} and @samp{qL} packets predate these conventions, and don't +have any terminator for the packet name; we suspect they are in +widespread use in places that are difficult to upgrade.}. Like the descriptions of the other packets, each description here has a template showing the packet's overall syntax, followed by an @@ -23239,6 +23249,9 @@ Reply: Returns information on @var{threadid}. Where: @var{mode} is a hex encoded 32 bit mode; @var{threadid} is a hex encoded 64 bit thread ID. +Don't use this packet; use the @samp{qThreadExtraInfo} query instead +(see below). + Reply: see @code{remote.c:remote_unpack_thread_info_response()}. @item qPart:@var{object}:read:@var{annex}:@var{offset},@var{length} @@ -23250,6 +23263,9 @@ starting at @var{offset} bytes into the data. The content and encoding of @var{annex} is specific to the object; it can supply additional details about what data to access. +Since this packet is ambiguous with the older @code{qP} packet, we +plan to rename it. + Here are the specific requests of this form defined so far. All @samp{qPart:@var{object}:read:@dots{}} requests use the same reply formats, listed below. @@ -23341,6 +23357,11 @@ Indicate a badly formed request. An empty reply indicates that @samp{qRcmd} is not recognized. @end table +(Note that the @code{qRcmd} packet's name is separated from the +command by a @samp{,}, not a @samp{:}, contrary to the naming +conventions above. Please don't use this packet as a model for new +packets.) + @item qSymbol:: @cindex symbol lookup, remote request @cindex @samp{qSymbol} packet @@ -23401,6 +23422,11 @@ comprising the printable string containing the extra information about the thread's attributes. @end table +(Note that the @code{qThreadExtraInfo} packet's name is separated from +the command by a @samp{,}, not a @samp{:}, contrary to the naming +conventions above. Please don't use this packet as a model for new +packets.) + @item QTStart @itemx QTStop @itemx QTinit diff --git a/gdb/doc/gdbint.texinfo b/gdb/doc/gdbint.texinfo index e1d1557..7bbd417 100644 --- a/gdb/doc/gdbint.texinfo +++ b/gdb/doc/gdbint.texinfo @@ -232,25 +232,21 @@ A frame is a construct that @value{GDBN} uses to keep track of calling and called functions. @cindex frame, unwind -@value{GDBN}'s current frame model is the result of an incremental -cleanup of working code, not a fresh design, so it's a little weird. - -The natural model would have a frame object, with methods that read -and write that frame's registers. Reading or writing the youngest -frame's registers would simply read or write the processor's current -registers, since the youngest frame is running directly on the -processor. Older frames might have some registers saved on the stack -by younger frames, so accessing the older frames' registers would do a -mix of memory accesses and register accesses, as appropriate. +@value{GDBN}'s frame model, a fresh design, was implemented with the +need to support @sc{dwarf}'s Call Frame Information in mind. In fact, +the term ``unwind'' is taken directly from that specification. +Developers wishing to learn more about unwinders, are encouraged to +read the the @sc{dwarf} specification. @findex frame_register_unwind -Instead, @value{GDBN}'s model is that you find a frame's registers by -``unwinding'' them from the next younger frame. That is, to access -the registers of frame #1 (the next-to-youngest frame), you actually -apply @code{frame_register_unwind} to frame #0 (the youngest frame). -But then the obvious question is: how do you access the registers of -the youngest frame itself? How do you ``unwind'' them when they're -not wound up? +@findex get_frame_register +@value{GDBN}'s model is that you find a frame's registers by +``unwinding'' them from the next younger frame. That is, +@samp{get_frame_register} which returns the value of a register in +frame #1 (the next-to-youngest frame), is implemented by calling frame +#0's @code{frame_register_unwind} (the youngest frame). But then the +obvious question is: how do you access the registers of the youngest +frame itself? @cindex sentinel frame @findex get_frame_type @@ -261,32 +257,6 @@ the current values of the youngest real frame's registers. If @var{f} is a sentinel frame, then @code{get_frame_type (@var{f}) == SENTINEL_FRAME}. -@findex create_new_frame -@vindex FRAME_FP -@code{FRAME_FP} in the machine description has no meaning to the -machine-independent part of @value{GDBN}, except that it is used when -setting up a new frame from scratch, as follows: - -@smallexample -create_new_frame (read_register (DEPRECATED_FP_REGNUM), read_pc ())); -@end smallexample - -@cindex frame pointer register -Other than that, all the meaning imparted to @code{DEPRECATED_FP_REGNUM} -is imparted by the machine-dependent code. So, -@code{DEPRECATED_FP_REGNUM} can have any value that is convenient for -the code that creates new frames. (@code{create_new_frame} calls -@code{DEPRECATED_INIT_EXTRA_FRAME_INFO} if it is defined; that is where -you should use the @code{DEPRECATED_FP_REGNUM} value, if your frames are -nonstandard.) - -@cindex frame chain -Given a @value{GDBN} frame, define @code{DEPRECATED_FRAME_CHAIN} to -determine the address of the calling function's frame. This will be -used to create a new @value{GDBN} frame struct, and then -@code{DEPRECATED_INIT_EXTRA_FRAME_INFO} and -@code{DEPRECATED_INIT_FRAME_PC} will be called for the new frame. - @section Prologue Analysis @cindex prologue analysis diff --git a/gdb/doc/observer.texi b/gdb/doc/observer.texi index 2d1c9f4..b9d5777 100644 --- a/gdb/doc/observer.texi +++ b/gdb/doc/observer.texi @@ -1,4 +1,19 @@ @c -*-texinfo-*- + +@c This file is part of the GDB manual. +@c +@c Copyright (C) 2003, 2004, 2005, 2006 +@c Free Software Foundation, Inc. +@c +@c See the file gdbint.texinfo for copying conditions. +@c +@c Also, the @deftypefun lines from this file are processed into a +@c header file during the GDB build process. Permission is granted +@c to redistribute and/or modify those lines under the terms of the +@c GNU General Public License as published by the Free Software +@c Foundation; either version 2 of the License, or (at your option) +@c any later version. + @node GDB Observers @appendix @value{GDBN} Currently available observers @@ -47,7 +62,7 @@ internal happenings, gdb, Debugging with @var{GDBN}}). @value{GDBN} notifies all @code{normal_stop} observers when the inferior execution has just stopped, the associated messages and annotations have been printed, and the control is about to be returned -to the user. +to the user. Note that the @code{normal_stop} notification is not emitted when the execution stops due to a breakpoint, and this breakpoint has diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index d479da2..3f7fbfe 100644 --- a/gdb/dwarf2-frame.c +++ b/gdb/dwarf2-frame.c @@ -89,6 +89,10 @@ struct dwarf2_fde gdb_byte *instructions; gdb_byte *end; + /* True if this FDE is read from a .eh_frame instead of a .debug_frame + section. */ + unsigned char eh_frame_p; + struct dwarf2_fde *next; }; @@ -267,10 +271,11 @@ execute_stack_op (gdb_byte *exp, ULONGEST len, static void execute_cfa_program (gdb_byte *insn_ptr, gdb_byte *insn_end, struct frame_info *next_frame, - struct dwarf2_frame_state *fs) + struct dwarf2_frame_state *fs, int eh_frame_p) { CORE_ADDR pc = frame_pc_unwind (next_frame); int bytes_read; + struct gdbarch *gdbarch = get_frame_arch (next_frame); while (insn_ptr < insn_end && fs->pc <= pc) { @@ -283,6 +288,8 @@ execute_cfa_program (gdb_byte *insn_ptr, gdb_byte *insn_end, else if ((insn & 0xc0) == DW_CFA_offset) { reg = insn & 0x3f; + if (eh_frame_p) + reg = dwarf2_frame_eh_frame_regnum (gdbarch, reg); insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp); offset = utmp * fs->data_align; dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); @@ -293,6 +300,8 @@ execute_cfa_program (gdb_byte *insn_ptr, gdb_byte *insn_end, { gdb_assert (fs->initial.reg); reg = insn & 0x3f; + if (eh_frame_p) + reg = dwarf2_frame_eh_frame_regnum (gdbarch, reg); dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); if (reg < fs->initial.num_regs) fs->regs.reg[reg] = fs->initial.reg[reg]; @@ -333,6 +342,8 @@ register %s (#%d) at 0x%s"), case DW_CFA_offset_extended: insn_ptr = read_uleb128 (insn_ptr, insn_end, ®); + if (eh_frame_p) + reg = dwarf2_frame_eh_frame_regnum (gdbarch, reg); insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp); offset = utmp * fs->data_align; dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); @@ -343,25 +354,35 @@ register %s (#%d) at 0x%s"), case DW_CFA_restore_extended: gdb_assert (fs->initial.reg); insn_ptr = read_uleb128 (insn_ptr, insn_end, ®); + if (eh_frame_p) + reg = dwarf2_frame_eh_frame_regnum (gdbarch, reg); dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); fs->regs.reg[reg] = fs->initial.reg[reg]; break; case DW_CFA_undefined: insn_ptr = read_uleb128 (insn_ptr, insn_end, ®); + if (eh_frame_p) + reg = dwarf2_frame_eh_frame_regnum (gdbarch, reg); dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); fs->regs.reg[reg].how = DWARF2_FRAME_REG_UNDEFINED; break; case DW_CFA_same_value: insn_ptr = read_uleb128 (insn_ptr, insn_end, ®); + if (eh_frame_p) + reg = dwarf2_frame_eh_frame_regnum (gdbarch, reg); dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAME_VALUE; break; case DW_CFA_register: insn_ptr = read_uleb128 (insn_ptr, insn_end, ®); + if (eh_frame_p) + reg = dwarf2_frame_eh_frame_regnum (gdbarch, reg); insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp); + if (eh_frame_p) + utmp = dwarf2_frame_eh_frame_regnum (gdbarch, utmp); dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_REG; fs->regs.reg[reg].loc.reg = utmp; @@ -405,6 +426,9 @@ bad CFI data; mismatched DW_CFA_restore_state at 0x%s"), paddr (fs->pc)); case DW_CFA_def_cfa_register: insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->cfa_reg); + if (eh_frame_p) + fs->cfa_reg = dwarf2_frame_eh_frame_regnum (gdbarch, + fs->cfa_reg); fs->cfa_how = CFA_REG_OFFSET; break; @@ -426,6 +450,8 @@ bad CFI data; mismatched DW_CFA_restore_state at 0x%s"), paddr (fs->pc)); case DW_CFA_expression: insn_ptr = read_uleb128 (insn_ptr, insn_end, ®); + if (eh_frame_p) + reg = dwarf2_frame_eh_frame_regnum (gdbarch, reg); dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp); fs->regs.reg[reg].loc.exp = insn_ptr; @@ -436,6 +462,8 @@ bad CFI data; mismatched DW_CFA_restore_state at 0x%s"), paddr (fs->pc)); case DW_CFA_offset_extended_sf: insn_ptr = read_uleb128 (insn_ptr, insn_end, ®); + if (eh_frame_p) + reg = dwarf2_frame_eh_frame_regnum (gdbarch, reg); insn_ptr = read_sleb128 (insn_ptr, insn_end, &offset); offset *= fs->data_align; dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); @@ -445,6 +473,9 @@ bad CFI data; mismatched DW_CFA_restore_state at 0x%s"), paddr (fs->pc)); case DW_CFA_def_cfa_sf: insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->cfa_reg); + if (eh_frame_p) + fs->cfa_reg = dwarf2_frame_eh_frame_regnum (gdbarch, + fs->cfa_reg); insn_ptr = read_sleb128 (insn_ptr, insn_end, &offset); fs->cfa_offset = offset * fs->data_align; fs->cfa_how = CFA_REG_OFFSET; @@ -512,6 +543,9 @@ struct dwarf2_frame_ops /* Check whether the frame preceding NEXT_FRAME will be a signal trampoline. */ int (*signal_frame_p) (struct gdbarch *, struct frame_info *); + + /* Convert .eh_frame register number to DWARF register number. */ + int (*eh_frame_regnum) (struct gdbarch *, int); }; /* Default architecture-specific register state initialization @@ -618,6 +652,31 @@ dwarf2_frame_signal_frame_p (struct gdbarch *gdbarch, return 0; return ops->signal_frame_p (gdbarch, next_frame); } + +/* Set the architecture-specific mapping of .eh_frame register numbers to + DWARF register numbers. */ + +void +dwarf2_frame_set_eh_frame_regnum (struct gdbarch *gdbarch, + int (*eh_frame_regnum) (struct gdbarch *, + int)) +{ + struct dwarf2_frame_ops *ops = gdbarch_data (gdbarch, dwarf2_frame_data); + + ops->eh_frame_regnum = eh_frame_regnum; +} + +/* Translate a .eh_frame register to DWARF register. */ + +int +dwarf2_frame_eh_frame_regnum (struct gdbarch *gdbarch, int regnum) +{ + struct dwarf2_frame_ops *ops = gdbarch_data (gdbarch, dwarf2_frame_data); + + if (ops->eh_frame_regnum == NULL) + return regnum; + return ops->eh_frame_regnum (gdbarch, regnum); +} struct dwarf2_frame_cache @@ -686,14 +745,15 @@ dwarf2_frame_cache (struct frame_info *next_frame, void **this_cache) /* First decode all the insns in the CIE. */ execute_cfa_program (fde->cie->initial_instructions, - fde->cie->end, next_frame, fs); + fde->cie->end, next_frame, fs, fde->eh_frame_p); /* Save the initialized register set. */ fs->initial = fs->regs; fs->initial.reg = dwarf2_frame_state_copy_regs (&fs->regs); /* Then decode the insns in the FDE up to our target PC. */ - execute_cfa_program (fde->instructions, fde->end, next_frame, fs); + execute_cfa_program (fde->instructions, fde->end, next_frame, fs, + fde->eh_frame_p); /* Caclulate the CFA. */ switch (fs->cfa_how) @@ -1490,6 +1550,11 @@ decode_frame_entry_1 (struct comp_unit *unit, gdb_byte *start, int eh_frame_p) else cie->return_address_register = read_unsigned_leb128 (unit->abfd, buf, &bytes_read); + if (eh_frame_p) + cie->return_address_register + = dwarf2_frame_eh_frame_regnum (current_gdbarch, + cie->return_address_register); + buf += bytes_read; cie->saw_z_augmentation = (*augmentation == 'z'); @@ -1607,6 +1672,8 @@ decode_frame_entry_1 (struct comp_unit *unit, gdb_byte *start, int eh_frame_p) fde->instructions = buf; fde->end = end; + fde->eh_frame_p = eh_frame_p; + add_fde (unit, fde); } diff --git a/gdb/dwarf2-frame.h b/gdb/dwarf2-frame.h index a4ad586..da9fe47 100644 --- a/gdb/dwarf2-frame.h +++ b/gdb/dwarf2-frame.h @@ -90,6 +90,19 @@ extern void int (*signal_frame_p) (struct gdbarch *, struct frame_info *)); +/* Set the architecture-specific mapping of .eh_frame register numbers to + DWARF register numbers. */ + +extern void + dwarf2_frame_set_eh_frame_regnum (struct gdbarch *gdbarch, + int (*eh_frame_regnum) (struct gdbarch *, + int)); + +/* Translate a .eh_frame register to DWARF register. */ + +extern int + dwarf2_frame_eh_frame_regnum (struct gdbarch *gdbarch, int regnum); + /* Return the frame unwind methods for the function that contains PC, or NULL if it can't be handled by DWARF CFI frame unwinder. */ diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 6fe9245..0881e3d 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -846,7 +846,7 @@ static struct line_header *(dwarf_decode_line_header static void dwarf_decode_lines (struct line_header *, char *, bfd *, struct dwarf2_cu *, struct partial_symtab *); -static void dwarf2_start_subfile (char *, char *); +static void dwarf2_start_subfile (char *, char *, char *); static struct symbol *new_symbol (struct die_info *, struct type *, struct dwarf2_cu *); @@ -6529,13 +6529,12 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, directory and file name numbers in the statement program are 1-based. */ struct file_entry *fe = &lh->file_names[file - 1]; - char *dir; + char *dir = NULL; if (fe->dir_index) dir = lh->include_dirs[fe->dir_index - 1]; - else - dir = comp_dir; - dwarf2_start_subfile (fe->name, dir); + + dwarf2_start_subfile (fe->name, dir, comp_dir); } /* Decode the table. */ @@ -6627,17 +6626,16 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, 0-based, but the directory and file name numbers in the statement program are 1-based. */ struct file_entry *fe; - char *dir; + char *dir = NULL; file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); line_ptr += bytes_read; fe = &lh->file_names[file - 1]; if (fe->dir_index) dir = lh->include_dirs[fe->dir_index - 1]; - else - dir = comp_dir; + if (!decode_for_pst_p) - dwarf2_start_subfile (fe->name, dir); + dwarf2_start_subfile (fe->name, dir, comp_dir); } break; case DW_LNS_set_column: @@ -6717,7 +6715,8 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, /* Start a subfile for DWARF. FILENAME is the name of the file and DIRNAME the name of the source directory which contains FILENAME - or NULL if not known. + or NULL if not known. COMP_DIR is the compilation directory for the + linetable's compilation unit or NULL if not known. This routine tries to keep line numbers from identical absolute and relative file names in a common subfile. @@ -6733,31 +6732,35 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, files.files[1].dir: /srcdir The line number information for list0.c has to end up in a single - subfile, so that `break /srcdir/list0.c:1' works as expected. */ + subfile, so that `break /srcdir/list0.c:1' works as expected. + start_subfile will ensure that this happens provided that we pass the + concatenation of files.files[1].dir and files.files[1].name as the + subfile's name. */ static void -dwarf2_start_subfile (char *filename, char *dirname) +dwarf2_start_subfile (char *filename, char *dirname, char *comp_dir) { - /* If the filename isn't absolute, try to match an existing subfile - with the full pathname. */ + char *fullname; + + /* While reading the DIEs, we call start_symtab(DW_AT_name, DW_AT_comp_dir). + `start_symtab' will always pass the contents of DW_AT_comp_dir as + second argument to start_subfile. To be consistent, we do the + same here. In order not to lose the line information directory, + we concatenate it to the filename when it makes sense. + Note that the Dwarf3 standard says (speaking of filenames in line + information): ``The directory index is ignored for file names + that represent full path names''. Thus ignoring dirname in the + `else' branch below isn't an issue. */ if (!IS_ABSOLUTE_PATH (filename) && dirname != NULL) - { - struct subfile *subfile; - char *fullname = concat (dirname, "/", filename, (char *)NULL); + fullname = concat (dirname, SLASH_STRING, filename, (char *)NULL); + else + fullname = filename; - for (subfile = subfiles; subfile; subfile = subfile->next) - { - if (FILENAME_CMP (subfile->name, fullname) == 0) - { - current_subfile = subfile; - xfree (fullname); - return; - } - } - xfree (fullname); - } - start_subfile (filename, dirname); + start_subfile (fullname, comp_dir); + + if (fullname != filename) + xfree (fullname); } static void @@ -6853,7 +6856,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu) /* Default assumptions. Use the passed type or decode it from the die. */ SYMBOL_DOMAIN (sym) = VAR_DOMAIN; - SYMBOL_CLASS (sym) = LOC_STATIC; + SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT; if (type != NULL) SYMBOL_TYPE (sym) = type; else diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 3c13ba6..1a0ddf3 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,13 @@ +2006-05-09 Nathan Sidwell <nathan@codesourcery.com> + + * configure.srv (m68k*-*-uclinux*): New target. + * linux-low.c (linux_create_inferior): Use vfork on mmuless systems. + (linux_resume_one_process): Remove extraneous cast. + (linux_read_offsets): New. + (linux_target_op): Add linux_read_offsets on mmuless systems. + * server.c (handle_query): Add qOffsets logic. + * target.h (struct target_ops): Add read_offsets. + 2006-03-15 Daniel Jacobowitz <dan@codesourcery.com> * linux-mips-low.c: Include <sys/ptrace.h> and "gdb_proc_service.h". diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv index e2d52c0..ca41c17 100644 --- a/gdb/gdbserver/configure.srv +++ b/gdb/gdbserver/configure.srv @@ -54,6 +54,12 @@ case "${target}" in srv_linux_regsets=yes srv_linux_thread_db=yes ;; + m68*-*-uclinux*) srv_regobj=reg-m68k.o + srv_tgtobj="linux-low.o linux-m68k-low.o" + srv_linux_usrregs=yes + srv_linux_regsets=yes + srv_linux_thread_db=yes + ;; mips*-*-linux*) srv_regobj=reg-mips.o srv_tgtobj="linux-low.o linux-mips-low.o" srv_linux_usrregs=yes diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 8518484..08f1d89 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -140,7 +140,11 @@ linux_create_inferior (char *program, char **allargs) void *new_process; int pid; +#if defined(__UCLIBC__) && !defined(__UCLIBC_HAS_MMU__) + pid = vfork (); +#else pid = fork (); +#endif if (pid < 0) perror_with_name ("fork"); @@ -896,7 +900,7 @@ linux_resume_one_process (struct inferior_list_entry *entry, if (debug_threads && the_low_target.get_pc != NULL) { fprintf (stderr, " "); - (long) (*the_low_target.get_pc) (); + (*the_low_target.get_pc) (); } /* If we have pending signals, consume one unless we are trying to reinsert @@ -1550,6 +1554,51 @@ linux_stopped_data_address (void) return 0; } +#if defined(__UCLIBC__) && !defined(__UCLIBC_HAS_MMU__) +#if defined(__mcoldfire__) +/* These should really be defined in the kernel's ptrace.h header. */ +#define PT_TEXT_ADDR 49*4 +#define PT_DATA_ADDR 50*4 +#define PT_TEXT_END_ADDR 51*4 +#endif + +/* Under uClinux, programs are loaded at non-zero offsets, which we need + to tell gdb about. */ + +static int +linux_read_offsets (CORE_ADDR *text_p, CORE_ADDR *data_p) +{ +#if defined(PT_TEXT_ADDR) && defined(PT_DATA_ADDR) && defined(PT_TEXT_END_ADDR) + unsigned long text, text_end, data; + int pid = get_thread_process (current_inferior)->head.id; + + errno = 0; + + text = ptrace (PTRACE_PEEKUSER, pid, (long)PT_TEXT_ADDR, 0); + text_end = ptrace (PTRACE_PEEKUSER, pid, (long)PT_TEXT_END_ADDR, 0); + data = ptrace (PTRACE_PEEKUSER, pid, (long)PT_DATA_ADDR, 0); + + if (errno == 0) + { + /* Both text and data offsets produced at compile-time (and so + used by gdb) are relative to the beginning of the program, + with the data segment immediately following the text segment. + However, the actual runtime layout in memory may put the data + somewhere else, so when we send gdb a data base-address, we + use the real data base address and subtract the compile-time + data base-address from it (which is just the length of the + text segment). BSS immediately follows data in both + cases. */ + *text_p = text; + *data_p = data - (text_end - text); + + return 1; + } +#endif + return 0; +} +#endif + static struct target_ops linux_target_ops = { linux_create_inferior, linux_attach, @@ -1569,6 +1618,9 @@ static struct target_ops linux_target_ops = { linux_remove_watchpoint, linux_stopped_by_watchpoint, linux_stopped_data_address, +#if defined(__UCLIBC__) && !defined(__UCLIBC_HAS_MMU__) + linux_read_offsets, +#endif }; static void diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index 0722e59..51b8764 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -129,6 +129,20 @@ handle_query (char *own_buf) } } + if (the_target->read_offsets != NULL + && strcmp ("qOffsets", own_buf) == 0) + { + CORE_ADDR text, data; + + if (the_target->read_offsets (&text, &data)) + sprintf (own_buf, "Text=%lX;Data=%lX;Bss=%lX", + (long)text, (long)data, (long)data); + else + write_enn (own_buf); + + return; + } + if (the_target->read_auxv != NULL && strncmp ("qPart:auxv:read::", own_buf, 17) == 0) { diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h index 7f65d3d..6c9a4d7 100644 --- a/gdb/gdbserver/target.h +++ b/gdb/gdbserver/target.h @@ -156,6 +156,11 @@ struct target_ops CORE_ADDR (*stopped_data_address) (void); + /* Reports the text, data offsets of the executable. This is + needed for uclinux where the executable is relocated during load + time. */ + + int (*read_offsets) (CORE_ADDR *text, CORE_ADDR *data); }; extern struct target_ops *the_target; diff --git a/gdb/gnu-nat.c b/gdb/gnu-nat.c index f17d001..968a9cf 100644 --- a/gdb/gnu-nat.c +++ b/gdb/gnu-nat.c @@ -1050,7 +1050,10 @@ inf_validate_procs (struct inf *inf) proc_debug (thread, "died!"); thread->port = MACH_PORT_NULL; thread = _proc_free (thread); /* THREAD is dead. */ - (last ? last->next : inf->threads) = thread; + if (last) + last->next = thread; + else + inf->threads = thread; } } @@ -1063,7 +1066,10 @@ inf_validate_procs (struct inf *inf) /* THREADS[I] is a thread we don't know about yet! */ { thread = make_proc (inf, threads[i], next_thread_id++); - (last ? last->next : inf->threads) = thread; + if (last) + last->next = thread; + else + inf->threads = thread; last = thread; proc_debug (thread, "new thread: %d", threads[i]); add_thread (pid_to_ptid (thread->tid)); /* Tell GDB's generic thread code. */ diff --git a/gdb/hppa-hpux-tdep.c b/gdb/hppa-hpux-tdep.c index 7eba123..b434584 100644 --- a/gdb/hppa-hpux-tdep.c +++ b/gdb/hppa-hpux-tdep.c @@ -865,14 +865,14 @@ GDB will be unable to intercept exception events."), does the equivalent of shl_findsym()) to find the plabel. */ args_for_find_stub args; - static char message[] = _("Error while finding exception callback hook:\n"); args.solib_handle = gdbarch_tdep (current_gdbarch)->solib_get_solib_by_pc (eh_notify_callback_addr); args.msym = msym; args.return_val = 0; recurse++; - catch_errors (cover_find_stub_with_shl_get, &args, message, + catch_errors (cover_find_stub_with_shl_get, &args, + _("Error while finding exception callback hook:\n"), RETURN_MASK_ALL); eh_notify_callback_addr = args.return_val; recurse--; diff --git a/gdb/linux-fork.c b/gdb/linux-fork.c index bb44682..e96275b 100644 --- a/gdb/linux-fork.c +++ b/gdb/linux-fork.c @@ -448,9 +448,18 @@ info_forks_command (char *arg, int from_tty) struct fork_info *fp; int cur_line; ULONGEST pc; + int requested = -1; + struct fork_info *printed = NULL; + + if (arg && *arg) + requested = (int) parse_and_eval_long (arg); for (fp = fork_list; fp; fp = fp->next) { + if (requested > 0 && fp->num != requested) + continue; + + printed = fp; if (ptid_equal (fp->ptid, inferior_ptid)) { printf_filtered ("* "); @@ -490,6 +499,13 @@ info_forks_command (char *arg, int from_tty) putchar_filtered ('\n'); } + if (printed == NULL) + { + if (requested > 0) + printf_filtered (_("No fork number %d.\n"), requested); + else + printf_filtered (_("No forks.\n")); + } } /* Save/restore mode variable 'detach_fork': @@ -670,11 +686,12 @@ Fork a duplicate process (experimental).")); restart <n>: restore program context from a checkpoint.\n\ Argument 'n' is checkpoint ID, as displayed by 'info checkpoints'.")); - /* Delete-checkpoint command: kill the process and remove it from + /* Delete checkpoint command: kill the process and remove it from fork list. */ - add_com ("delete-checkpoint", class_obscure, delete_fork_command, _("\ -Delete a fork/checkpoint (experimental).")); + add_cmd ("checkpoint", class_obscure, delete_fork_command, _("\ +Delete a fork/checkpoint (experimental)."), + &deletelist); /* Detach-checkpoint command: release the process to run independantly, and remove it from the fork list. */ @@ -691,7 +708,7 @@ Detach from a fork/checkpoint (experimental).")); /* Command aliases (let "fork" and "checkpoint" be used interchangeably). */ - add_com_alias ("delete-fork", "delete-checkpoint", class_obscure, 1); + add_alias_cmd ("fork", "checkpoint", class_obscure, 1, &deletelist); add_com_alias ("detach-fork", "detach-checkpoint", class_obscure, 1); add_info_alias ("forks", "checkpoints", 0); diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index f050e7e..932119e 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -36,6 +36,7 @@ #include "gdbthread.h" #include "gdbcmd.h" #include "regcache.h" +#include "regset.h" #include "inf-ptrace.h" #include "auxv.h" #include <sys/param.h> /* for MAXPATHLEN */ @@ -899,10 +900,13 @@ exit_lwp (struct lwp_info *lp) struct thread_info *thr; thr = iterate_over_threads (find_thread_from_lwp, &lp->ptid); - if (thr && !ptid_equal (thr->ptid, inferior_ptid)) - delete_thread (thr->ptid); - else - record_dead_thread (thr->ptid); + if (thr) + { + if (!ptid_equal (thr->ptid, inferior_ptid)) + delete_thread (thr->ptid); + else + record_dead_thread (thr->ptid); + } } delete_lwp (lp->ptid); @@ -1278,10 +1282,11 @@ kill_lwp (int lwpid, int signo) just pass off to linux_handle_extended_wait, but if it reports a clone event we need to add the new LWP to our list (and not report the trap to higher layers). This function returns non-zero if - the event should be ignored and we should wait again. */ + the event should be ignored and we should wait again. If STOPPING + is true, the new LWP remains stopped, otherwise it is continued. */ static int -linux_nat_handle_extended (struct lwp_info *lp, int status) +linux_nat_handle_extended (struct lwp_info *lp, int status, int stopping) { linux_handle_extended_wait (GET_LWP (lp->ptid), status, &lp->waitstatus); @@ -1293,7 +1298,11 @@ linux_nat_handle_extended (struct lwp_info *lp, int status) new_lp = add_lwp (BUILD_LWP (lp->waitstatus.value.related_pid, GET_PID (inferior_ptid))); new_lp->cloned = 1; - new_lp->stopped = 1; + + if (stopping) + new_lp->stopped = 1; + else + ptrace (PTRACE_CONT, lp->waitstatus.value.related_pid, 0, 0); lp->waitstatus.kind = TARGET_WAITKIND_IGNORE; @@ -1377,7 +1386,7 @@ wait_lwp (struct lwp_info *lp) fprintf_unfiltered (gdb_stdlog, "WL: Handling extended status 0x%06x\n", status); - if (linux_nat_handle_extended (lp, status)) + if (linux_nat_handle_extended (lp, status, 1)) return wait_lwp (lp); } @@ -2022,7 +2031,7 @@ retry: fprintf_unfiltered (gdb_stdlog, "LLW: Handling extended status 0x%06x\n", status); - if (linux_nat_handle_extended (lp, status)) + if (linux_nat_handle_extended (lp, status, 0)) { status = 0; continue; @@ -2154,7 +2163,10 @@ retry: { int signo = target_signal_from_host (WSTOPSIG (status)); - if (signal_stop_state (signo) == 0 + /* If we get a signal while single-stepping, we may need special + care, e.g. to skip the signal handler. Defer to common code. */ + if (!lp->step + && signal_stop_state (signo) == 0 && signal_print_state (signo) == 0 && signal_pass_state (signo) == 1) { @@ -2535,21 +2547,50 @@ linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid, gdb_fpxregset_t fpxregs; #endif unsigned long lwp = ptid_get_lwp (ptid); + struct gdbarch *gdbarch = current_gdbarch; + const struct regset *regset; + int core_regset_p; + + core_regset_p = gdbarch_regset_from_core_section_p (gdbarch); + if (core_regset_p + && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg", + sizeof (gregs))) != NULL + && regset->collect_regset != NULL) + regset->collect_regset (regset, current_regcache, -1, + &gregs, sizeof (gregs)); + else + fill_gregset (&gregs, -1); - fill_gregset (&gregs, -1); note_data = (char *) elfcore_write_prstatus (obfd, note_data, note_size, lwp, stop_signal, &gregs); - fill_fpregset (&fpregs, -1); + if (core_regset_p + && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg2", + sizeof (fpregs))) != NULL + && regset->collect_regset != NULL) + regset->collect_regset (regset, current_regcache, -1, + &fpregs, sizeof (fpregs)); + else + fill_fpregset (&fpregs, -1); + note_data = (char *) elfcore_write_prfpreg (obfd, note_data, note_size, &fpregs, sizeof (fpregs)); + #ifdef FILL_FPXREGSET - fill_fpxregset (&fpxregs, -1); + if (core_regset_p + && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg-xfp", + sizeof (fpxregs))) != NULL + && regset->collect_regset != NULL) + regset->collect_regset (regset, current_regcache, -1, + &fpxregs, sizeof (fpxregs)); + else + fill_fpxregset (&fpxregs, -1); + note_data = (char *) elfcore_write_prxfpreg (obfd, note_data, note_size, diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c index 981bc06..8c081df 100644 --- a/gdb/linux-thread-db.c +++ b/gdb/linux-thread-db.c @@ -1047,7 +1047,7 @@ thread_db_store_registers (int regno) { gdb_byte raw[MAX_REGISTER_SIZE]; - deprecated_read_register_gen (regno, raw); + regcache_raw_collect (current_regcache, regno, raw); thread_db_fetch_registers (-1); regcache_raw_supply (current_regcache, regno, raw); } diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c new file mode 100644 index 0000000..e93a98c --- /dev/null +++ b/gdb/m32c-tdep.c @@ -0,0 +1,2552 @@ +/* Renesas M32C target-dependent code for GDB, the GNU debugger. + + Copyright 2004, 2005 Free Software Foundation, Inc. + + This file is part of GDB. + + 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. */ + +#include "defs.h" + +#include <stdarg.h> + +#if defined (HAVE_STRING_H) +#include <string.h> +#endif + +#include "gdb_assert.h" +#include "elf-bfd.h" +#include "elf/m32c.h" +#include "gdb/sim-m32c.h" +#include "dis-asm.h" +#include "gdbtypes.h" +#include "regcache.h" +#include "arch-utils.h" +#include "frame.h" +#include "frame-unwind.h" +#include "dwarf2-frame.h" +#include "dwarf2expr.h" +#include "symtab.h" +#include "gdbcore.h" +#include "value.h" +#include "reggroups.h" +#include "prologue-value.h" +#include "target.h" + + +/* The m32c tdep structure. */ + +static struct reggroup *m32c_dma_reggroup; + +struct m32c_reg; + +/* The type of a function that moves the value of REG between CACHE or + BUF --- in either direction. */ +typedef void (m32c_move_reg_t) (struct m32c_reg *reg, + struct regcache *cache, + void *buf); + +struct m32c_reg +{ + /* The name of this register. */ + const char *name; + + /* Its type. */ + struct type *type; + + /* The architecture this register belongs to. */ + struct gdbarch *arch; + + /* Its GDB register number. */ + int num; + + /* Its sim register number. */ + int sim_num; + + /* Its DWARF register number, or -1 if it doesn't have one. */ + int dwarf_num; + + /* Register group memberships. */ + unsigned int general_p : 1; + unsigned int dma_p : 1; + unsigned int system_p : 1; + unsigned int save_restore_p : 1; + + /* Functions to read its value from a regcache, and write its value + to a regcache. */ + m32c_move_reg_t *read, *write; + + /* Data for READ and WRITE functions. The exact meaning depends on + the specific functions selected; see the comments for those + functions. */ + struct m32c_reg *rx, *ry; + int n; +}; + + +/* An overestimate of the number of raw and pseudoregisters we will + have. The exact answer depends on the variant of the architecture + at hand, but we can use this to declare statically allocated + arrays, and bump it up when needed. */ +#define M32C_MAX_NUM_REGS (75) + +/* The largest assigned DWARF register number. */ +#define M32C_MAX_DWARF_REGNUM (40) + + +struct gdbarch_tdep +{ + /* All the registers for this variant, indexed by GDB register + number, and the number of registers present. */ + struct m32c_reg regs[M32C_MAX_NUM_REGS]; + + /* The number of valid registers. */ + int num_regs; + + /* Interesting registers. These are pointers into REGS. */ + struct m32c_reg *pc, *flg; + struct m32c_reg *r0, *r1, *r2, *r3, *a0, *a1; + struct m32c_reg *r2r0, *r3r2r1r0, *r3r1r2r0; + struct m32c_reg *sb, *fb, *sp; + + /* A table indexed by DWARF register numbers, pointing into + REGS. */ + struct m32c_reg *dwarf_regs[M32C_MAX_DWARF_REGNUM + 1]; + + /* Types for this architecture. We can't use the builtin_type_foo + types, because they're not initialized when building a gdbarch + structure. */ + struct type *voyd, *ptr_voyd, *func_voyd; + struct type *uint8, *uint16; + struct type *int8, *int16, *int32, *int64; + + /* The types for data address and code address registers. */ + struct type *data_addr_reg_type, *code_addr_reg_type; + + /* The number of bytes a return address pushed by a 'jsr' instruction + occupies on the stack. */ + int ret_addr_bytes; + + /* The number of bytes an address register occupies on the stack + when saved by an 'enter' or 'pushm' instruction. */ + int push_addr_bytes; +}; + + +/* Types. */ + +static void +make_types (struct gdbarch *arch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (arch); + unsigned long mach = gdbarch_bfd_arch_info (arch)->mach; + int data_addr_reg_bits, code_addr_reg_bits; + char type_name[50]; + +#if 0 + /* This is used to clip CORE_ADDR values, so this value is + appropriate both on the m32c, where pointers are 32 bits long, + and on the m16c, where pointers are sixteen bits long, but there + may be code above the 64k boundary. */ + set_gdbarch_addr_bit (arch, 24); +#else + /* GCC uses 32 bits for addrs in the dwarf info, even though + only 16/24 bits are used. Setting addr_bit to 24 causes + errors in reading the dwarf addresses. */ + set_gdbarch_addr_bit (arch, 32); +#endif + + set_gdbarch_int_bit (arch, 16); + switch (mach) + { + case bfd_mach_m16c: + data_addr_reg_bits = 16; + code_addr_reg_bits = 24; + set_gdbarch_ptr_bit (arch, 16); + tdep->ret_addr_bytes = 3; + tdep->push_addr_bytes = 2; + break; + + case bfd_mach_m32c: + data_addr_reg_bits = 24; + code_addr_reg_bits = 24; + set_gdbarch_ptr_bit (arch, 32); + tdep->ret_addr_bytes = 4; + tdep->push_addr_bytes = 4; + break; + + default: + gdb_assert (0); + } + + /* The builtin_type_mumble variables are sometimes uninitialized when + this is called, so we avoid using them. */ + tdep->voyd = init_type (TYPE_CODE_VOID, 1, 0, "void", NULL); + tdep->ptr_voyd = init_type (TYPE_CODE_PTR, gdbarch_ptr_bit (arch) / 8, + TYPE_FLAG_UNSIGNED, NULL, NULL); + TYPE_TARGET_TYPE (tdep->ptr_voyd) = tdep->voyd; + tdep->func_voyd = lookup_function_type (tdep->voyd); + + sprintf (type_name, "%s_data_addr_t", + gdbarch_bfd_arch_info (arch)->printable_name); + tdep->data_addr_reg_type + = init_type (TYPE_CODE_PTR, data_addr_reg_bits / 8, + TYPE_FLAG_UNSIGNED, xstrdup (type_name), NULL); + TYPE_TARGET_TYPE (tdep->data_addr_reg_type) = tdep->voyd; + + sprintf (type_name, "%s_code_addr_t", + gdbarch_bfd_arch_info (arch)->printable_name); + tdep->code_addr_reg_type + = init_type (TYPE_CODE_PTR, code_addr_reg_bits / 8, + TYPE_FLAG_UNSIGNED, xstrdup (type_name), NULL); + TYPE_TARGET_TYPE (tdep->code_addr_reg_type) = tdep->func_voyd; + + tdep->uint8 = init_type (TYPE_CODE_INT, 1, TYPE_FLAG_UNSIGNED, + "uint8_t", NULL); + tdep->uint16 = init_type (TYPE_CODE_INT, 2, TYPE_FLAG_UNSIGNED, + "uint16_t", NULL); + tdep->int8 = init_type (TYPE_CODE_INT, 1, 0, "int8_t", NULL); + tdep->int16 = init_type (TYPE_CODE_INT, 2, 0, "int16_t", NULL); + tdep->int32 = init_type (TYPE_CODE_INT, 4, 0, "int32_t", NULL); + tdep->int64 = init_type (TYPE_CODE_INT, 8, 0, "int64_t", NULL); +} + + + +/* Register set. */ + +static const char * +m32c_register_name (int num) +{ + return gdbarch_tdep (current_gdbarch)->regs[num].name; +} + + +static struct type * +m32c_register_type (struct gdbarch *arch, int reg_nr) +{ + return gdbarch_tdep (arch)->regs[reg_nr].type; +} + + +static int +m32c_register_sim_regno (int reg_nr) +{ + return gdbarch_tdep (current_gdbarch)->regs[reg_nr].sim_num; +} + + +static int +m32c_debug_info_reg_to_regnum (int reg_nr) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + if (0 <= reg_nr && reg_nr <= M32C_MAX_DWARF_REGNUM + && tdep->dwarf_regs[reg_nr]) + return tdep->dwarf_regs[reg_nr]->num; + else + /* The DWARF CFI code expects to see -1 for invalid register + numbers. */ + return -1; +} + + +int +m32c_register_reggroup_p (struct gdbarch *gdbarch, int regnum, + struct reggroup *group) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct m32c_reg *reg = &tdep->regs[regnum]; + + /* The anonymous raw registers aren't in any groups. */ + if (! reg->name) + return 0; + + if (group == all_reggroup) + return 1; + + if (group == general_reggroup + && reg->general_p) + return 1; + + if (group == m32c_dma_reggroup + && reg->dma_p) + return 1; + + if (group == system_reggroup + && reg->system_p) + return 1; + + /* Since the m32c DWARF register numbers refer to cooked registers, not + raw registers, and frame_pop depends on the save and restore groups + containing registers the DWARF CFI will actually mention, our save + and restore groups are cooked registers, not raw registers. (This is + why we can't use the default reggroup function.) */ + if ((group == save_reggroup + || group == restore_reggroup) + && reg->save_restore_p) + return 1; + + return 0; +} + + +/* Register move functions. We declare them here using + m32c_move_reg_t to check the types. */ +static m32c_move_reg_t m32c_raw_read, m32c_raw_write; +static m32c_move_reg_t m32c_banked_read, m32c_banked_write; +static m32c_move_reg_t m32c_sb_read, m32c_sb_write; +static m32c_move_reg_t m32c_part_read, m32c_part_write; +static m32c_move_reg_t m32c_cat_read, m32c_cat_write; +static m32c_move_reg_t m32c_r3r2r1r0_read, m32c_r3r2r1r0_write; + + +/* Copy the value of the raw register REG from CACHE to BUF. */ +static void +m32c_raw_read (struct m32c_reg *reg, struct regcache *cache, void *buf) +{ + regcache_raw_read (cache, reg->num, buf); +} + + +/* Copy the value of the raw register REG from BUF to CACHE. */ +static void +m32c_raw_write (struct m32c_reg *reg, struct regcache *cache, void *buf) +{ + regcache_raw_write (cache, reg->num, (const void *) buf); +} + + +/* Return the value of the 'flg' register in CACHE. */ +static int +m32c_read_flg (struct regcache *cache) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (cache)); + ULONGEST flg; + regcache_raw_read_unsigned (cache, tdep->flg->num, &flg); + return flg & 0xffff; +} + + +/* Move the value of a banked register from CACHE to BUF. + If the value of the 'flg' register in CACHE has any of the bits + masked in REG->n set, then read REG->ry. Otherwise, read + REG->rx. */ +static void +m32c_banked_read (struct m32c_reg *reg, struct regcache *cache, void *buf) +{ + struct m32c_reg *bank_reg + = ((m32c_read_flg (cache) & reg->n) ? reg->ry : reg->rx); + regcache_raw_read (cache, bank_reg->num, buf); +} + + +/* Move the value of a banked register from BUF to CACHE. + If the value of the 'flg' register in CACHE has any of the bits + masked in REG->n set, then write REG->ry. Otherwise, write + REG->rx. */ +static void +m32c_banked_write (struct m32c_reg *reg, struct regcache *cache, void *buf) +{ + struct m32c_reg *bank_reg + = ((m32c_read_flg (cache) & reg->n) ? reg->ry : reg->rx); + regcache_raw_write (cache, bank_reg->num, (const void *) buf); +} + + +/* Move the value of SB from CACHE to BUF. On bfd_mach_m32c, SB is a + banked register; on bfd_mach_m16c, it's not. */ +static void +m32c_sb_read (struct m32c_reg *reg, struct regcache *cache, void *buf) +{ + if (gdbarch_bfd_arch_info (reg->arch)->mach == bfd_mach_m16c) + m32c_raw_read (reg->rx, cache, buf); + else + m32c_banked_read (reg, cache, buf); +} + + +/* Move the value of SB from BUF to CACHE. On bfd_mach_m32c, SB is a + banked register; on bfd_mach_m16c, it's not. */ +static void +m32c_sb_write (struct m32c_reg *reg, struct regcache *cache, void *buf) +{ + if (gdbarch_bfd_arch_info (reg->arch)->mach == bfd_mach_m16c) + m32c_raw_write (reg->rx, cache, buf); + else + m32c_banked_write (reg, cache, buf); +} + + +/* Assuming REG uses m32c_part_read and m32c_part_write, set *OFFSET_P + and *LEN_P to the offset and length, in bytes, of the part REG + occupies in its underlying register. The offset is from the + lower-addressed end, regardless of the architecture's endianness. + (The M32C family is always little-endian, but let's keep those + assumptions out of here.) */ +static void +m32c_find_part (struct m32c_reg *reg, int *offset_p, int *len_p) +{ + /* The length of the containing register, of which REG is one part. */ + int containing_len = TYPE_LENGTH (reg->rx->type); + + /* The length of one "element" in our imaginary array. */ + int elt_len = TYPE_LENGTH (reg->type); + + /* The offset of REG's "element" from the least significant end of + the containing register. */ + int elt_offset = reg->n * elt_len; + + /* If we extend off the end, trim the length of the element. */ + if (elt_offset + elt_len > containing_len) + { + elt_len = containing_len - elt_offset; + /* We shouldn't be declaring partial registers that go off the + end of their containing registers. */ + gdb_assert (elt_len > 0); + } + + /* Flip the offset around if we're big-endian. */ + if (gdbarch_byte_order (reg->arch) == BFD_ENDIAN_BIG) + elt_offset = TYPE_LENGTH (reg->rx->type) - elt_offset - elt_len; + + *offset_p = elt_offset; + *len_p = elt_len; +} + + +/* Move the value of a partial register (r0h, intbl, etc.) from CACHE + to BUF. Treating the value of the register REG->rx as an array of + REG->type values, where higher indices refer to more significant + bits, read the value of the REG->n'th element. */ +static void +m32c_part_read (struct m32c_reg *reg, struct regcache *cache, void *buf) +{ + int offset, len; + memset (buf, 0, TYPE_LENGTH (reg->type)); + m32c_find_part (reg, &offset, &len); + regcache_cooked_read_part (cache, reg->rx->num, offset, len, buf); +} + + +/* Move the value of a banked register from BUF to CACHE. + Treating the value of the register REG->rx as an array of REG->type + values, where higher indices refer to more significant bits, write + the value of the REG->n'th element. */ +static void +m32c_part_write (struct m32c_reg *reg, struct regcache *cache, void *buf) +{ + int offset, len; + m32c_find_part (reg, &offset, &len); + regcache_cooked_write_part (cache, reg->rx->num, offset, len, buf); +} + + +/* Move the value of REG from CACHE to BUF. REG's value is the + concatenation of the values of the registers REG->rx and REG->ry, + with REG->rx contributing the more significant bits. */ +static void +m32c_cat_read (struct m32c_reg *reg, struct regcache *cache, void *buf) +{ + int high_bytes = TYPE_LENGTH (reg->rx->type); + int low_bytes = TYPE_LENGTH (reg->ry->type); + /* For address arithmetic. */ + unsigned char *cbuf = buf; + + gdb_assert (TYPE_LENGTH (reg->type) == high_bytes + low_bytes); + + if (gdbarch_byte_order (reg->arch) == BFD_ENDIAN_BIG) + { + regcache_cooked_read (cache, reg->rx->num, cbuf); + regcache_cooked_read (cache, reg->ry->num, cbuf + high_bytes); + } + else + { + regcache_cooked_read (cache, reg->rx->num, cbuf + low_bytes); + regcache_cooked_read (cache, reg->ry->num, cbuf); + } +} + + +/* Move the value of REG from CACHE to BUF. REG's value is the + concatenation of the values of the registers REG->rx and REG->ry, + with REG->rx contributing the more significant bits. */ +static void +m32c_cat_write (struct m32c_reg *reg, struct regcache *cache, void *buf) +{ + int high_bytes = TYPE_LENGTH (reg->rx->type); + int low_bytes = TYPE_LENGTH (reg->ry->type); + /* For address arithmetic. */ + unsigned char *cbuf = buf; + + gdb_assert (TYPE_LENGTH (reg->type) == high_bytes + low_bytes); + + if (gdbarch_byte_order (reg->arch) == BFD_ENDIAN_BIG) + { + regcache_cooked_write (cache, reg->rx->num, cbuf); + regcache_cooked_write (cache, reg->ry->num, cbuf + high_bytes); + } + else + { + regcache_cooked_write (cache, reg->rx->num, cbuf + low_bytes); + regcache_cooked_write (cache, reg->ry->num, cbuf); + } +} + + +/* Copy the value of the raw register REG from CACHE to BUF. REG is + the concatenation (from most significant to least) of r3, r2, r1, + and r0. */ +static void +m32c_r3r2r1r0_read (struct m32c_reg *reg, struct regcache *cache, void *buf) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (reg->arch); + int len = TYPE_LENGTH (tdep->r0->type); + + /* For address arithmetic. */ + unsigned char *cbuf = buf; + + if (gdbarch_byte_order (reg->arch) == BFD_ENDIAN_BIG) + { + regcache_cooked_read (cache, tdep->r0->num, cbuf + len * 3); + regcache_cooked_read (cache, tdep->r1->num, cbuf + len * 2); + regcache_cooked_read (cache, tdep->r2->num, cbuf + len * 1); + regcache_cooked_read (cache, tdep->r3->num, cbuf); + } + else + { + regcache_cooked_read (cache, tdep->r0->num, cbuf); + regcache_cooked_read (cache, tdep->r1->num, cbuf + len * 1); + regcache_cooked_read (cache, tdep->r2->num, cbuf + len * 2); + regcache_cooked_read (cache, tdep->r3->num, cbuf + len * 3); + } +} + + +/* Copy the value of the raw register REG from BUF to CACHE. REG is + the concatenation (from most significant to least) of r3, r2, r1, + and r0. */ +static void +m32c_r3r2r1r0_write (struct m32c_reg *reg, struct regcache *cache, void *buf) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (reg->arch); + int len = TYPE_LENGTH (tdep->r0->type); + + /* For address arithmetic. */ + unsigned char *cbuf = buf; + + if (gdbarch_byte_order (reg->arch) == BFD_ENDIAN_BIG) + { + regcache_cooked_write (cache, tdep->r0->num, cbuf + len * 3); + regcache_cooked_write (cache, tdep->r1->num, cbuf + len * 2); + regcache_cooked_write (cache, tdep->r2->num, cbuf + len * 1); + regcache_cooked_write (cache, tdep->r3->num, cbuf); + } + else + { + regcache_cooked_write (cache, tdep->r0->num, cbuf); + regcache_cooked_write (cache, tdep->r1->num, cbuf + len * 1); + regcache_cooked_write (cache, tdep->r2->num, cbuf + len * 2); + regcache_cooked_write (cache, tdep->r3->num, cbuf + len * 3); + } +} + + +static void +m32c_pseudo_register_read (struct gdbarch *arch, + struct regcache *cache, + int cookednum, + gdb_byte *buf) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (arch); + struct m32c_reg *reg; + + gdb_assert (0 <= cookednum && cookednum < tdep->num_regs); + gdb_assert (arch == get_regcache_arch (cache)); + gdb_assert (arch == tdep->regs[cookednum].arch); + reg = &tdep->regs[cookednum]; + + reg->read (reg, cache, buf); +} + + +static void +m32c_pseudo_register_write (struct gdbarch *arch, + struct regcache *cache, + int cookednum, + const gdb_byte *buf) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (arch); + struct m32c_reg *reg; + + gdb_assert (0 <= cookednum && cookednum < tdep->num_regs); + gdb_assert (arch == get_regcache_arch (cache)); + gdb_assert (arch == tdep->regs[cookednum].arch); + reg = &tdep->regs[cookednum]; + + reg->write (reg, cache, (void *) buf); +} + + +/* Add a register with the given fields to the end of ARCH's table. + Return a pointer to the newly added register. */ +static struct m32c_reg * +add_reg (struct gdbarch *arch, + const char *name, + struct type *type, + int sim_num, + m32c_move_reg_t *read, + m32c_move_reg_t *write, + struct m32c_reg *rx, + struct m32c_reg *ry, + int n) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (arch); + struct m32c_reg *r = &tdep->regs[tdep->num_regs]; + + gdb_assert (tdep->num_regs < M32C_MAX_NUM_REGS); + + r->name = name; + r->type = type; + r->arch = arch; + r->num = tdep->num_regs; + r->sim_num = sim_num; + r->dwarf_num = -1; + r->general_p = 0; + r->dma_p = 0; + r->system_p = 0; + r->save_restore_p = 0; + r->read = read; + r->write = write; + r->rx = rx; + r->ry = ry; + r->n = n; + + tdep->num_regs++; + + return r; +} + + +/* Record NUM as REG's DWARF register number. */ +static void +set_dwarf_regnum (struct m32c_reg *reg, int num) +{ + gdb_assert (num < M32C_MAX_NUM_REGS); + + /* Update the reg->DWARF mapping. Only count the first number + assigned to this register. */ + if (reg->dwarf_num == -1) + reg->dwarf_num = num; + + /* Update the DWARF->reg mapping. */ + gdbarch_tdep (reg->arch)->dwarf_regs[num] = reg; +} + + +/* Mark REG as a general-purpose register, and return it. */ +static struct m32c_reg * +mark_general (struct m32c_reg *reg) +{ + reg->general_p = 1; + return reg; +} + + +/* Mark REG as a DMA register, and return it. */ +static struct m32c_reg * +mark_dma (struct m32c_reg *reg) +{ + reg->dma_p = 1; + return reg; +} + + +/* Mark REG as a SYSTEM register, and return it. */ +static struct m32c_reg * +mark_system (struct m32c_reg *reg) +{ + reg->system_p = 1; + return reg; +} + + +/* Mark REG as a save-restore register, and return it. */ +static struct m32c_reg * +mark_save_restore (struct m32c_reg *reg) +{ + reg->save_restore_p = 1; + return reg; +} + + +#define FLAGBIT_B 0x0010 +#define FLAGBIT_U 0x0080 + +/* Handy macros for declaring registers. These all evaluate to + pointers to the register declared. Macros that define two + registers evaluate to a pointer to the first. */ + +/* A raw register named NAME, with type TYPE and sim number SIM_NUM. */ +#define R(name, type, sim_num) \ + (add_reg (arch, (name), (type), (sim_num), \ + m32c_raw_read, m32c_raw_write, NULL, NULL, 0)) + +/* The simulator register number for a raw register named NAME. */ +#define SIM(name) (m32c_sim_reg_ ## name) + +/* A raw unsigned 16-bit data register named NAME. + NAME should be an identifier, not a string. */ +#define R16U(name) \ + (R(#name, tdep->uint16, SIM (name))) + +/* A raw data address register named NAME. + NAME should be an identifier, not a string. */ +#define RA(name) \ + (R(#name, tdep->data_addr_reg_type, SIM (name))) + +/* A raw code address register named NAME. NAME should + be an identifier, not a string. */ +#define RC(name) \ + (R(#name, tdep->code_addr_reg_type, SIM (name))) + +/* A pair of raw registers named NAME0 and NAME1, with type TYPE. + NAME should be an identifier, not a string. */ +#define RP(name, type) \ + (R(#name "0", (type), SIM (name ## 0)), \ + R(#name "1", (type), SIM (name ## 1)) - 1) + +/* A raw banked general-purpose data register named NAME. + NAME should be an identifier, not a string. */ +#define RBD(name) \ + (R(NULL, tdep->int16, SIM (name ## _bank0)), \ + R(NULL, tdep->int16, SIM (name ## _bank1)) - 1) + +/* A raw banked data address register named NAME. + NAME should be an identifier, not a string. */ +#define RBA(name) \ + (R(NULL, tdep->data_addr_reg_type, SIM (name ## _bank0)), \ + R(NULL, tdep->data_addr_reg_type, SIM (name ## _bank1)) - 1) + +/* A cooked register named NAME referring to a raw banked register + from the bank selected by the current value of FLG. RAW_PAIR + should be a pointer to the first register in the banked pair. + NAME must be an identifier, not a string. */ +#define CB(name, raw_pair) \ + (add_reg (arch, #name, (raw_pair)->type, 0, \ + m32c_banked_read, m32c_banked_write, \ + (raw_pair), (raw_pair + 1), FLAGBIT_B)) + +/* A pair of registers named NAMEH and NAMEL, of type TYPE, that + access the top and bottom halves of the register pointed to by + NAME. NAME should be an identifier. */ +#define CHL(name, type) \ + (add_reg (arch, #name "h", (type), 0, \ + m32c_part_read, m32c_part_write, name, NULL, 1), \ + add_reg (arch, #name "l", (type), 0, \ + m32c_part_read, m32c_part_write, name, NULL, 0) - 1) + +/* A register constructed by concatenating the two registers HIGH and + LOW, whose name is HIGHLOW and whose type is TYPE. */ +#define CCAT(high, low, type) \ + (add_reg (arch, #high #low, (type), 0, \ + m32c_cat_read, m32c_cat_write, (high), (low), 0)) + +/* Abbreviations for marking register group membership. */ +#define G(reg) (mark_general (reg)) +#define S(reg) (mark_system (reg)) +#define DMA(reg) (mark_dma (reg)) + + +/* Construct the register set for ARCH. */ +static void +make_regs (struct gdbarch *arch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (arch); + int mach = gdbarch_bfd_arch_info (arch)->mach; + + struct m32c_reg *raw_r0_pair = RBD (r0); + struct m32c_reg *raw_r1_pair = RBD (r1); + struct m32c_reg *raw_r2_pair = RBD (r2); + struct m32c_reg *raw_r3_pair = RBD (r3); + struct m32c_reg *raw_a0_pair = RBA (a0); + struct m32c_reg *raw_a1_pair = RBA (a1); + struct m32c_reg *raw_fb_pair = RBA (fb); + + /* sb is banked on the bfd_mach_m32c, but not on bfd_mach_m16c. + We always declare both raw registers, and deal with the distinction + in the pseudoregister. */ + struct m32c_reg *raw_sb_pair = RBA (sb); + + struct m32c_reg *usp = S (RA (usp)); + struct m32c_reg *isp = S (RA (isp)); + struct m32c_reg *intb = S (RC (intb)); + struct m32c_reg *pc = G (RC (pc)); + struct m32c_reg *flg = G (R16U (flg)); + + if (mach == bfd_mach_m32c) + { + struct m32c_reg *svf = S (R16U (svf)); + struct m32c_reg *svp = S (RC (svp)); + struct m32c_reg *vct = S (RC (vct)); + + struct m32c_reg *dmd01 = DMA (RP (dmd, tdep->uint8)); + struct m32c_reg *dct01 = DMA (RP (dct, tdep->uint16)); + struct m32c_reg *drc01 = DMA (RP (drc, tdep->uint16)); + struct m32c_reg *dma01 = DMA (RP (dma, tdep->data_addr_reg_type)); + struct m32c_reg *dsa01 = DMA (RP (dsa, tdep->data_addr_reg_type)); + struct m32c_reg *dra01 = DMA (RP (dra, tdep->data_addr_reg_type)); + } + + int num_raw_regs = tdep->num_regs; + + struct m32c_reg *r0 = G (CB (r0, raw_r0_pair)); + struct m32c_reg *r1 = G (CB (r1, raw_r1_pair)); + struct m32c_reg *r2 = G (CB (r2, raw_r2_pair)); + struct m32c_reg *r3 = G (CB (r3, raw_r3_pair)); + struct m32c_reg *a0 = G (CB (a0, raw_a0_pair)); + struct m32c_reg *a1 = G (CB (a1, raw_a1_pair)); + struct m32c_reg *fb = G (CB (fb, raw_fb_pair)); + + /* sb is banked on the bfd_mach_m32c, but not on bfd_mach_m16c. + Specify custom read/write functions that do the right thing. */ + struct m32c_reg *sb + = G (add_reg (arch, "sb", raw_sb_pair->type, 0, + m32c_sb_read, m32c_sb_write, + raw_sb_pair, raw_sb_pair + 1, 0)); + + /* The current sp is either usp or isp, depending on the value of + the FLG register's U bit. */ + struct m32c_reg *sp + = G (add_reg (arch, "sp", usp->type, 0, + m32c_banked_read, m32c_banked_write, isp, usp, FLAGBIT_U)); + + struct m32c_reg *r0hl = CHL (r0, tdep->int8); + struct m32c_reg *r1hl = CHL (r1, tdep->int8); + struct m32c_reg *r2hl = CHL (r2, tdep->int8); + struct m32c_reg *r3hl = CHL (r3, tdep->int8); + struct m32c_reg *intbhl = CHL (intb, tdep->int16); + + struct m32c_reg *r2r0 = CCAT (r2, r0, tdep->int32); + struct m32c_reg *r3r1 = CCAT (r3, r1, tdep->int32); + struct m32c_reg *r3r1r2r0 = CCAT (r3r1, r2r0, tdep->int64); + + struct m32c_reg *r3r2r1r0 + = add_reg (arch, "r3r2r1r0", tdep->int64, 0, + m32c_r3r2r1r0_read, m32c_r3r2r1r0_write, NULL, NULL, 0); + + struct m32c_reg *a1a0; + if (mach == bfd_mach_m16c) + a1a0 = CCAT (a1, a0, tdep->int32); + else + a1a0 = NULL; + + int num_cooked_regs = tdep->num_regs - num_raw_regs; + + tdep->pc = pc; + tdep->flg = flg; + tdep->r0 = r0; + tdep->r1 = r1; + tdep->r2 = r2; + tdep->r3 = r3; + tdep->r2r0 = r2r0; + tdep->r3r2r1r0 = r3r2r1r0; + tdep->r3r1r2r0 = r3r1r2r0; + tdep->a0 = a0; + tdep->a1 = a1; + tdep->sb = sb; + tdep->fb = fb; + tdep->sp = sp; + + /* Set up the DWARF register table. */ + memset (tdep->dwarf_regs, 0, sizeof (tdep->dwarf_regs)); + set_dwarf_regnum (r0hl + 1, 0x01); + set_dwarf_regnum (r0hl + 0, 0x02); + set_dwarf_regnum (r1hl + 1, 0x03); + set_dwarf_regnum (r1hl + 0, 0x04); + set_dwarf_regnum (r0, 0x05); + set_dwarf_regnum (r1, 0x06); + set_dwarf_regnum (r2, 0x07); + set_dwarf_regnum (r3, 0x08); + set_dwarf_regnum (a0, 0x09); + set_dwarf_regnum (a1, 0x0a); + set_dwarf_regnum (fb, 0x0b); + set_dwarf_regnum (sp, 0x0c); + set_dwarf_regnum (pc, 0x0d); /* GCC's invention */ + set_dwarf_regnum (sb, 0x13); + set_dwarf_regnum (r2r0, 0x15); + set_dwarf_regnum (r3r1, 0x16); + if (a1a0) + set_dwarf_regnum (a1a0, 0x17); + + /* Enumerate the save/restore register group. + + The regcache_save and regcache_restore functions apply their read + function to each register in this group. + + Since frame_pop supplies frame_unwind_register as its read + function, the registers meaningful to the Dwarf unwinder need to + be in this group. + + On the other hand, when we make inferior calls, save_inferior_status + and restore_inferior_status use them to preserve the current register + values across the inferior call. For this, you'd kind of like to + preserve all the raw registers, to protect the interrupted code from + any sort of bank switching the callee might have done. But we handle + those cases so badly anyway --- for example, it matters whether we + restore FLG before or after we restore the general-purpose registers, + but there's no way to express that --- that it isn't worth worrying + about. + + We omit control registers like inthl: if you call a function that + changes those, it's probably because you wanted that change to be + visible to the interrupted code. */ + mark_save_restore (r0); + mark_save_restore (r1); + mark_save_restore (r2); + mark_save_restore (r3); + mark_save_restore (a0); + mark_save_restore (a1); + mark_save_restore (sb); + mark_save_restore (fb); + mark_save_restore (sp); + mark_save_restore (pc); + mark_save_restore (flg); + + set_gdbarch_num_regs (arch, num_raw_regs); + set_gdbarch_num_pseudo_regs (arch, num_cooked_regs); + set_gdbarch_pc_regnum (arch, pc->num); + set_gdbarch_sp_regnum (arch, sp->num); + set_gdbarch_register_name (arch, m32c_register_name); + set_gdbarch_register_type (arch, m32c_register_type); + set_gdbarch_pseudo_register_read (arch, m32c_pseudo_register_read); + set_gdbarch_pseudo_register_write (arch, m32c_pseudo_register_write); + set_gdbarch_register_sim_regno (arch, m32c_register_sim_regno); + set_gdbarch_stab_reg_to_regnum (arch, m32c_debug_info_reg_to_regnum); + set_gdbarch_dwarf_reg_to_regnum (arch, m32c_debug_info_reg_to_regnum); + set_gdbarch_dwarf2_reg_to_regnum (arch, m32c_debug_info_reg_to_regnum); + set_gdbarch_register_reggroup_p (arch, m32c_register_reggroup_p); + + reggroup_add (arch, general_reggroup); + reggroup_add (arch, all_reggroup); + reggroup_add (arch, save_reggroup); + reggroup_add (arch, restore_reggroup); + reggroup_add (arch, system_reggroup); + reggroup_add (arch, m32c_dma_reggroup); +} + + + +/* Breakpoints. */ + +static const unsigned char * +m32c_breakpoint_from_pc (CORE_ADDR *pc, int *len) +{ + static unsigned char break_insn[] = { 0x00 }; /* brk */ + + *len = sizeof (break_insn); + return break_insn; +} + + + +/* Prologue analysis. */ + +struct m32c_prologue +{ + /* For consistency with the DWARF 2 .debug_frame info generated by + GCC, a frame's CFA is the address immediately after the saved + return address. */ + + /* The architecture for which we generated this prologue info. */ + struct gdbarch *arch; + + enum { + /* This function uses a frame pointer. */ + prologue_with_frame_ptr, + + /* This function has no frame pointer. */ + prologue_sans_frame_ptr, + + /* This function sets up the stack, so its frame is the first + frame on the stack. */ + prologue_first_frame + + } kind; + + /* If KIND is prologue_with_frame_ptr, this is the offset from the + CFA to where the frame pointer points. This is always zero or + negative. */ + LONGEST frame_ptr_offset; + + /* If KIND is prologue_sans_frame_ptr, the offset from the CFA to + the stack pointer --- always zero or negative. + + Calling this a "size" is a bit misleading, but given that the + stack grows downwards, using offsets for everything keeps one + from going completely sign-crazy: you never change anything's + sign for an ADD instruction; always change the second operand's + sign for a SUB instruction; and everything takes care of + itself. + + Functions that use alloca don't have a constant frame size. But + they always have frame pointers, so we must use that to find the + CFA (and perhaps to unwind the stack pointer). */ + LONGEST frame_size; + + /* The address of the first instruction at which the frame has been + set up and the arguments are where the debug info says they are + --- as best as we can tell. */ + CORE_ADDR prologue_end; + + /* reg_offset[R] is the offset from the CFA at which register R is + saved, or 1 if register R has not been saved. (Real values are + always zero or negative.) */ + LONGEST reg_offset[M32C_MAX_NUM_REGS]; +}; + + +/* The longest I've seen, anyway. */ +#define M32C_MAX_INSN_LEN (9) + +/* Processor state, for the prologue analyzer. */ +struct m32c_pv_state +{ + struct gdbarch *arch; + pv_t r0, r1, r2, r3; + pv_t a0, a1; + pv_t sb, fb, sp; + pv_t pc; + struct pv_area *stack; + + /* Bytes from the current PC, the address they were read from, + and the address of the next unconsumed byte. */ + gdb_byte insn[M32C_MAX_INSN_LEN]; + CORE_ADDR scan_pc, next_addr; +}; + + +/* Push VALUE on STATE's stack, occupying SIZE bytes. Return zero if + all went well, or non-zero if simulating the action would trash our + state. */ +static int +m32c_pv_push (struct m32c_pv_state *state, pv_t value, int size) +{ + if (pv_area_store_would_trash (state->stack, state->sp)) + return 1; + + state->sp = pv_add_constant (state->sp, -size); + pv_area_store (state->stack, state->sp, size, value); + + return 0; +} + + +/* A source or destination location for an m16c or m32c + instruction. */ +struct srcdest +{ + /* If srcdest_reg, the location is a register pointed to by REG. + If srcdest_partial_reg, the location is part of a register pointed + to by REG. We don't try to handle this too well. + If srcdest_mem, the location is memory whose address is ADDR. */ + enum { srcdest_reg, srcdest_partial_reg, srcdest_mem } kind; + pv_t *reg, addr; +}; + + +/* Return the SIZE-byte value at LOC in STATE. */ +static pv_t +m32c_srcdest_fetch (struct m32c_pv_state *state, struct srcdest loc, int size) +{ + if (loc.kind == srcdest_mem) + return pv_area_fetch (state->stack, loc.addr, size); + else if (loc.kind == srcdest_partial_reg) + return pv_unknown (); + else + return *loc.reg; +} + + +/* Write VALUE, a SIZE-byte value, to LOC in STATE. Return zero if + all went well, or non-zero if simulating the store would trash our + state. */ +static int +m32c_srcdest_store (struct m32c_pv_state *state, struct srcdest loc, + pv_t value, int size) +{ + if (loc.kind == srcdest_mem) + { + if (pv_area_store_would_trash (state->stack, loc.addr)) + return 1; + pv_area_store (state->stack, loc.addr, size, value); + } + else if (loc.kind == srcdest_partial_reg) + *loc.reg = pv_unknown (); + else + *loc.reg = value; + + return 0; +} + + +static int +m32c_sign_ext (int v, int bits) +{ + int mask = 1 << (bits - 1); + return (v ^ mask) - mask; +} + +static unsigned int +m32c_next_byte (struct m32c_pv_state *st) +{ + gdb_assert (st->next_addr - st->scan_pc < sizeof (st->insn)); + return st->insn[st->next_addr++ - st->scan_pc]; +} + +static int +m32c_udisp8 (struct m32c_pv_state *st) +{ + return m32c_next_byte (st); +} + + +static int +m32c_sdisp8 (struct m32c_pv_state *st) +{ + return m32c_sign_ext (m32c_next_byte (st), 8); +} + + +static int +m32c_udisp16 (struct m32c_pv_state *st) +{ + int low = m32c_next_byte (st); + int high = m32c_next_byte (st); + + return low + (high << 8); +} + + +static int +m32c_sdisp16 (struct m32c_pv_state *st) +{ + int low = m32c_next_byte (st); + int high = m32c_next_byte (st); + + return m32c_sign_ext (low + (high << 8), 16); +} + + +static int +m32c_udisp24 (struct m32c_pv_state *st) +{ + int low = m32c_next_byte (st); + int mid = m32c_next_byte (st); + int high = m32c_next_byte (st); + + return low + (mid << 8) + (high << 16); +} + + +/* Extract the 'source' field from an m32c MOV.size:G-format instruction. */ +static int +m32c_get_src23 (unsigned char *i) +{ + return (((i[0] & 0x70) >> 2) + | ((i[1] & 0x30) >> 4)); +} + + +/* Extract the 'dest' field from an m32c MOV.size:G-format instruction. */ +static int +m32c_get_dest23 (unsigned char *i) +{ + return (((i[0] & 0x0e) << 1) + | ((i[1] & 0xc0) >> 6)); +} + + +static struct srcdest +m32c_decode_srcdest4 (struct m32c_pv_state *st, + int code, int size) +{ + struct srcdest sd; + + if (code < 6) + sd.kind = (size == 2 ? srcdest_reg : srcdest_partial_reg); + else + sd.kind = srcdest_mem; + + switch (code) + { + case 0x0: sd.reg = (size == 1 ? &st->r0 : &st->r0); break; + case 0x1: sd.reg = (size == 1 ? &st->r0 : &st->r1); break; + case 0x2: sd.reg = (size == 1 ? &st->r1 : &st->r2); break; + case 0x3: sd.reg = (size == 1 ? &st->r1 : &st->r3); break; + + case 0x4: sd.reg = &st->a0; break; + case 0x5: sd.reg = &st->a1; break; + + case 0x6: sd.addr = st->a0; break; + case 0x7: sd.addr = st->a1; break; + + case 0x8: sd.addr = pv_add_constant (st->a0, m32c_udisp8 (st)); break; + case 0x9: sd.addr = pv_add_constant (st->a1, m32c_udisp8 (st)); break; + case 0xa: sd.addr = pv_add_constant (st->sb, m32c_udisp8 (st)); break; + case 0xb: sd.addr = pv_add_constant (st->fb, m32c_sdisp8 (st)); break; + + case 0xc: sd.addr = pv_add_constant (st->a0, m32c_udisp16 (st)); break; + case 0xd: sd.addr = pv_add_constant (st->a1, m32c_udisp16 (st)); break; + case 0xe: sd.addr = pv_add_constant (st->sb, m32c_udisp16 (st)); break; + case 0xf: sd.addr = pv_constant (m32c_udisp16 (st)); break; + + default: + gdb_assert (0); + } + + return sd; +} + + +static struct srcdest +m32c_decode_sd23 (struct m32c_pv_state *st, int code, int size, int ind) +{ + struct srcdest sd; + + switch (code) + { + case 0x12: + case 0x13: + case 0x10: + case 0x11: + sd.kind = (size == 1) ? srcdest_partial_reg : srcdest_reg; + break; + + case 0x02: + case 0x03: + sd.kind = (size == 4) ? srcdest_reg : srcdest_partial_reg; + break; + + default: + sd.kind = srcdest_mem; + break; + + } + + switch (code) + { + case 0x12: sd.reg = &st->r0; break; + case 0x13: sd.reg = &st->r1; break; + case 0x10: sd.reg = ((size == 1) ? &st->r0 : &st->r2); break; + case 0x11: sd.reg = ((size == 1) ? &st->r1 : &st->r3); break; + case 0x02: sd.reg = &st->a0; break; + case 0x03: sd.reg = &st->a1; break; + + case 0x00: sd.addr = st->a0; break; + case 0x01: sd.addr = st->a1; break; + case 0x04: sd.addr = pv_add_constant (st->a0, m32c_udisp8 (st)); break; + case 0x05: sd.addr = pv_add_constant (st->a1, m32c_udisp8 (st)); break; + case 0x06: sd.addr = pv_add_constant (st->sb, m32c_udisp8 (st)); break; + case 0x07: sd.addr = pv_add_constant (st->fb, m32c_sdisp8 (st)); break; + case 0x08: sd.addr = pv_add_constant (st->a0, m32c_udisp16 (st)); break; + case 0x09: sd.addr = pv_add_constant (st->a1, m32c_udisp16 (st)); break; + case 0x0a: sd.addr = pv_add_constant (st->sb, m32c_udisp16 (st)); break; + case 0x0b: sd.addr = pv_add_constant (st->fb, m32c_sdisp16 (st)); break; + case 0x0c: sd.addr = pv_add_constant (st->a0, m32c_udisp24 (st)); break; + case 0x0d: sd.addr = pv_add_constant (st->a1, m32c_udisp24 (st)); break; + case 0x0f: sd.addr = pv_constant (m32c_udisp16 (st)); break; + case 0x0e: sd.addr = pv_constant (m32c_udisp24 (st)); break; + default: + gdb_assert (0); + } + + if (ind) + { + sd.addr = m32c_srcdest_fetch (st, sd, 4); + sd.kind = srcdest_mem; + } + + return sd; +} + + +/* The r16c and r32c machines have instructions with similar + semantics, but completely different machine language encodings. So + we break out the semantics into their own functions, and leave + machine-specific decoding in m32c_analyze_prologue. + + The following functions all expect their arguments already decoded, + and they all return zero if analysis should continue past this + instruction, or non-zero if analysis should stop. */ + + +/* Simulate an 'enter SIZE' instruction in STATE. */ +static int +m32c_pv_enter (struct m32c_pv_state *state, int size) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (state->arch); + + /* If simulating this store would require us to forget + everything we know about the stack frame in the name of + accuracy, it would be better to just quit now. */ + if (pv_area_store_would_trash (state->stack, state->sp)) + return 1; + + if (m32c_pv_push (state, state->fb, tdep->push_addr_bytes)) + return 1; + state->fb = state->sp; + state->sp = pv_add_constant (state->sp, -size); + + return 0; +} + + +static int +m32c_pv_pushm_one (struct m32c_pv_state *state, pv_t reg, + int bit, int src, int size) +{ + if (bit & src) + { + if (m32c_pv_push (state, reg, size)) + return 1; + } + + return 0; +} + + +/* Simulate a 'pushm SRC' instruction in STATE. */ +static int +m32c_pv_pushm (struct m32c_pv_state *state, int src) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (state->arch); + + /* The bits in SRC indicating which registers to save are: + r0 r1 r2 r3 a0 a1 sb fb */ + return + ( m32c_pv_pushm_one (state, state->fb, 0x01, src, tdep->push_addr_bytes) + || m32c_pv_pushm_one (state, state->sb, 0x02, src, tdep->push_addr_bytes) + || m32c_pv_pushm_one (state, state->a1, 0x04, src, tdep->push_addr_bytes) + || m32c_pv_pushm_one (state, state->a0, 0x08, src, tdep->push_addr_bytes) + || m32c_pv_pushm_one (state, state->r3, 0x10, src, 2) + || m32c_pv_pushm_one (state, state->r2, 0x20, src, 2) + || m32c_pv_pushm_one (state, state->r1, 0x40, src, 2) + || m32c_pv_pushm_one (state, state->r0, 0x80, src, 2)); +} + +/* Return non-zero if VALUE is the first incoming argument register. */ + +static int +m32c_is_1st_arg_reg (struct m32c_pv_state *state, pv_t value) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (state->arch); + return (value.kind == pvk_register + && (gdbarch_bfd_arch_info (state->arch)->mach == bfd_mach_m16c + ? (value.reg == tdep->r1->num) + : (value.reg == tdep->r0->num)) + && value.k == 0); +} + +/* Return non-zero if VALUE is an incoming argument register. */ + +static int +m32c_is_arg_reg (struct m32c_pv_state *state, pv_t value) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (state->arch); + return (value.kind == pvk_register + && (gdbarch_bfd_arch_info (state->arch)->mach == bfd_mach_m16c + ? (value.reg == tdep->r1->num || value.reg == tdep->r2->num) + : (value.reg == tdep->r0->num)) + && value.k == 0); +} + +/* Return non-zero if a store of VALUE to LOC is probably spilling an + argument register to its stack slot in STATE. Such instructions + should be included in the prologue, if possible. + + The store is a spill if: + - the value being stored is the original value of an argument register; + - the value has not already been stored somewhere in STACK; and + - LOC is a stack slot (e.g., a memory location whose address is + relative to the original value of the SP). */ + +static int +m32c_is_arg_spill (struct m32c_pv_state *st, + struct srcdest loc, + pv_t value) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (st->arch); + + return (m32c_is_arg_reg (st, value) + && loc.kind == srcdest_mem + && pv_is_register (loc.addr, tdep->sp->num) + && ! pv_area_find_reg (st->stack, st->arch, value.reg, 0)); +} + +/* Return non-zero if a store of VALUE to LOC is probably + copying the struct return address into an address register + for immediate use. This is basically a "spill" into the + address register, instead of onto the stack. + + The prerequisites are: + - value being stored is original value of the FIRST arg register; + - value has not already been stored on stack; and + - LOC is an address register (a0 or a1). */ + +static int +m32c_is_struct_return (struct m32c_pv_state *st, + struct srcdest loc, + pv_t value) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (st->arch); + + return (m32c_is_1st_arg_reg (st, value) + && !pv_area_find_reg (st->stack, st->arch, value.reg, 0) + && loc.kind == srcdest_reg + && (pv_is_register (*loc.reg, tdep->a0->num) + || pv_is_register (*loc.reg, tdep->a1->num))); +} + +/* Return non-zero if a 'pushm' saving the registers indicated by SRC + was a register save: + - all the named registers should have their original values, and + - the stack pointer should be at a constant offset from the + original stack pointer. */ +static int +m32c_pushm_is_reg_save (struct m32c_pv_state *st, int src) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (st->arch); + /* The bits in SRC indicating which registers to save are: + r0 r1 r2 r3 a0 a1 sb fb */ + return + (pv_is_register (st->sp, tdep->sp->num) + && (! (src & 0x01) || pv_is_register_k (st->fb, tdep->fb->num, 0)) + && (! (src & 0x02) || pv_is_register_k (st->sb, tdep->sb->num, 0)) + && (! (src & 0x04) || pv_is_register_k (st->a1, tdep->a1->num, 0)) + && (! (src & 0x08) || pv_is_register_k (st->a0, tdep->a0->num, 0)) + && (! (src & 0x10) || pv_is_register_k (st->r3, tdep->r3->num, 0)) + && (! (src & 0x20) || pv_is_register_k (st->r2, tdep->r2->num, 0)) + && (! (src & 0x40) || pv_is_register_k (st->r1, tdep->r1->num, 0)) + && (! (src & 0x80) || pv_is_register_k (st->r0, tdep->r0->num, 0))); +} + + +/* Function for finding saved registers in a 'struct pv_area'; we pass + this to pv_area_scan. + + If VALUE is a saved register, ADDR says it was saved at a constant + offset from the frame base, and SIZE indicates that the whole + register was saved, record its offset in RESULT_UNTYPED. */ +static void +check_for_saved (void *prologue_untyped, pv_t addr, CORE_ADDR size, pv_t value) +{ + struct m32c_prologue *prologue = (struct m32c_prologue *) prologue_untyped; + struct gdbarch *arch = prologue->arch; + struct gdbarch_tdep *tdep = gdbarch_tdep (arch); + + /* Is this the unchanged value of some register being saved on the + stack? */ + if (value.kind == pvk_register + && value.k == 0 + && pv_is_register (addr, tdep->sp->num)) + { + /* Some registers require special handling: they're saved as a + larger value than the register itself. */ + CORE_ADDR saved_size = register_size (arch, value.reg); + + if (value.reg == tdep->pc->num) + saved_size = tdep->ret_addr_bytes; + else if (gdbarch_register_type (arch, value.reg) + == tdep->data_addr_reg_type) + saved_size = tdep->push_addr_bytes; + + if (size == saved_size) + { + /* Find which end of the saved value corresponds to our + register. */ + if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG) + prologue->reg_offset[value.reg] + = (addr.k + saved_size - register_size (arch, value.reg)); + else + prologue->reg_offset[value.reg] = addr.k; + } + } +} + + +/* Analyze the function prologue for ARCH at START, going no further + than LIMIT, and place a description of what we found in + PROLOGUE. */ +void +m32c_analyze_prologue (struct gdbarch *arch, + CORE_ADDR start, CORE_ADDR limit, + struct m32c_prologue *prologue) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (arch); + unsigned long mach = gdbarch_bfd_arch_info (arch)->mach; + CORE_ADDR after_last_frame_related_insn; + struct cleanup *back_to; + struct m32c_pv_state st; + + st.arch = arch; + st.r0 = pv_register (tdep->r0->num, 0); + st.r1 = pv_register (tdep->r1->num, 0); + st.r2 = pv_register (tdep->r2->num, 0); + st.r3 = pv_register (tdep->r3->num, 0); + st.a0 = pv_register (tdep->a0->num, 0); + st.a1 = pv_register (tdep->a1->num, 0); + st.sb = pv_register (tdep->sb->num, 0); + st.fb = pv_register (tdep->fb->num, 0); + st.sp = pv_register (tdep->sp->num, 0); + st.pc = pv_register (tdep->pc->num, 0); + st.stack = make_pv_area (tdep->sp->num); + back_to = make_cleanup_free_pv_area (st.stack); + + /* Record that the call instruction has saved the return address on + the stack. */ + m32c_pv_push (&st, st.pc, tdep->ret_addr_bytes); + + memset (prologue, 0, sizeof (*prologue)); + prologue->arch = arch; + { + int i; + for (i = 0; i < M32C_MAX_NUM_REGS; i++) + prologue->reg_offset[i] = 1; + } + + st.scan_pc = after_last_frame_related_insn = start; + + while (st.scan_pc < limit) + { + pv_t pre_insn_fb = st.fb; + pv_t pre_insn_sp = st.sp; + + /* In theory we could get in trouble by trying to read ahead + here, when we only know we're expecting one byte. In + practice I doubt anyone will care, and it makes the rest of + the code easier. */ + if (target_read_memory (st.scan_pc, st.insn, sizeof (st.insn))) + /* If we can't fetch the instruction from memory, stop here + and hope for the best. */ + break; + st.next_addr = st.scan_pc; + + /* The assembly instructions are written as they appear in the + section of the processor manuals that describe the + instruction encodings. + + When a single assembly language instruction has several + different machine-language encodings, the manual + distinguishes them by a number in parens, before the + mnemonic. Those numbers are included, as well. + + The srcdest decoding instructions have the same names as the + analogous functions in the simulator. */ + if (mach == bfd_mach_m16c) + { + /* (1) ENTER #imm8 */ + if (st.insn[0] == 0x7c && st.insn[1] == 0xf2) + { + if (m32c_pv_enter (&st, st.insn[2])) + break; + st.next_addr += 3; + } + /* (1) PUSHM src */ + else if (st.insn[0] == 0xec) + { + int src = st.insn[1]; + if (m32c_pv_pushm (&st, src)) + break; + st.next_addr += 2; + + if (m32c_pushm_is_reg_save (&st, src)) + after_last_frame_related_insn = st.next_addr; + } + + /* (6) MOV.size:G src, dest */ + else if ((st.insn[0] & 0xfe) == 0x72) + { + int size = (st.insn[0] & 0x01) ? 2 : 1; + + st.next_addr += 2; + + struct srcdest src + = m32c_decode_srcdest4 (&st, (st.insn[1] >> 4) & 0xf, size); + struct srcdest dest + = m32c_decode_srcdest4 (&st, st.insn[1] & 0xf, size); + pv_t src_value = m32c_srcdest_fetch (&st, src, size); + + if (m32c_is_arg_spill (&st, dest, src_value)) + after_last_frame_related_insn = st.next_addr; + else if (m32c_is_struct_return (&st, dest, src_value)) + after_last_frame_related_insn = st.next_addr; + + if (m32c_srcdest_store (&st, dest, src_value, size)) + break; + } + + /* (1) LDC #IMM16, sp */ + else if (st.insn[0] == 0xeb + && st.insn[1] == 0x50) + { + st.next_addr += 2; + st.sp = pv_constant (m32c_udisp16 (&st)); + } + + else + /* We've hit some instruction we don't know how to simulate. + Strictly speaking, we should set every value we're + tracking to "unknown". But we'll be optimistic, assume + that we have enough information already, and stop + analysis here. */ + break; + } + else + { + int src_indirect = 0; + int dest_indirect = 0; + int i = 0; + + gdb_assert (mach == bfd_mach_m32c); + + /* Check for prefix bytes indicating indirect addressing. */ + if (st.insn[0] == 0x41) + { + src_indirect = 1; + i++; + } + else if (st.insn[0] == 0x09) + { + dest_indirect = 1; + i++; + } + else if (st.insn[0] == 0x49) + { + src_indirect = dest_indirect = 1; + i++; + } + + /* (1) ENTER #imm8 */ + if (st.insn[i] == 0xec) + { + if (m32c_pv_enter (&st, st.insn[i + 1])) + break; + st.next_addr += 2; + } + + /* (1) PUSHM src */ + else if (st.insn[i] == 0x8f) + { + int src = st.insn[i + 1]; + if (m32c_pv_pushm (&st, src)) + break; + st.next_addr += 2; + + if (m32c_pushm_is_reg_save (&st, src)) + after_last_frame_related_insn = st.next_addr; + } + + /* (7) MOV.size:G src, dest */ + else if ((st.insn[i] & 0x80) == 0x80 + && (st.insn[i + 1] & 0x0f) == 0x0b + && m32c_get_src23 (&st.insn[i]) < 20 + && m32c_get_dest23 (&st.insn[i]) < 20) + { + int bw = st.insn[i] & 0x01; + int size = bw ? 2 : 1; + + st.next_addr += 2; + + struct srcdest src + = m32c_decode_sd23 (&st, m32c_get_src23 (&st.insn[i]), + size, src_indirect); + struct srcdest dest + = m32c_decode_sd23 (&st, m32c_get_dest23 (&st.insn[i]), + size, dest_indirect); + pv_t src_value = m32c_srcdest_fetch (&st, src, size); + + if (m32c_is_arg_spill (&st, dest, src_value)) + after_last_frame_related_insn = st.next_addr; + + if (m32c_srcdest_store (&st, dest, src_value, size)) + break; + } + /* (2) LDC #IMM24, sp */ + else if (st.insn[i] == 0xd5 + && st.insn[i + 1] == 0x29) + { + st.next_addr += 2; + st.sp = pv_constant (m32c_udisp24 (&st)); + } + else + /* We've hit some instruction we don't know how to simulate. + Strictly speaking, we should set every value we're + tracking to "unknown". But we'll be optimistic, assume + that we have enough information already, and stop + analysis here. */ + break; + } + + /* If this instruction changed the FB or decreased the SP (i.e., + allocated more stack space), then this may be a good place to + declare the prologue finished. However, there are some + exceptions: + + - If the instruction just changed the FB back to its original + value, then that's probably a restore instruction. The + prologue should definitely end before that. + + - If the instruction increased the value of the SP (that is, + shrunk the frame), then it's probably part of a frame + teardown sequence, and the prologue should end before + that. */ + + if (! pv_is_identical (st.fb, pre_insn_fb)) + { + if (! pv_is_register_k (st.fb, tdep->fb->num, 0)) + after_last_frame_related_insn = st.next_addr; + } + else if (! pv_is_identical (st.sp, pre_insn_sp)) + { + /* The comparison of the constants looks odd, there, because + .k is unsigned. All it really means is that the SP is + lower than it was before the instruction. */ + if ( pv_is_register (pre_insn_sp, tdep->sp->num) + && pv_is_register (st.sp, tdep->sp->num) + && ((pre_insn_sp.k - st.sp.k) < (st.sp.k - pre_insn_sp.k))) + after_last_frame_related_insn = st.next_addr; + } + + st.scan_pc = st.next_addr; + } + + /* Did we load a constant value into the stack pointer? */ + if (pv_is_constant (st.sp)) + prologue->kind = prologue_first_frame; + + /* Alternatively, did we initialize the frame pointer? Remember + that the CFA is the address after the return address. */ + if (pv_is_register (st.fb, tdep->sp->num)) + { + prologue->kind = prologue_with_frame_ptr; + prologue->frame_ptr_offset = st.fb.k; + } + + /* Is the frame size a known constant? Remember that frame_size is + actually the offset from the CFA to the SP (i.e., a negative + value). */ + else if (pv_is_register (st.sp, tdep->sp->num)) + { + prologue->kind = prologue_sans_frame_ptr; + prologue->frame_size = st.sp.k; + } + + /* We haven't been able to make sense of this function's frame. Treat + it as the first frame. */ + else + prologue->kind = prologue_first_frame; + + /* Record where all the registers were saved. */ + pv_area_scan (st.stack, check_for_saved, (void *) prologue); + + prologue->prologue_end = after_last_frame_related_insn; + + do_cleanups (back_to); +} + + +static CORE_ADDR +m32c_skip_prologue (CORE_ADDR ip) +{ + char *name; + CORE_ADDR func_addr, func_end, sal_end; + struct m32c_prologue p; + + /* Try to find the extent of the function that contains IP. */ + if (! find_pc_partial_function (ip, &name, &func_addr, &func_end)) + return ip; + + /* Find end by prologue analysis. */ + m32c_analyze_prologue (current_gdbarch, ip, func_end, &p); + /* Find end by line info. */ + sal_end = skip_prologue_using_sal (ip); + /* Return whichever is lower. */ + if (sal_end != 0 && sal_end != ip && sal_end < p.prologue_end) + return sal_end; + else + return p.prologue_end; +} + + + +/* Stack unwinding. */ + +static struct m32c_prologue * +m32c_analyze_frame_prologue (struct frame_info *next_frame, + void **this_prologue_cache) +{ + if (! *this_prologue_cache) + { + CORE_ADDR func_start = frame_func_unwind (next_frame); + CORE_ADDR stop_addr = frame_pc_unwind (next_frame); + + /* If we couldn't find any function containing the PC, then + just initialize the prologue cache, but don't do anything. */ + if (! func_start) + stop_addr = func_start; + + *this_prologue_cache = FRAME_OBSTACK_ZALLOC (struct m32c_prologue); + m32c_analyze_prologue (get_frame_arch (next_frame), + func_start, stop_addr, *this_prologue_cache); + } + + return *this_prologue_cache; +} + + +static CORE_ADDR +m32c_frame_base (struct frame_info *next_frame, + void **this_prologue_cache) +{ + struct m32c_prologue *p + = m32c_analyze_frame_prologue (next_frame, this_prologue_cache); + struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (next_frame)); + + /* In functions that use alloca, the distance between the stack + pointer and the frame base varies dynamically, so we can't use + the SP plus static information like prologue analysis to find the + frame base. However, such functions must have a frame pointer, + to be able to restore the SP on exit. So whenever we do have a + frame pointer, use that to find the base. */ + switch (p->kind) + { + case prologue_with_frame_ptr: + { + CORE_ADDR fb + = frame_unwind_register_unsigned (next_frame, tdep->fb->num); + return fb - p->frame_ptr_offset; + } + + case prologue_sans_frame_ptr: + { + CORE_ADDR sp + = frame_unwind_register_unsigned (next_frame, tdep->sp->num); + return sp - p->frame_size; + } + + case prologue_first_frame: + return 0; + + default: + gdb_assert (0); + } +} + + +static void +m32c_this_id (struct frame_info *next_frame, + void **this_prologue_cache, + struct frame_id *this_id) +{ + CORE_ADDR base = m32c_frame_base (next_frame, this_prologue_cache); + + if (base) + *this_id = frame_id_build (base, frame_func_unwind (next_frame)); + /* Otherwise, leave it unset, and that will terminate the backtrace. */ +} + + +static void +m32c_prev_register (struct frame_info *next_frame, + void **this_prologue_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, gdb_byte *bufferp) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (next_frame)); + struct m32c_prologue *p + = m32c_analyze_frame_prologue (next_frame, this_prologue_cache); + CORE_ADDR frame_base = m32c_frame_base (next_frame, this_prologue_cache); + int reg_size = register_size (get_frame_arch (next_frame), regnum); + + if (regnum == tdep->sp->num) + { + *optimizedp = 0; + *lvalp = not_lval; + *addrp = 0; + *realnump = -1; + if (bufferp) + store_unsigned_integer (bufferp, reg_size, frame_base); + } + + /* If prologue analysis says we saved this register somewhere, + return a description of the stack slot holding it. */ + else if (p->reg_offset[regnum] != 1) + { + *optimizedp = 0; + *lvalp = lval_memory; + *addrp = frame_base + p->reg_offset[regnum]; + *realnump = -1; + if (bufferp) + get_frame_memory (next_frame, *addrp, bufferp, reg_size); + } + + /* Otherwise, presume we haven't changed the value of this + register, and get it from the next frame. */ + else + frame_register_unwind (next_frame, regnum, + optimizedp, lvalp, addrp, realnump, bufferp); +} + + +static const struct frame_unwind m32c_unwind = { + NORMAL_FRAME, + m32c_this_id, + m32c_prev_register +}; + + +static const struct frame_unwind * +m32c_frame_sniffer (struct frame_info *next_frame) +{ + return &m32c_unwind; +} + + +static CORE_ADDR +m32c_unwind_pc (struct gdbarch *arch, struct frame_info *next_frame) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (arch); + return frame_unwind_register_unsigned (next_frame, tdep->pc->num); +} + + +static CORE_ADDR +m32c_unwind_sp (struct gdbarch *arch, struct frame_info *next_frame) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (arch); + return frame_unwind_register_unsigned (next_frame, tdep->sp->num); +} + + +/* Inferior calls. */ + +/* The calling conventions, according to GCC: + + r8c, m16c + --------- + First arg may be passed in r1l or r1 if it (1) fits (QImode or + HImode), (2) is named, and (3) is an integer or pointer type (no + structs, floats, etc). Otherwise, it's passed on the stack. + + Second arg may be passed in r2, same restrictions (but not QImode), + even if the first arg is passed on the stack. + + Third and further args are passed on the stack. No padding is + used, stack "alignment" is 8 bits. + + m32cm, m32c + ----------- + + First arg may be passed in r0l or r0, same restrictions as above. + + Second and further args are passed on the stack. Padding is used + after QImode parameters (i.e. lower-addressed byte is the value, + higher-addressed byte is the padding), stack "alignment" is 16 + bits. */ + + +/* Return true if TYPE is a type that can be passed in registers. (We + ignore the size, and pay attention only to the type code; + acceptable sizes depends on which register is being considered to + hold it.) */ +static int +m32c_reg_arg_type (struct type *type) +{ + enum type_code code = TYPE_CODE (type); + + return (code == TYPE_CODE_INT + || code == TYPE_CODE_ENUM + || code == TYPE_CODE_PTR + || code == TYPE_CODE_REF + || code == TYPE_CODE_BOOL + || code == TYPE_CODE_CHAR); +} + + +static CORE_ADDR +m32c_push_dummy_call (struct gdbarch *gdbarch, struct value *function, + struct regcache *regcache, CORE_ADDR bp_addr, int nargs, + struct value **args, CORE_ADDR sp, int struct_return, + CORE_ADDR struct_addr) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach; + CORE_ADDR cfa; + int i; + + /* The number of arguments given in this function's prototype, or + zero if it has a non-prototyped function type. The m32c ABI + passes arguments mentioned in the prototype differently from + those in the ellipsis of a varargs function, or from those passed + to a non-prototyped function. */ + int num_prototyped_args = 0; + + { + struct type *func_type = value_type (function); + + gdb_assert (TYPE_CODE (func_type) == TYPE_CODE_FUNC || + TYPE_CODE (func_type) == TYPE_CODE_METHOD); + +#if 0 + /* The ABI description in gcc/config/m32c/m32c.abi says that + we need to handle prototyped and non-prototyped functions + separately, but the code in GCC doesn't actually do so. */ + if (TYPE_PROTOTYPED (func_type)) +#endif + num_prototyped_args = TYPE_NFIELDS (func_type); + } + + /* First, if the function returns an aggregate by value, push a + pointer to a buffer for it. This doesn't affect the way + subsequent arguments are allocated to registers. */ + if (struct_return) + { + int ptr_len = TYPE_LENGTH (tdep->ptr_voyd); + sp -= ptr_len; + write_memory_unsigned_integer (sp, ptr_len, struct_addr); + } + + /* Push the arguments. */ + for (i = nargs - 1; i >= 0; i--) + { + struct value *arg = args[i]; + const gdb_byte *arg_bits = value_contents (arg); + struct type *arg_type = value_type (arg); + ULONGEST arg_size = TYPE_LENGTH (arg_type); + + /* Can it go in r1 or r1l (for m16c) or r0 or r0l (for m32c)? */ + if (i == 0 + && arg_size <= 2 + && i < num_prototyped_args + && m32c_reg_arg_type (arg_type)) + { + /* Extract and re-store as an integer as a terse way to make + sure it ends up in the least significant end of r1. (GDB + should avoid assuming endianness, even on uni-endian + processors.) */ + ULONGEST u = extract_unsigned_integer (arg_bits, arg_size); + struct m32c_reg *reg = (mach == bfd_mach_m16c) ? tdep->r1 : tdep->r0; + regcache_cooked_write_unsigned (regcache, reg->num, u); + } + + /* Can it go in r2? */ + else if (mach == bfd_mach_m16c + && i == 1 + && arg_size == 2 + && i < num_prototyped_args + && m32c_reg_arg_type (arg_type)) + regcache_cooked_write (regcache, tdep->r2->num, arg_bits); + + /* Everything else goes on the stack. */ + else + { + sp -= arg_size; + + /* Align the stack. */ + if (mach == bfd_mach_m32c) + sp &= ~1; + + write_memory (sp, arg_bits, arg_size); + } + } + + /* This is the CFA we use to identify the dummy frame. */ + cfa = sp; + + /* Push the return address. */ + sp -= tdep->ret_addr_bytes; + write_memory_unsigned_integer (sp, tdep->ret_addr_bytes, bp_addr); + + /* Update the stack pointer. */ + regcache_cooked_write_unsigned (regcache, tdep->sp->num, sp); + + /* We need to borrow an odd trick from the i386 target here. + + The value we return from this function gets used as the stack + address (the CFA) for the dummy frame's ID. The obvious thing is + to return the new TOS. However, that points at the return + address, saved on the stack, which is inconsistent with the CFA's + described by GCC's DWARF 2 .debug_frame information: DWARF 2 + .debug_frame info uses the address immediately after the saved + return address. So you end up with a dummy frame whose CFA + points at the return address, but the frame for the function + being called has a CFA pointing after the return address: the + younger CFA is *greater than* the older CFA. The sanity checks + in frame.c don't like that. + + So we try to be consistent with the CFA's used by DWARF 2. + Having a dummy frame and a real frame with the *same* CFA is + tolerable. */ + return cfa; +} + + +static struct frame_id +m32c_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) +{ + /* This needs to return a frame ID whose PC is the return address + passed to m32c_push_dummy_call, and whose stack_addr is the SP + m32c_push_dummy_call returned. + + m32c_unwind_sp gives us the CFA, which is the value the SP had + before the return address was pushed. */ + return frame_id_build (m32c_unwind_sp (gdbarch, next_frame), + frame_pc_unwind (next_frame)); +} + + + +/* Return values. */ + +/* Return value conventions, according to GCC: + + r8c, m16c + --------- + + QImode in r0l + HImode in r0 + SImode in r2r0 + near pointer in r0 + far pointer in r2r0 + + Aggregate values (regardless of size) are returned by pushing a + pointer to a temporary area on the stack after the args are pushed. + The function fills in this area with the value. Note that this + pointer on the stack does not affect how register arguments, if any, + are configured. + + m32cm, m32c + ----------- + Same. */ + +/* Return non-zero if values of type TYPE are returned by storing them + in a buffer whose address is passed on the stack, ahead of the + other arguments. */ +static int +m32c_return_by_passed_buf (struct type *type) +{ + enum type_code code = TYPE_CODE (type); + + return (code == TYPE_CODE_STRUCT + || code == TYPE_CODE_UNION); +} + +static enum return_value_convention +m32c_return_value (struct gdbarch *gdbarch, + struct type *valtype, + struct regcache *regcache, + gdb_byte *readbuf, + const gdb_byte *writebuf) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + enum return_value_convention conv; + ULONGEST valtype_len = TYPE_LENGTH (valtype); + + if (m32c_return_by_passed_buf (valtype)) + conv = RETURN_VALUE_STRUCT_CONVENTION; + else + conv = RETURN_VALUE_REGISTER_CONVENTION; + + if (readbuf) + { + /* We should never be called to find values being returned by + RETURN_VALUE_STRUCT_CONVENTION. Those can't be located, + unless we made the call ourselves. */ + gdb_assert (conv == RETURN_VALUE_REGISTER_CONVENTION); + + gdb_assert (valtype_len <= 8); + + /* Anything that fits in r0 is returned there. */ + if (valtype_len <= TYPE_LENGTH (tdep->r0->type)) + { + ULONGEST u; + regcache_cooked_read_unsigned (regcache, tdep->r0->num, &u); + store_unsigned_integer (readbuf, valtype_len, u); + } + else + { + /* Everything else is passed in mem0, using as many bytes as + needed. This is not what the Renesas tools do, but it's + what GCC does at the moment. */ + struct minimal_symbol *mem0 + = lookup_minimal_symbol ("mem0", NULL, NULL); + + if (! mem0) + error ("The return value is stored in memory at 'mem0', " + "but GDB cannot find\n" + "its address."); + read_memory (SYMBOL_VALUE_ADDRESS (mem0), readbuf, valtype_len); + } + } + + if (writebuf) + { + /* We should never be called to store values to be returned + using RETURN_VALUE_STRUCT_CONVENTION. We have no way of + finding the buffer, unless we made the call ourselves. */ + gdb_assert (conv == RETURN_VALUE_REGISTER_CONVENTION); + + gdb_assert (valtype_len <= 8); + + /* Anything that fits in r0 is returned there. */ + if (valtype_len <= TYPE_LENGTH (tdep->r0->type)) + { + ULONGEST u = extract_unsigned_integer (writebuf, valtype_len); + regcache_cooked_write_unsigned (regcache, tdep->r0->num, u); + } + else + { + /* Everything else is passed in mem0, using as many bytes as + needed. This is not what the Renesas tools do, but it's + what GCC does at the moment. */ + struct minimal_symbol *mem0 + = lookup_minimal_symbol ("mem0", NULL, NULL); + + if (! mem0) + error ("The return value is stored in memory at 'mem0', " + "but GDB cannot find\n" + " its address."); + write_memory (SYMBOL_VALUE_ADDRESS (mem0), + (char *) writebuf, valtype_len); + } + } + + return conv; +} + + + +/* Trampolines. */ + +/* The m16c and m32c use a trampoline function for indirect function + calls. An indirect call looks like this: + + ... push arguments ... + ... push target function address ... + jsr.a m32c_jsri16 + + The code for m32c_jsri16 looks like this: + + m32c_jsri16: + + # Save return address. + pop.w m32c_jsri_ret + pop.b m32c_jsri_ret+2 + + # Store target function address. + pop.w m32c_jsri_addr + + # Re-push return address. + push.b m32c_jsri_ret+2 + push.w m32c_jsri_ret + + # Call the target function. + jmpi.a m32c_jsri_addr + + Without further information, GDB will treat calls to m32c_jsri16 + like calls to any other function. Since m32c_jsri16 doesn't have + debugging information, that normally means that GDB sets a step- + resume breakpoint and lets the program continue --- which is not + what the user wanted. (Giving the trampoline debugging info + doesn't help: the user expects the program to stop in the function + their program is calling, not in some trampoline code they've never + seen before.) + + The SKIP_TRAMPOLINE_CODE gdbarch method tells GDB how to step + through such trampoline functions transparently to the user. When + given the address of a trampoline function's first instruction, + SKIP_TRAMPOLINE_CODE should return the address of the first + instruction of the function really being called. If GDB decides it + wants to step into that function, it will set a breakpoint there + and silently continue to it. + + We recognize the trampoline by name, and extract the target address + directly from the stack. This isn't great, but recognizing by its + code sequence seems more fragile. */ + +static CORE_ADDR +m32c_skip_trampoline_code (CORE_ADDR stop_pc) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + + /* It would be nicer to simply look up the addresses of known + trampolines once, and then compare stop_pc with them. However, + we'd need to ensure that that cached address got invalidated when + someone loaded a new executable, and I'm not quite sure of the + best way to do that. find_pc_partial_function does do some + caching, so we'll see how this goes. */ + char *name; + CORE_ADDR start, end; + + if (find_pc_partial_function (stop_pc, &name, &start, &end)) + { + /* Are we stopped at the beginning of the trampoline function? */ + if (strcmp (name, "m32c_jsri16") == 0 + && stop_pc == start) + { + /* Get the stack pointer. The return address is at the top, + and the target function's address is just below that. We + know it's a two-byte address, since the trampoline is + m32c_jsri*16*. */ + CORE_ADDR sp = get_frame_sp (get_current_frame ()); + CORE_ADDR target + = read_memory_unsigned_integer (sp + tdep->ret_addr_bytes, 2); + + /* What we have now is the address of a jump instruction. + What we need is the destination of that jump. + The opcode is 1 byte, and the destination is the next 3 bytes. + */ + target = read_memory_unsigned_integer (target + 1, 3); + return target; + } + } + + return 0; +} + + +/* Address/pointer conversions. */ + +/* On the m16c, there is a 24-bit address space, but only a very few + instructions can generate addresses larger than 0xffff: jumps, + jumps to subroutines, and the lde/std (load/store extended) + instructions. + + Since GCC can only support one size of pointer, we can't have + distinct 'near' and 'far' pointer types; we have to pick one size + for everything. If we wanted to use 24-bit pointers, then GCC + would have to use lde and ste for all memory references, which + would be terrible for performance and code size. So the GNU + toolchain uses 16-bit pointers for everything, and gives up the + ability to have pointers point outside the first 64k of memory. + + However, as a special hack, we let the linker place functions at + addresses above 0xffff, as long as it also places a trampoline in + the low 64k for every function whose address is taken. Each + trampoline consists of a single jmp.a instruction that jumps to the + function's real entry point. Pointers to functions can be 16 bits + long, even though the functions themselves are at higher addresses: + the pointers refer to the trampolines, not the functions. + + This complicates things for GDB, however: given the address of a + function (from debug info or linker symbols, say) which could be + anywhere in the 24-bit address space, how can we find an + appropriate 16-bit value to use as a pointer to it? + + If the linker has not generated a trampoline for the function, + we're out of luck. Well, I guess we could malloc some space and + write a jmp.a instruction to it, but I'm not going to get into that + at the moment. + + If the linker has generated a trampoline for the function, then it + also emitted a symbol for the trampoline: if the function's linker + symbol is named NAME, then the function's trampoline's linker + symbol is named NAME.plt. + + So, given a code address: + - We try to find a linker symbol at that address. + - If we find such a symbol named NAME, we look for a linker symbol + named NAME.plt. + - If we find such a symbol, we assume it is a trampoline, and use + its address as the pointer value. + + And, given a function pointer: + - We try to find a linker symbol at that address named NAME.plt. + - If we find such a symbol, we look for a linker symbol named NAME. + - If we find that, we provide that as the function's address. + - If any of the above steps fail, we return the original address + unchanged; it might really be a function in the low 64k. + + See? You *knew* there was a reason you wanted to be a computer + programmer! :) */ + +static void +m32c_m16c_address_to_pointer (struct type *type, gdb_byte *buf, CORE_ADDR addr) +{ + gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR || + TYPE_CODE (type) == TYPE_CODE_REF); + + enum type_code target_code = TYPE_CODE (TYPE_TARGET_TYPE (type)); + + if (target_code == TYPE_CODE_FUNC || target_code == TYPE_CODE_METHOD) + { + /* Try to find a linker symbol at this address. */ + struct minimal_symbol *func_msym = lookup_minimal_symbol_by_pc (addr); + + if (! func_msym) + error ("Cannot convert code address %s to function pointer:\n" + "couldn't find a symbol at that address, to find trampoline.", + paddr_nz (addr)); + + char *func_name = SYMBOL_LINKAGE_NAME (func_msym); + char *tramp_name = xmalloc (strlen (func_name) + 5); + strcpy (tramp_name, func_name); + strcat (tramp_name, ".plt"); + + /* Try to find a linker symbol for the trampoline. */ + struct minimal_symbol *tramp_msym + = lookup_minimal_symbol (tramp_name, NULL, NULL); + + /* We've either got another copy of the name now, or don't need + the name any more. */ + xfree (tramp_name); + + if (! tramp_msym) + error ("Cannot convert code address %s to function pointer:\n" + "couldn't find trampoline named '%s.plt'.", + paddr_nz (addr), func_name); + + /* The trampoline's address is our pointer. */ + addr = SYMBOL_VALUE_ADDRESS (tramp_msym); + } + + store_unsigned_integer (buf, TYPE_LENGTH (type), addr); +} + + +static CORE_ADDR +m32c_m16c_pointer_to_address (struct type *type, const gdb_byte *buf) +{ + gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR || + TYPE_CODE (type) == TYPE_CODE_REF); + + CORE_ADDR ptr = extract_unsigned_integer (buf, TYPE_LENGTH (type)); + + enum type_code target_code = TYPE_CODE (TYPE_TARGET_TYPE (type)); + + if (target_code == TYPE_CODE_FUNC || target_code == TYPE_CODE_METHOD) + { + /* See if there is a minimal symbol at that address whose name is + "NAME.plt". */ + struct minimal_symbol *ptr_msym = lookup_minimal_symbol_by_pc (ptr); + + if (ptr_msym) + { + char *ptr_msym_name = SYMBOL_LINKAGE_NAME (ptr_msym); + int len = strlen (ptr_msym_name); + + if (len > 4 + && strcmp (ptr_msym_name + len - 4, ".plt") == 0) + { + /* We have a .plt symbol; try to find the symbol for the + corresponding function. + + Since the trampoline contains a jump instruction, we + could also just extract the jump's target address. I + don't see much advantage one way or the other. */ + char *func_name = xmalloc (len - 4 + 1); + memcpy (func_name, ptr_msym_name, len - 4); + func_name[len - 4] = '\0'; + struct minimal_symbol *func_msym + = lookup_minimal_symbol (func_name, NULL, NULL); + + /* If we do have such a symbol, return its value as the + function's true address. */ + if (func_msym) + ptr = SYMBOL_VALUE_ADDRESS (func_msym); + } + } + } + + return ptr; +} + + + +/* Initialization. */ + +static struct gdbarch * +m32c_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) +{ + struct gdbarch *arch; + struct gdbarch_tdep *tdep; + unsigned long mach = info.bfd_arch_info->mach; + + /* Find a candidate among the list of architectures we've created + already. */ + for (arches = gdbarch_list_lookup_by_info (arches, &info); + arches != NULL; + arches = gdbarch_list_lookup_by_info (arches->next, &info)) + return arches->gdbarch; + + tdep = xcalloc (1, sizeof (*tdep)); + arch = gdbarch_alloc (&info, tdep); + + /* Essential types. */ + make_types (arch); + + /* Address/pointer conversions. */ + if (mach == bfd_mach_m16c) + { + set_gdbarch_address_to_pointer (arch, m32c_m16c_address_to_pointer); + set_gdbarch_pointer_to_address (arch, m32c_m16c_pointer_to_address); + } + + /* Register set. */ + make_regs (arch); + + /* Disassembly. */ + set_gdbarch_print_insn (arch, print_insn_m32c); + + /* Breakpoints. */ + set_gdbarch_breakpoint_from_pc (arch, m32c_breakpoint_from_pc); + + /* Prologue analysis and unwinding. */ + set_gdbarch_inner_than (arch, core_addr_lessthan); + set_gdbarch_skip_prologue (arch, m32c_skip_prologue); + set_gdbarch_unwind_pc (arch, m32c_unwind_pc); + set_gdbarch_unwind_sp (arch, m32c_unwind_sp); +#if 0 + /* I'm dropping the dwarf2 sniffer because it has a few problems. + They may be in the dwarf2 cfi code in GDB, or they may be in + the debug info emitted by the upstream toolchain. I don't + know which, but I do know that the prologue analyzer works better. + MVS 04/13/06 + */ + frame_unwind_append_sniffer (arch, dwarf2_frame_sniffer); +#endif + frame_unwind_append_sniffer (arch, m32c_frame_sniffer); + + /* Inferior calls. */ + set_gdbarch_push_dummy_call (arch, m32c_push_dummy_call); + set_gdbarch_return_value (arch, m32c_return_value); + set_gdbarch_unwind_dummy_id (arch, m32c_unwind_dummy_id); + + /* Trampolines. */ + set_gdbarch_skip_trampoline_code (arch, m32c_skip_trampoline_code); + + return arch; +} + + +void +_initialize_m32c_tdep (void) +{ + register_gdbarch_init (bfd_arch_m32c, m32c_gdbarch_init); + + m32c_dma_reggroup = reggroup_new ("dma", USER_REGGROUP); +} diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c index 213f97a..c798c90 100644 --- a/gdb/mi/mi-main.c +++ b/gdb/mi/mi-main.c @@ -1107,23 +1107,37 @@ captured_mi_execute_command (struct ui_out *uiout, void *data) /* Call the "console" interpreter. */ argv[0] = "console"; argv[1] = context->command; - mi_cmd_interpreter_exec ("-interpreter-exec", argv, 2); + args->rc = mi_cmd_interpreter_exec ("-interpreter-exec", argv, 2); - /* If we changed interpreters, DON'T print out anything. */ + /* If we changed interpreters, DON'T print out anything. */ if (current_interp_named_p (INTERP_MI) || current_interp_named_p (INTERP_MI1) || current_interp_named_p (INTERP_MI2) || current_interp_named_p (INTERP_MI3)) { - /* print the result */ - /* FIXME: Check for errors here. */ - fputs_unfiltered (context->token, raw_stdout); - fputs_unfiltered ("^done", raw_stdout); - mi_out_put (uiout, raw_stdout); - mi_out_rewind (uiout); - fputs_unfiltered ("\n", raw_stdout); - args->action = EXECUTE_COMMAND_DISPLAY_PROMPT; - args->rc = MI_CMD_DONE; + if (args->rc == MI_CMD_DONE) + { + fputs_unfiltered (context->token, raw_stdout); + fputs_unfiltered ("^done", raw_stdout); + mi_out_put (uiout, raw_stdout); + mi_out_rewind (uiout); + fputs_unfiltered ("\n", raw_stdout); + args->action = EXECUTE_COMMAND_DISPLAY_PROMPT; + } + else if (args->rc == MI_CMD_ERROR) + { + if (mi_error_message) + { + fputs_unfiltered (context->token, raw_stdout); + fputs_unfiltered ("^error,msg=\"", raw_stdout); + fputstr_unfiltered (mi_error_message, '"', raw_stdout); + xfree (mi_error_message); + fputs_unfiltered ("\"\n", raw_stdout); + } + mi_out_rewind (uiout); + } + else + mi_out_rewind (uiout); } break; } diff --git a/gdb/mingw-hdep.c b/gdb/mingw-hdep.c index 79b23dc..bb0f50a 100644 --- a/gdb/mingw-hdep.c +++ b/gdb/mingw-hdep.c @@ -167,6 +167,10 @@ gdb_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, for (fd = 0, indx = 0; fd < n; ++fd) { HANDLE fd_h; + struct serial *scb; + + if (!FD_ISSET (fd, readfds) && !FD_ISSET (fd, writefds)) + continue; if (FD_ISSET (fd, readfds)) { @@ -189,6 +193,12 @@ gdb_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, else num_ready++; } + + /* We created at least one event handle for this fd. Let the + device know we are finished with it. */ + scb = serial_for_fd (fd); + if (scb) + serial_done_wait_handle (scb); } return num_ready; diff --git a/gdb/mips-mdebug-tdep.c b/gdb/mips-mdebug-tdep.c index db79713..06cfba5 100644 --- a/gdb/mips-mdebug-tdep.c +++ b/gdb/mips-mdebug-tdep.c @@ -394,7 +394,7 @@ mips_mdebug_frame_prev_register (struct frame_info *next_frame, void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, - int *realnump, void *valuep) + int *realnump, gdb_byte *valuep) { struct mips_frame_cache *info = mips_mdebug_frame_cache (next_frame, this_cache); diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index dcb4406..4378206 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -3719,26 +3719,9 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, big endian targets. It does not seem to be necessary to do the - same for integral types. - - Also don't do this adjustment on O64 binaries. - - cagney/2001-07-23: gdb/179: Also, GCC, when - outputting LE O32 with sizeof (struct) < - mips_abi_regsize(), generates a left shift as - part of storing the argument in a register a - register (the left shift isn't generated when - sizeof (struct) >= mips_abi_regsize()). Since - it is quite possible that this is GCC - contradicting the LE/O32 ABI, GDB has not been - adjusted to accommodate this. Either someone - needs to demonstrate that the LE/O32 ABI - specifies such a left shift OR this new ABI gets - identified as such and GDB gets tweaked - accordingly. */ + same for integral types. */ - if (mips_abi_regsize (gdbarch) < 8 - && TARGET_BYTE_ORDER == BFD_ENDIAN_BIG + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG && partial_len < mips_abi_regsize (gdbarch) && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)) @@ -3788,7 +3771,45 @@ mips_o64_return_value (struct gdbarch *gdbarch, struct type *type, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { - return RETURN_VALUE_STRUCT_CONVENTION; + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + + if (TYPE_CODE (type) == TYPE_CODE_STRUCT + || TYPE_CODE (type) == TYPE_CODE_UNION + || TYPE_CODE (type) == TYPE_CODE_ARRAY) + return RETURN_VALUE_STRUCT_CONVENTION; + else if (fp_register_arg_p (TYPE_CODE (type), type)) + { + /* A floating-point value. It fits in the least significant + part of FP0. */ + if (mips_debug) + fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n"); + mips_xfer_register (regcache, + NUM_REGS + mips_regnum (current_gdbarch)->fp0, + TYPE_LENGTH (type), + TARGET_BYTE_ORDER, readbuf, writebuf, 0); + return RETURN_VALUE_REGISTER_CONVENTION; + } + else + { + /* A scalar extract each part but least-significant-byte + justified. */ + int offset; + int regnum; + for (offset = 0, regnum = MIPS_V0_REGNUM; + offset < TYPE_LENGTH (type); + offset += mips_stack_argsize (gdbarch), regnum++) + { + int xfer = mips_stack_argsize (gdbarch); + if (offset + xfer > TYPE_LENGTH (type)) + xfer = TYPE_LENGTH (type) - offset; + if (mips_debug) + fprintf_unfiltered (gdb_stderr, "Return scalar+%d:%d in $%d\n", + offset, xfer, regnum); + mips_xfer_register (regcache, NUM_REGS + regnum, xfer, + TARGET_BYTE_ORDER, readbuf, writebuf, offset); + } + return RETURN_VALUE_REGISTER_CONVENTION; + } } /* Floating point register management. diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c index 7697862..b4931cb 100644 --- a/gdb/ppc-linux-nat.c +++ b/gdb/ppc-linux-nat.c @@ -30,6 +30,7 @@ #include "target.h" #include "linux-nat.h" +#include <stdint.h> #include <sys/types.h> #include <sys/param.h> #include <signal.h> @@ -44,18 +45,6 @@ #include "gregset.h" #include "ppc-tdep.h" -#ifndef PT_READ_U -#define PT_READ_U PTRACE_PEEKUSR -#endif -#ifndef PT_WRITE_U -#define PT_WRITE_U PTRACE_POKEUSR -#endif - -/* Default the type of the ptrace transfer to int. */ -#ifndef PTRACE_XFER_TYPE -#define PTRACE_XFER_TYPE int -#endif - /* Glibc's headers don't define PTRACE_GETVRREGS so we cannot use a configure time check. Some older glibc's (for instance 2.2.1) don't have a specific powerpc version of ptrace.h, and fall back on @@ -126,13 +115,12 @@ typedef char gdb_vrregset_t[SIZEOF_VRREGS]; /* On PPC processors that support the the Signal Processing Extension (SPE) APU, the general-purpose registers are 64 bits long. - However, the ordinary Linux kernel PTRACE_PEEKUSR / PTRACE_POKEUSR - / PT_READ_U / PT_WRITE_U ptrace calls only access the lower half of - each register, to allow them to behave the same way they do on - non-SPE systems. There's a separate pair of calls, - PTRACE_GETEVRREGS / PTRACE_SETEVRREGS, that read and write the top - halves of all the general-purpose registers at once, along with - some SPE-specific registers. + However, the ordinary Linux kernel PTRACE_PEEKUSER / PTRACE_POKEUSER + ptrace calls only access the lower half of each register, to allow + them to behave the same way they do on non-SPE systems. There's a + separate pair of calls, PTRACE_GETEVRREGS / PTRACE_SETEVRREGS, that + read and write the top halves of all the general-purpose registers + at once, along with some SPE-specific registers. GDB itself continues to claim the general-purpose registers are 32 bits long. It has unnamed raw registers that hold the upper halves @@ -190,7 +178,7 @@ ppc_register_u_addr (int regno) struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); /* NOTE: cagney/2003-11-25: This is the word size used by the ptrace interface, and not the wordsize of the program's ABI. */ - int wordsize = sizeof (PTRACE_XFER_TYPE); + int wordsize = sizeof (long); /* General purpose registers occupy 1 slot each in the buffer */ if (regno >= tdep->ppc_gp0_regnum @@ -384,17 +372,17 @@ fetch_register (int tid, int regno) return; } - /* Read the raw register using PTRACE_XFER_TYPE sized chunks. On a + /* Read the raw register using sizeof(long) sized chunks. On a 32-bit platform, 64-bit floating-point registers will require two transfers. */ for (bytes_transferred = 0; bytes_transferred < register_size (current_gdbarch, regno); - bytes_transferred += sizeof (PTRACE_XFER_TYPE)) + bytes_transferred += sizeof (long)) { errno = 0; - *(PTRACE_XFER_TYPE *) & buf[bytes_transferred] - = ptrace (PT_READ_U, tid, (PTRACE_ARG3_TYPE) regaddr, 0); - regaddr += sizeof (PTRACE_XFER_TYPE); + *(long *) &buf[bytes_transferred] + = ptrace (PTRACE_PEEKUSER, tid, (PTRACE_TYPE_ARG3) regaddr, 0); + regaddr += sizeof (long); if (errno != 0) { char message[128]; @@ -406,7 +394,7 @@ fetch_register (int tid, int regno) /* Now supply the register. Keep in mind that the regcache's idea of the register's size may not be a multiple of sizeof - (PTRACE_XFER_TYPE). */ + (long). */ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_LITTLE) { /* Little-endian values are always found at the left end of the @@ -668,10 +656,10 @@ store_register (int tid, int regno) /* First collect the register. Keep in mind that the regcache's idea of the register's size may not be a multiple of sizeof - (PTRACE_XFER_TYPE). */ + (long). */ memset (buf, 0, sizeof buf); bytes_to_transfer = align_up (register_size (current_gdbarch, regno), - sizeof (PTRACE_XFER_TYPE)); + sizeof (long)); if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE) { /* Little-endian values always sit at the left end of the buffer. */ @@ -685,12 +673,12 @@ store_register (int tid, int regno) regcache_raw_collect (current_regcache, regno, buf + padding); } - for (i = 0; i < bytes_to_transfer; i += sizeof (PTRACE_XFER_TYPE)) + for (i = 0; i < bytes_to_transfer; i += sizeof (long)) { errno = 0; - ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) regaddr, - *(PTRACE_XFER_TYPE *) & buf[i]); - regaddr += sizeof (PTRACE_XFER_TYPE); + ptrace (PTRACE_POKEUSER, tid, (PTRACE_TYPE_ARG3) regaddr, + *(long *) &buf[i]); + regaddr += sizeof (long); if (errno == EIO && regno == tdep->ppc_fpscr_regnum) @@ -901,7 +889,7 @@ ppc_linux_stopped_by_watchpoint (void) (siginfo.si_code & 0xffff) != 0x0004) return 0; - last_stopped_data_address = (CORE_ADDR) siginfo.si_addr; + last_stopped_data_address = (uintptr_t) siginfo.si_addr; return 1; } @@ -926,7 +914,7 @@ supply_gregset (gdb_gregset_t *gregsetp) { /* NOTE: cagney/2003-11-25: This is the word size used by the ptrace interface, and not the wordsize of the program's ABI. */ - int wordsize = sizeof (PTRACE_XFER_TYPE); + int wordsize = sizeof (long); ppc_linux_supply_gregset (current_regcache, -1, gregsetp, sizeof (gdb_gregset_t), wordsize); } @@ -936,7 +924,7 @@ right_fill_reg (int regnum, void *reg) { /* NOTE: cagney/2003-11-25: This is the word size used by the ptrace interface, and not the wordsize of the program's ABI. */ - int wordsize = sizeof (PTRACE_XFER_TYPE); + int wordsize = sizeof (long); /* Right fill the register. */ regcache_raw_collect (current_regcache, regnum, ((bfd_byte *) reg diff --git a/gdb/ppcnbsd-tdep.c b/gdb/ppcnbsd-tdep.c index 9547fcd..57ba742 100644 --- a/gdb/ppcnbsd-tdep.c +++ b/gdb/ppcnbsd-tdep.c @@ -246,8 +246,8 @@ static struct core_fns ppcnbsd_elfcore_fns = static enum return_value_convention ppcnbsd_return_value (struct gdbarch *gdbarch, struct type *valtype, - struct regcache *regcache, void *readbuf, - const void *writebuf) + struct regcache *regcache, gdb_byte *readbuf, + const gdb_byte *writebuf) { if ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT || TYPE_CODE (valtype) == TYPE_CODE_UNION) diff --git a/gdb/remote.c b/gdb/remote.c index 22581a5..c6ed900 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -973,7 +973,7 @@ typedef unsigned char threadref[OPAQUETHREADBYTES]; typedef int gdb_threadref; /* Internal GDB thread reference. */ /* gdb_ext_thread_info is an internal GDB data structure which is - equivalint to the reply of the remote threadinfo packet. */ + equivalent to the reply of the remote threadinfo packet. */ struct gdb_ext_thread_info { @@ -2187,7 +2187,7 @@ remote_detach (char *args, int from_tty) /* Same as remote_detach, but don't send the "D" packet; just disconnect. */ static void -remote_disconnect (char *args, int from_tty) +remote_disconnect (struct target_ops *target, char *args, int from_tty) { if (args) error (_("Argument given to \"detach\" when remotely debugging.")); diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index f932b4c..f22236c 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -59,7 +59,6 @@ #include "frame-unwind.h" #include "frame-base.h" -#include "reggroups.h" #include "rs6000-tdep.h" /* If the kernel has to deliver a signal, it pushes a sigcontext diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c index 4018ad1..b7b372d 100644 --- a/gdb/s390-tdep.c +++ b/gdb/s390-tdep.c @@ -444,19 +444,41 @@ s390_supply_regset (const struct regset *regset, struct regcache *regcache, } } +/* Collect register REGNUM from the register cache REGCACHE and store + it in the buffer specified by REGS and LEN as described by the + general-purpose register set REGSET. If REGNUM is -1, do this for + all registers in REGSET. */ +static void +s390_collect_regset (const struct regset *regset, + const struct regcache *regcache, + int regnum, void *regs, size_t len) +{ + const int *offset = regset->descr; + int i; + + for (i = 0; i < S390_NUM_REGS; i++) + { + if ((regnum == i || regnum == -1) && offset[i] != -1) + regcache_raw_collect (regcache, i, (char *)regs + offset[i]); + } +} + static const struct regset s390_gregset = { s390_regmap_gregset, - s390_supply_regset + s390_supply_regset, + s390_collect_regset }; static const struct regset s390x_gregset = { s390x_regmap_gregset, - s390_supply_regset + s390_supply_regset, + s390_collect_regset }; static const struct regset s390_fpregset = { s390_regmap_fpregset, - s390_supply_regset + s390_supply_regset, + s390_collect_regset }; /* Return the appropriate register set for the core section identified diff --git a/gdb/ser-mingw.c b/gdb/ser-mingw.c index 7a6f232..79e186b 100644 --- a/gdb/ser-mingw.c +++ b/gdb/ser-mingw.c @@ -26,6 +26,7 @@ #include "ser-tcp.h" #include <windows.h> +#include <conio.h> #include <fcntl.h> #include <unistd.h> @@ -350,23 +351,22 @@ struct ser_console_state HANDLE start_select; HANDLE stop_select; + HANDLE exit_select; + HANDLE have_stopped; + + HANDLE thread; }; static DWORD WINAPI console_select_thread (void *arg) { struct serial *scb = arg; - struct ser_console_state *state, state_copy; - int event_index, fd; + struct ser_console_state *state; + int event_index; HANDLE h; - /* Copy useful information out of the control block, to make sure - that we do not race with freeing it. */ - state_copy = *(struct ser_console_state *) scb->state; - state = &state_copy; - fd = scb->fd; - - h = (HANDLE) _get_osfhandle (fd); + state = scb->state; + h = (HANDLE) _get_osfhandle (scb->fd); while (1) { @@ -374,14 +374,15 @@ console_select_thread (void *arg) INPUT_RECORD record; DWORD n_records; + SetEvent (state->have_stopped); + wait_events[0] = state->start_select; - wait_events[1] = state->stop_select; + wait_events[1] = state->exit_select; if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) != WAIT_OBJECT_0) - { - CloseHandle (state->stop_select); - return 0; - } + return 0; + + ResetEvent (state->have_stopped); retry: wait_events[0] = state->stop_select; @@ -391,10 +392,7 @@ console_select_thread (void *arg) if (event_index == WAIT_OBJECT_0 || WaitForSingleObject (state->stop_select, 0) == WAIT_OBJECT_0) - { - CloseHandle (state->stop_select); - return 0; - } + continue; if (event_index != WAIT_OBJECT_0 + 1) { @@ -415,9 +413,30 @@ console_select_thread (void *arg) if (record.EventType == KEY_EVENT && record.Event.KeyEvent.bKeyDown) { - /* This is really a keypress. */ - SetEvent (state->read_event); - continue; + WORD keycode = record.Event.KeyEvent.wVirtualKeyCode; + + /* Ignore events containing only control keys. We must + recognize "enhanced" keys which we are interested in + reading via getch, if they do not map to ASCII. But we + do not want to report input available for e.g. the + control key alone. */ + + if (record.Event.KeyEvent.uChar.AsciiChar != 0 + || keycode == VK_PRIOR + || keycode == VK_NEXT + || keycode == VK_END + || keycode == VK_HOME + || keycode == VK_LEFT + || keycode == VK_UP + || keycode == VK_RIGHT + || keycode == VK_DOWN + || keycode == VK_INSERT + || keycode == VK_DELETE) + { + /* This is really a keypress. */ + SetEvent (state->read_event); + continue; + } } /* Otherwise discard it and wait again. */ @@ -439,31 +458,27 @@ static DWORD WINAPI pipe_select_thread (void *arg) { struct serial *scb = arg; - struct ser_console_state *state, state_copy; - int event_index, fd; + struct ser_console_state *state; + int event_index; HANDLE h; - /* Copy useful information out of the control block, to make sure - that we do not race with freeing it. */ - state_copy = *(struct ser_console_state *) scb->state; - state = &state_copy; - fd = scb->fd; - - h = (HANDLE) _get_osfhandle (fd); + state = scb->state; + h = (HANDLE) _get_osfhandle (scb->fd); while (1) { HANDLE wait_events[2]; DWORD n_avail; + SetEvent (state->have_stopped); + wait_events[0] = state->start_select; - wait_events[1] = state->stop_select; + wait_events[1] = state->exit_select; if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) != WAIT_OBJECT_0) - { - CloseHandle (state->stop_select); - return 0; - } + return 0; + + ResetEvent (state->have_stopped); retry: if (!PeekNamedPipe (h, NULL, 0, NULL, &n_avail, NULL)) @@ -478,13 +493,11 @@ pipe_select_thread (void *arg) continue; } - if (WaitForSingleObject (state->stop_select, 0) == WAIT_OBJECT_0) - { - CloseHandle (state->stop_select); - return 0; - } + /* Delay 10ms before checking again, but allow the stop event + to wake us. */ + if (WaitForSingleObject (state->stop_select, 10) == WAIT_OBJECT_0) + continue; - Sleep (10); goto retry; } } @@ -511,29 +524,62 @@ ser_console_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except) memset (state, 0, sizeof (struct ser_console_state)); scb->state = state; - /* Create auto reset events to wake and terminate the select thread. */ + /* Create auto reset events to wake, stop, and exit the select + thread. */ state->start_select = CreateEvent (0, FALSE, FALSE, 0); state->stop_select = CreateEvent (0, FALSE, FALSE, 0); + state->exit_select = CreateEvent (0, FALSE, FALSE, 0); - /* Create our own events to report read and exceptions separately. - The exception event is currently never used. */ + /* Create a manual reset event to signal whether the thread is + stopped. This must be manual reset, because we may wait on + it multiple times without ever starting the thread. */ + state->have_stopped = CreateEvent (0, TRUE, FALSE, 0); + + /* Create our own events to report read and exceptions separately. */ state->read_event = CreateEvent (0, FALSE, FALSE, 0); state->except_event = CreateEvent (0, FALSE, FALSE, 0); - /* And finally start the select thread. */ if (is_tty) - CreateThread (NULL, 0, console_select_thread, scb, 0, &threadId); + state->thread = CreateThread (NULL, 0, console_select_thread, scb, 0, + &threadId); else - CreateThread (NULL, 0, pipe_select_thread, scb, 0, &threadId); + state->thread = CreateThread (NULL, 0, pipe_select_thread, scb, 0, + &threadId); } + *read = state->read_event; + *except = state->except_event; + + /* Start from a blank state. */ ResetEvent (state->read_event); ResetEvent (state->except_event); + ResetEvent (state->stop_select); + + /* First check for a key already in the buffer. If there is one, + we don't need a thread. This also catches the second key of + multi-character returns from getch, for instance for arrow + keys. The second half is in a C library internal buffer, + and PeekConsoleInput will not find it. */ + if (_kbhit ()) + { + SetEvent (state->read_event); + return; + } + /* Otherwise, start the select thread. */ SetEvent (state->start_select); +} - *read = state->read_event; - *except = state->except_event; +static void +ser_console_done_wait_handle (struct serial *scb) +{ + struct ser_console_state *state = scb->state; + + if (state == NULL) + return; + + SetEvent (state->stop_select); + WaitForSingleObject (state->have_stopped, INFINITE); } static void @@ -543,7 +589,14 @@ ser_console_close (struct serial *scb) if (scb->state) { - SetEvent (state->stop_select); + SetEvent (state->exit_select); + + WaitForSingleObject (state->thread, INFINITE); + + CloseHandle (state->start_select); + CloseHandle (state->stop_select); + CloseHandle (state->exit_select); + CloseHandle (state->have_stopped); CloseHandle (state->read_event); CloseHandle (state->except_event); @@ -571,6 +624,217 @@ ser_console_get_tty_state (struct serial *scb) return NULL; } +struct pipe_state +{ + /* Since we use the pipe_select_thread for our select emulation, + we need to place the state structure it requires at the front + of our state. */ + struct ser_console_state wait; + + /* The pex obj for our (one-stage) pipeline. */ + struct pex_obj *pex; + + /* Streams for the pipeline's input and output. */ + FILE *input, *output; +}; + +static struct pipe_state * +make_pipe_state (void) +{ + struct pipe_state *ps = XMALLOC (struct pipe_state); + + memset (ps, 0, sizeof (*ps)); + ps->wait.read_event = INVALID_HANDLE_VALUE; + ps->wait.except_event = INVALID_HANDLE_VALUE; + ps->wait.start_select = INVALID_HANDLE_VALUE; + ps->wait.stop_select = INVALID_HANDLE_VALUE; + + return ps; +} + +static void +free_pipe_state (struct pipe_state *ps) +{ + int saved_errno = errno; + + if (ps->wait.read_event != INVALID_HANDLE_VALUE) + CloseHandle (ps->wait.read_event); + if (ps->wait.except_event != INVALID_HANDLE_VALUE) + CloseHandle (ps->wait.except_event); + if (ps->wait.start_select != INVALID_HANDLE_VALUE) + CloseHandle (ps->wait.start_select); + + /* If we have a select thread running, let the select thread free + the stop event. */ + if (ps->wait.stop_select != INVALID_HANDLE_VALUE) + SetEvent (ps->wait.stop_select); + + /* Close the pipe to the child. We must close the pipe before + calling pex_free because pex_free will wait for the child to exit + and the child will not exit until the pipe is closed. */ + if (ps->input) + fclose (ps->input); + if (ps->pex) + pex_free (ps->pex); + /* pex_free closes ps->output. */ + + xfree (ps); + + errno = saved_errno; +} + +static void +cleanup_pipe_state (void *untyped) +{ + struct pipe_state *ps = untyped; + + free_pipe_state (ps); +} + +static int +pipe_windows_open (struct serial *scb, const char *name) +{ + char **argv = buildargv (name); + struct cleanup *back_to = make_cleanup_freeargv (argv); + if (! argv[0] || argv[0][0] == '\0') + error ("missing child command"); + + struct pipe_state *ps = make_pipe_state (); + make_cleanup (cleanup_pipe_state, ps); + + ps->pex = pex_init (PEX_USE_PIPES, "target remote pipe", NULL); + if (! ps->pex) + goto fail; + ps->input = pex_input_pipe (ps->pex, 1); + if (! ps->input) + goto fail; + + { + int err; + const char *err_msg + = pex_run (ps->pex, PEX_SEARCH | PEX_BINARY_INPUT | PEX_BINARY_OUTPUT, + argv[0], argv, NULL, NULL, + &err); + + if (err_msg) + { + /* Our caller expects us to return -1, but all they'll do with + it generally is print the message based on errno. We have + all the same information here, plus err_msg provided by + pex_run, so we just raise the error here. */ + if (err) + error ("error starting child process '%s': %s: %s", + name, err_msg, safe_strerror (err)); + else + error ("error starting child process '%s': %s", + name, err_msg); + } + } + + ps->output = pex_read_output (ps->pex, 1); + if (! ps->output) + goto fail; + + scb->fd = fileno (ps->output); + scb->state = (void *) ps; + + discard_cleanups (back_to); + return 0; + + fail: + do_cleanups (back_to); + return -1; +} + + +static void +pipe_windows_close (struct serial *scb) +{ + struct pipe_state *ps = scb->state; + + /* In theory, we should try to kill the subprocess here, but the pex + interface doesn't give us enough information to do that. Usually + closing the input pipe will get the message across. */ + + free_pipe_state (ps); +} + + +static int +pipe_windows_read (struct serial *scb, size_t count) +{ + HANDLE pipeline_out = (HANDLE) _get_osfhandle (scb->fd); + if (pipeline_out == INVALID_HANDLE_VALUE) + return -1; + + DWORD available; + if (! PeekNamedPipe (pipeline_out, NULL, 0, NULL, &available, NULL)) + return -1; + + if (count > available) + count = available; + + DWORD bytes_read; + if (! ReadFile (pipeline_out, scb->buf, count, &bytes_read, NULL)) + return -1; + + return bytes_read; +} + + +static int +pipe_windows_write (struct serial *scb, const void *buf, size_t count) +{ + struct pipe_state *ps = scb->state; + int pipeline_in_fd = fileno (ps->input); + if (pipeline_in_fd < 0) + return -1; + + HANDLE pipeline_in = (HANDLE) _get_osfhandle (pipeline_in_fd); + if (pipeline_in == INVALID_HANDLE_VALUE) + return -1; + + DWORD written; + if (! WriteFile (pipeline_in, buf, count, &written, NULL)) + return -1; + + return written; +} + + +static void +pipe_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except) +{ + struct pipe_state *ps = scb->state; + + /* Have we allocated our events yet? */ + if (ps->wait.read_event == INVALID_HANDLE_VALUE) + { + DWORD threadId; + + /* Create auto reset events to wake and terminate the select thread. */ + ps->wait.start_select = CreateEvent (0, FALSE, FALSE, 0); + ps->wait.stop_select = CreateEvent (0, FALSE, FALSE, 0); + + /* Create our own events to report read and exceptions separately. + The exception event is currently never used. */ + ps->wait.read_event = CreateEvent (0, FALSE, FALSE, 0); + ps->wait.except_event = CreateEvent (0, FALSE, FALSE, 0); + + /* Start the select thread. */ + CreateThread (NULL, 0, pipe_select_thread, scb, 0, &threadId); + } + + ResetEvent (ps->wait.read_event); + ResetEvent (ps->wait.except_event); + + SetEvent (ps->wait.start_select); + + *read = ps->wait.read_event; + *except = ps->wait.except_event; +} + + struct net_windows_state { HANDLE read_event; @@ -578,7 +842,12 @@ struct net_windows_state HANDLE start_select; HANDLE stop_select; + HANDLE exit_select; + HANDLE have_stopped; + HANDLE sock_event; + + HANDLE thread; }; static DWORD WINAPI @@ -586,27 +855,24 @@ net_windows_select_thread (void *arg) { struct serial *scb = arg; struct net_windows_state *state, state_copy; - int event_index, fd; + int event_index; - /* Copy useful information out of the control block, to make sure - that we do not race with freeing it. */ - state_copy = *(struct net_windows_state *) scb->state; - state = &state_copy; - fd = scb->fd; + state = scb->state; while (1) { HANDLE wait_events[2]; WSANETWORKEVENTS events; + SetEvent (state->have_stopped); + wait_events[0] = state->start_select; - wait_events[1] = state->stop_select; + wait_events[1] = state->exit_select; if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) != WAIT_OBJECT_0) - { - CloseHandle (state->stop_select); - return 0; - } + return 0; + + ResetEvent (state->have_stopped); wait_events[0] = state->stop_select; wait_events[1] = state->sock_event; @@ -615,10 +881,7 @@ net_windows_select_thread (void *arg) if (event_index == WAIT_OBJECT_0 || WaitForSingleObject (state->stop_select, 0) == WAIT_OBJECT_0) - { - CloseHandle (state->stop_select); - return 0; - } + continue; if (event_index != WAIT_OBJECT_0 + 1) { @@ -630,7 +893,9 @@ net_windows_select_thread (void *arg) /* Enumerate the internal network events, and reset the object that signalled us to catch the next event. */ - WSAEnumNetworkEvents (fd, state->sock_event, &events); + WSAEnumNetworkEvents (scb->fd, state->sock_event, &events); + + gdb_assert (events.lNetworkEvents & (FD_READ | FD_CLOSE)); if (events.lNetworkEvents & FD_READ) SetEvent (state->read_event); @@ -645,13 +910,78 @@ net_windows_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except) { struct net_windows_state *state = scb->state; + /* Start from a clean slate. */ ResetEvent (state->read_event); ResetEvent (state->except_event); - - SetEvent (state->start_select); + ResetEvent (state->stop_select); *read = state->read_event; *except = state->except_event; + + /* Check any pending events. This both avoids starting the thread + unnecessarily, and handles stray FD_READ events (see below). */ + if (WaitForSingleObject (state->sock_event, 0) == WAIT_OBJECT_0) + { + WSANETWORKEVENTS events; + int any = 0; + + /* Enumerate the internal network events, and reset the object that + signalled us to catch the next event. */ + WSAEnumNetworkEvents (scb->fd, state->sock_event, &events); + + /* You'd think that FD_READ or FD_CLOSE would be set here. But, + sometimes, neither is. I suspect that the FD_READ is set and + the corresponding event signalled while recv is running, and + the FD_READ is then lowered when recv consumes all the data, + but there's no way to un-signal the event. This isn't a + problem for the call in net_select_thread, since any new + events after this point will not have been drained by recv. + It just means that we can't have the obvious assert here. */ + + /* If there is a read event, it might be still valid, or it might + not be - it may have been signalled before we last called + recv. Double-check that there is data. */ + if (events.lNetworkEvents & FD_READ) + { + unsigned long available; + + if (ioctlsocket (scb->fd, FIONREAD, &available) == 0 + && available > 0) + { + SetEvent (state->read_event); + any = 1; + } + else + /* Oops, no data. This call to recv will cause future + data to retrigger the event, e.g. while we are + in net_select_thread. */ + recv (scb->fd, NULL, 0, 0); + } + + /* If there's a close event, then record it - it is obviously + still valid, and it will not be resignalled. */ + if (events.lNetworkEvents & FD_CLOSE) + { + SetEvent (state->except_event); + any = 1; + } + + /* If we set either handle, there's no need to wake the thread. */ + if (any) + return; + } + + /* Start the select thread. */ + SetEvent (state->start_select); +} + +static void +net_windows_done_wait_handle (struct serial *scb) +{ + struct net_windows_state *state = scb->state; + + SetEvent (state->stop_select); + WaitForSingleObject (state->have_stopped, INFINITE); } static int @@ -669,9 +999,16 @@ net_windows_open (struct serial *scb, const char *name) memset (state, 0, sizeof (struct net_windows_state)); scb->state = state; - /* Create auto reset events to wake and terminate the select thread. */ + /* Create auto reset events to wake, stop, and exit the select + thread. */ state->start_select = CreateEvent (0, FALSE, FALSE, 0); state->stop_select = CreateEvent (0, FALSE, FALSE, 0); + state->exit_select = CreateEvent (0, FALSE, FALSE, 0); + + /* Create a manual reset event to signal whether the thread is + stopped. This must be manual reset, because we may wait on + it multiple times without ever starting the thread. */ + state->have_stopped = CreateEvent (0, TRUE, FALSE, 0); /* Associate an event with the socket. */ state->sock_event = CreateEvent (0, TRUE, FALSE, 0); @@ -682,7 +1019,8 @@ net_windows_open (struct serial *scb, const char *name) state->except_event = CreateEvent (0, FALSE, FALSE, 0); /* And finally start the select thread. */ - CreateThread (NULL, 0, net_windows_select_thread, scb, 0, &threadId); + state->thread = CreateThread (NULL, 0, net_windows_select_thread, scb, 0, + &threadId); return 0; } @@ -693,11 +1031,17 @@ net_windows_close (struct serial *scb) { struct net_windows_state *state = scb->state; - SetEvent (state->stop_select); + SetEvent (state->exit_select); + WaitForSingleObject (state->thread, INFINITE); CloseHandle (state->read_event); CloseHandle (state->except_event); + CloseHandle (state->start_select); + CloseHandle (state->stop_select); + CloseHandle (state->exit_select); + CloseHandle (state->have_stopped); + CloseHandle (state->sock_event); xfree (scb->state); @@ -760,6 +1104,35 @@ _initialize_ser_windows (void) ops->noflush_set_tty_state = ser_base_noflush_set_tty_state; ops->drain_output = ser_base_drain_output; ops->wait_handle = ser_console_wait_handle; + ops->done_wait_handle = ser_console_done_wait_handle; + + serial_add_interface (ops); + + /* The pipe interface. */ + + ops = XMALLOC (struct serial_ops); + memset (ops, 0, sizeof (struct serial_ops)); + ops->name = "pipe"; + ops->next = 0; + ops->open = pipe_windows_open; + ops->close = pipe_windows_close; + ops->readchar = ser_base_readchar; + ops->write = ser_base_write; + ops->flush_output = ser_base_flush_output; + ops->flush_input = ser_base_flush_input; + ops->send_break = ser_base_send_break; + ops->go_raw = ser_base_raw; + ops->get_tty_state = ser_base_get_tty_state; + ops->set_tty_state = ser_base_set_tty_state; + ops->print_tty_state = ser_base_print_tty_state; + ops->noflush_set_tty_state = ser_base_noflush_set_tty_state; + ops->setbaudrate = ser_base_setbaudrate; + ops->setstopbits = ser_base_setstopbits; + ops->drain_output = ser_base_drain_output; + ops->async = ser_base_async; + ops->read_prim = pipe_windows_read; + ops->write_prim = pipe_windows_write; + ops->wait_handle = pipe_wait_handle; serial_add_interface (ops); @@ -792,5 +1165,6 @@ _initialize_ser_windows (void) ops->read_prim = net_read_prim; ops->write_prim = net_write_prim; ops->wait_handle = net_windows_wait_handle; + ops->done_wait_handle = net_windows_done_wait_handle; serial_add_interface (ops); } diff --git a/gdb/serial.c b/gdb/serial.c index fb74e1c..6a2c634 100644 --- a/gdb/serial.c +++ b/gdb/serial.c @@ -557,6 +557,13 @@ serial_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except) *except = NULL; } } + +void +serial_done_wait_handle (struct serial *scb) +{ + if (scb->ops->done_wait_handle) + scb->ops->done_wait_handle (scb); +} #endif #if 0 diff --git a/gdb/serial.h b/gdb/serial.h index d9a395b..8d7ae65 100644 --- a/gdb/serial.h +++ b/gdb/serial.h @@ -253,6 +253,7 @@ struct serial_ops when signaled, in *READ. Return a handle indicating errors in *EXCEPT. */ void (*wait_handle) (struct serial *scb, HANDLE *read, HANDLE *except); + void (*done_wait_handle) (struct serial *scb); #endif /* USE_WIN32API */ }; @@ -270,6 +271,9 @@ extern void serial_log_command (const char *); serial device. */ extern void serial_wait_handle (struct serial *, HANDLE *, HANDLE *); +/* Windows-only: signal that we are done with the wait handles. */ +extern void serial_done_wait_handle (struct serial *); + #endif /* USE_WIN32API */ #endif /* SERIAL_H */ diff --git a/gdb/symtab.c b/gdb/symtab.c index ad4ed03..2832dd1 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -4030,6 +4030,11 @@ skip_prologue_using_sal (CORE_ADDR func_addr) prologue_sal = find_pc_line (start_pc, 0); if (prologue_sal.line != 0) { + /* If there is only one sal that covers the entire function, + then it is probably a single line function, like + "foo(){}". */ + if (prologue_sal.end == end_pc) + return start_pc; while (prologue_sal.end < end_pc) { struct symtab_and_line sal; diff --git a/gdb/target.c b/gdb/target.c index 52e4527..bcb47de 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -97,8 +97,6 @@ static void debug_to_attach (char *, int); static void debug_to_detach (char *, int); -static void debug_to_disconnect (char *, int); - static void debug_to_resume (ptid_t, int, enum target_signal); static ptid_t debug_to_wait (ptid_t, struct target_waitstatus *); @@ -388,7 +386,7 @@ update_current_target (void) INHERIT (to_attach, t); INHERIT (to_post_attach, t); INHERIT (to_detach, t); - INHERIT (to_disconnect, t); + /* Do not inherit to_disconnect. */ INHERIT (to_resume, t); INHERIT (to_wait, t); INHERIT (to_fetch_registers, t); @@ -483,9 +481,6 @@ update_current_target (void) de_fault (to_detach, (void (*) (char *, int)) target_ignore); - de_fault (to_disconnect, - (void (*) (char *, int)) - tcomplain); de_fault (to_resume, (void (*) (ptid_t, int, enum target_signal)) noprocess); @@ -1490,7 +1485,19 @@ target_detach (char *args, int from_tty) void target_disconnect (char *args, int from_tty) { - (current_target.to_disconnect) (args, from_tty); + struct target_ops *t; + + for (t = current_target.beneath; t != NULL; t = t->beneath) + if (t->to_disconnect != NULL) + { + if (targetdebug) + fprintf_unfiltered (gdb_stdlog, "target_disconnect (%s, %d)\n", + args, from_tty); + t->to_disconnect (t, args, from_tty); + return; + } + + tcomplain (); } int @@ -1907,15 +1914,6 @@ debug_to_detach (char *args, int from_tty) } static void -debug_to_disconnect (char *args, int from_tty) -{ - debug_target.to_disconnect (args, from_tty); - - fprintf_unfiltered (gdb_stdlog, "target_disconnect (%s, %d)\n", - args, from_tty); -} - -static void debug_to_resume (ptid_t ptid, int step, enum target_signal siggnal) { debug_target.to_resume (ptid, step, siggnal); @@ -2521,7 +2519,6 @@ setup_target_debug (void) current_target.to_attach = debug_to_attach; current_target.to_post_attach = debug_to_post_attach; current_target.to_detach = debug_to_detach; - current_target.to_disconnect = debug_to_disconnect; current_target.to_resume = debug_to_resume; current_target.to_wait = debug_to_wait; current_target.to_fetch_registers = debug_to_fetch_registers; @@ -2569,7 +2566,6 @@ setup_target_debug (void) current_target.to_enable_exception_callback = debug_to_enable_exception_callback; current_target.to_get_current_exception_event = debug_to_get_current_exception_event; current_target.to_pid_to_exec_file = debug_to_pid_to_exec_file; - } diff --git a/gdb/target.h b/gdb/target.h index 7decfd7..bf4917f 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -303,7 +303,7 @@ struct target_ops void (*to_attach) (char *, int); void (*to_post_attach) (int); void (*to_detach) (char *, int); - void (*to_disconnect) (char *, int); + void (*to_disconnect) (struct target_ops *, char *, int); void (*to_resume) (ptid_t, int, enum target_signal); ptid_t (*to_wait) (ptid_t, struct target_waitstatus *); void (*to_fetch_registers) (int); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 738ee69..6b74c4d 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,77 @@ +2006-05-11 Fred Fish <fnf@specifix.com> + + * gdb.base/bang.exp: Ignore unexpected output between the + "program exited normally" and the gdb prompt, as many other + tests do. + +2006-05-07 Mark Kettenis <kettenis@gnu.org> + + * gdb.base/help.exp: Make "delete checkpoint" part option for + "help d" and "help delete" tests. + +2006-05-06 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + + * gdb.mi/mi-basics.exp: Add missing serial number to + expected output in some mi_gdb_test statements. + * gdb.mi/mi2-basics.exp: Likewise. + +2006-05-05 Joel Brobecker <brobecker@adacore.com> + + * gdb.base/del.c: New file. + * gdb.base/del.exp: New testcase. + +2006-05-05 David S. Miller <davem@sunset.davemloft.net> + + * gdb.base/break.exp: Do not assume a breakpoint on + main will actually be in $srcfile when optimizing. + * gdb.base/savedregs.exp: Do not require that the dummy + frame location match up to a symbol and source file location. + * gdb.mi/mi-regs.exp (111-data-list-register-values x): "No registers" + will get printed without a mi_cmd_data_list_register_values prefix. + (*-data-list-register-*): Correct regular expressions to expect the new + pseudo d? floating point registers. + * gdb.mi/mi2-regs.exp: Likewise. + +2006-05-05 Christophe Lyon <christophe.lyon@st.com> + + * gdb.cp/m-static.h (class gnu_obj_4): Add dummy member. + * gdb.cp/m-static.cc (main): Write to test4.dummy, so that test4 + is allocated by the compiler. + * gdb.mi/var-cmd.c: (do_special_tests): Write to u, anonu, s, + anons, e, anone to force their allocation by the compiler. + +2006-05-05 Daniel Jacobowitz <dan@codesourcery.com> + + * gdb.base/help.exp: Update expected text for help d and + help delete. + +2006-05-02 Mark Kettenis <kettenis@gnu.org> + + * gdb.asm/asm-source.exp: Add powerpc-*-netbsd* to the list of + NetBSD/ELF targets. + +2006-04-30 Mark Kettenis <kettenis@gnu.org> + + * gdb.base/sigbpt.exp (stepi_out): FAIL when inserting a + single-step breakpoint fails; make this a KFAIL on + sparc*-*-openbsd*. + * gdb.base/siginfo.exp: Likewise. + * gdb.base/sigstep.exp (advance, advancei): Likewise. + +2006-04-26 Michael Snyder <msnyder@redhat.com> + + * gdb.base/multi-forks.exp: Modify patterns for "run to exit", + which may have to consume output from other forks. + Add tests to make sure that "delete fork" succeeded. + +2006-04-20 Michael Snyder <msnyder@redhat.com> + + * 2006-03-22 Jim Blandy <jimb@redhat.com> + Add support for the Renesas M32C and M16C. + + * gdb.asm/asm-source.exp: Add m32c target. + * gdb.asm/m32c.inc: Support for m32c target. + 2006-04-07 Andrew Stubbs <andrew.stubbs@st.com> * gdb.base/commands.exp (recursive_source_test): New test. diff --git a/gdb/testsuite/gdb.asm/asm-source.exp b/gdb/testsuite/gdb.asm/asm-source.exp index cbd38a4..41c2d72 100644 --- a/gdb/testsuite/gdb.asm/asm-source.exp +++ b/gdb/testsuite/gdb.asm/asm-source.exp @@ -73,6 +73,9 @@ switch -glob -- [istarget] { "m32r*-linux*" { set asm-arch m32r-linux } + "m32c-*-*" { + set asm-arch m32c + } "m32r*-*" { set asm-arch m32r append link-flags "--whole-archive -lgloss --no-whole-archive" @@ -160,6 +163,7 @@ if { "${asm-arch}" == "" } { # On NetBSD/ELF we need a special NetBSD-identifying note section. if { [istarget "*-*-netbsdelf*"] || [istarget "mips*-*-netbsd*"] + || [istarget "powerpc-*-netbsd*"] || [istarget "x86_64-*-netbsd*"] } then { set asm-note "netbsd" } diff --git a/gdb/testsuite/gdb.asm/m32c.inc b/gdb/testsuite/gdb.asm/m32c.inc new file mode 100644 index 0000000..7925e77 --- /dev/null +++ b/gdb/testsuite/gdb.asm/m32c.inc @@ -0,0 +1,33 @@ + comment "subroutine prologue" + .macro gdbasm_enter + enter #0 + .endm + + comment "subroutine epilogue" + .macro gdbasm_leave + exitd + .endm + + .macro gdbasm_call subr + jsr.a \subr + .endm + + .macro gdbasm_several_nops + nop + nop + nop + nop + .endm + + comment "exit (0)" + .macro gdbasm_exit0 + mov.w #0, r1 + mov.b #1, r0l + ste.b r0l,0xe0000 + .endm + + comment "crt0 startup" + .macro gdbasm_startup + ldc #0xfc00, sp + .endm + diff --git a/gdb/testsuite/gdb.base/bang.exp b/gdb/testsuite/gdb.base/bang.exp index d0cb7b5..c967275 100644 --- a/gdb/testsuite/gdb.base/bang.exp +++ b/gdb/testsuite/gdb.base/bang.exp @@ -38,7 +38,7 @@ gdb_load ${binfile} gdb_run_cmd gdb_expect { - -re ".*Program exited normally\.\r\n$gdb_prompt $" { + -re ".*Program exited normally.*$gdb_prompt $" { pass "run program" } timeout { diff --git a/gdb/testsuite/gdb.base/break.exp b/gdb/testsuite/gdb.base/break.exp index 4a704fb..13458a9 100644 --- a/gdb/testsuite/gdb.base/break.exp +++ b/gdb/testsuite/gdb.base/break.exp @@ -887,7 +887,7 @@ if [target_info exists gdb_stub] { # test break at function # gdb_test "break main" \ - "Breakpoint.*at.* file .*$srcfile, line.*" \ + "Breakpoint.*at.* file .*, line.*" \ "breakpoint function, optimized file" # diff --git a/gdb/testsuite/gdb.base/del.c b/gdb/testsuite/gdb.base/del.c new file mode 100644 index 0000000..f17c29d --- /dev/null +++ b/gdb/testsuite/gdb.base/del.c @@ -0,0 +1,26 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2006 Free Software Foundation, Inc. + + 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. + + Please email any bugs, comments, and/or additions to this file to: + bug-gdb@prep.ai.mit.edu */ + +int +main(void) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.base/del.exp b/gdb/testsuite/gdb.base/del.exp new file mode 100644 index 0000000..4d5bf47 --- /dev/null +++ b/gdb/testsuite/gdb.base/del.exp @@ -0,0 +1,57 @@ +# Copyright 2006 Free Software Foundation, Inc. + +# 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. + +# The intent of this testcase it to verify that various aliases and +# shortcuts of the "delete" command never stop working. + +if $tracelevel then { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +set testfile del +set srcfile ${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + untested "Couldn't compile test program" + return -1 +} + +# Get things started. + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +# Test whether the "del" command works as an alias of "delete". +# For that, insert a breakpoint at an easy location, remove it, +# and then check in the output of "info break" that this breakpoint +# no longer exists. + +gdb_test "break main" \ + "Breakpoint.*at.* file .*$srcfile, line.*" \ + "breakpoint function" + +gdb_test "del \$bpnum" \ + "" \ + "Remove last breakpoint" + +gdb_test "info break" \ + "No breakpoints or watchpoints." \ + "info break after removing break on main" diff --git a/gdb/testsuite/gdb.base/help.exp b/gdb/testsuite/gdb.base/help.exp index 437c39e..8312458 100644 --- a/gdb/testsuite/gdb.base/help.exp +++ b/gdb/testsuite/gdb.base/help.exp @@ -1,5 +1,5 @@ # Copyright 1988, 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2002 +# 2000, 2002, 2003, 2005, 2006 # Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify @@ -84,9 +84,9 @@ gdb_test "help condition" "Specify breakpoint number N to break only if COND is # test help core-file gdb_test "help core-file" "Use FILE as core dump for examining memory and registers\.\[\r\n\]+No arg means have no core file\. This command has been superseded by the\[\r\n\]+`target core' and `detach' commands\." "help core-file" # test help delete "d" abbreviation -gdb_test "help d" "Delete some breakpoints or auto-display expressions\.\[\r\n\]+Arguments are breakpoint numbers with spaces in between\.\[\r\n\]+To delete all breakpoints, give no argument\.\[\r\n\]+Also a prefix command for deletion of other GDB objects\.\[\r\n\]+The \"unset\" command is also an alias for \"delete\"\.\[\r\n\]+List of delete subcommands:\[\r\n\]+delete breakpoints -- Delete some breakpoints or auto-display expressions\[\r\n\]+delete display -- Cancel some expressions to be displayed when program stops\[\r\n\]+delete mem -- Delete memory region\[\r\n\]+delete tracepoints -- Delete specified tracepoints\[\r\n\]+Type \"help delete\" followed by delete subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help delete \"d\" abbreviation" +gdb_test "help d" "Delete some breakpoints or auto-display expressions\.\[\r\n\]+Arguments are breakpoint numbers with spaces in between\.\[\r\n\]+To delete all breakpoints, give no argument\.\[\r\n\]+Also a prefix command for deletion of other GDB objects\.\[\r\n\]+The \"unset\" command is also an alias for \"delete\"\.\[\r\n\]+List of delete subcommands:\[\r\n\]+delete breakpoints -- Delete some breakpoints or auto-display expressions\[\r\n\]+(delete checkpoint -- Delete a fork/checkpoint \\(experimental\\)\[\r\n\]+)?delete display -- Cancel some expressions to be displayed when program stops\[\r\n\]+delete mem -- Delete memory region\[\r\n\]+delete tracepoints -- Delete specified tracepoints\[\r\n\]+Type \"help delete\" followed by delete subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help delete \"d\" abbreviation" # test help delete -gdb_test "help delete" "Delete some breakpoints or auto-display expressions\.\[\r\n\]+Arguments are breakpoint numbers with spaces in between\.\[\r\n\]+To delete all breakpoints, give no argument\.\[\r\n\]+Also a prefix command for deletion of other GDB objects\.\[\r\n\]+The \"unset\" command is also an alias for \"delete\"\.\[\r\n\]+List of delete subcommands:\[\r\n\]+delete breakpoints -- Delete some breakpoints or auto-display expressions\[\r\n\]+delete display -- Cancel some expressions to be displayed when program stops\[\r\n\]+delete mem -- Delete memory region\[\r\n\]+delete tracepoints -- Delete specified tracepoints\[\r\n\]+Type \"help delete\" followed by delete subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help delete" +gdb_test "help delete" "Delete some breakpoints or auto-display expressions\.\[\r\n\]+Arguments are breakpoint numbers with spaces in between\.\[\r\n\]+To delete all breakpoints, give no argument\.\[\r\n\]+Also a prefix command for deletion of other GDB objects\.\[\r\n\]+The \"unset\" command is also an alias for \"delete\"\.\[\r\n\]+List of delete subcommands:\[\r\n\]+delete breakpoints -- Delete some breakpoints or auto-display expressions\[\r\n\]+(delete checkpoint -- Delete a fork/checkpoint \\(experimental\\)\[\r\n\]+)?delete display -- Cancel some expressions to be displayed when program stops\[\r\n\]+delete mem -- Delete memory region\[\r\n\]+delete tracepoints -- Delete specified tracepoints\[\r\n\]+Type \"help delete\" followed by delete subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help delete" # test help data gdb_test "help data" "Examining data\.\[\r\n\]+List of commands:.*\[\r\n\]+Type \"help\" followed by command name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help data" # test help define diff --git a/gdb/testsuite/gdb.base/multi-forks.exp b/gdb/testsuite/gdb.base/multi-forks.exp index 82fdc50..5a706d7 100644 --- a/gdb/testsuite/gdb.base/multi-forks.exp +++ b/gdb/testsuite/gdb.base/multi-forks.exp @@ -67,7 +67,7 @@ gdb_test "set follow child" "" "" send_gdb "continue\n" gdb_expect { - -re ".*Break.* main .*$gdb_prompt $" {} + -re ".*Break.* main .*$gdb_prompt.*$" {} -re ".*$gdb_prompt $" {fail "run to exit 1"} default {fail "run to exit 1 (timeout)"} } @@ -84,7 +84,7 @@ gdb_test "set follow parent" "" "" send_gdb "continue\n" gdb_expect { - -re ".*Break.* main .*$gdb_prompt $" {} + -re ".*Break.* main .*$gdb_prompt.*$" {} -re ".*$gdb_prompt $" {fail "run to exit 2"} default {fail "run to exit 2 (timeout)"} } @@ -136,22 +136,31 @@ gdb_test "detach-fork 3" "Detached .*" "Detach 3" gdb_test "detach-fork 4" "Detached .*" "Detach 4" # -# Test delete-fork +# Test delete fork # -gdb_test "delete-fork 5" "" "Delete 5" -gdb_test "delete-fork 6" "" "Delete 6" -gdb_test "delete-fork 7" "" "Delete 7" -gdb_test "delete-fork 8" "" "Delete 8" -gdb_test "delete-fork 9" "" "Delete 9" -gdb_test "delete-fork 10" "" "Delete 10" -gdb_test "delete-fork 11" "" "Delete 11" -gdb_test "delete-fork 12" "" "Delete 12" -gdb_test "delete-fork 13" "" "Delete 13" -gdb_test "delete-fork 14" "" "Delete 14" -gdb_test "delete-fork 15" "" "Delete 15" - - +gdb_test "delete fork 5" "" "Delete 5" +gdb_test "info fork 5" "No fork number 5." "Did delete 5" +gdb_test "delete fork 6" "" "Delete 6" +gdb_test "info fork 6" "No fork number 6." "Did delete 6" +gdb_test "delete fork 7" "" "Delete 7" +gdb_test "info fork 7" "No fork number 7." "Did delete 7" +gdb_test "delete fork 8" "" "Delete 8" +gdb_test "info fork 8" "No fork number 8." "Did delete 8" +gdb_test "delete fork 9" "" "Delete 9" +gdb_test "info fork 9" "No fork number 9." "Did delete 9" +gdb_test "delete fork 10" "" "Delete 10" +gdb_test "info fork 10" "No fork number 10." "Did delete 10" +gdb_test "delete fork 11" "" "Delete 11" +gdb_test "info fork 11" "No fork number 11." "Did delete 11" +gdb_test "delete fork 12" "" "Delete 12" +gdb_test "info fork 12" "No fork number 12." "Did delete 12" +gdb_test "delete fork 13" "" "Delete 13" +gdb_test "info fork 13" "No fork number 13." "Did delete 13" +gdb_test "delete fork 14" "" "Delete 14" +gdb_test "info fork 14" "No fork number 14." "Did delete 14" +gdb_test "delete fork 15" "" "Delete 15" +gdb_test "info fork 15" "No fork number 15." "Did delete 15" return 0 diff --git a/gdb/testsuite/gdb.base/savedregs.exp b/gdb/testsuite/gdb.base/savedregs.exp index 319d281..bdf6c33 100644 --- a/gdb/testsuite/gdb.base/savedregs.exp +++ b/gdb/testsuite/gdb.base/savedregs.exp @@ -81,7 +81,7 @@ proc process_saved_regs { current inner outer } { dummy { # Dummy frame's do not have saved registers, and do # not print <dummy>. - set pat "Stack frame at .* in .*" + set pat "Stack frame at .*" } sigtramp { # Sigtramp frames don't yet print <signal trampoline>. diff --git a/gdb/testsuite/gdb.base/sigbpt.exp b/gdb/testsuite/gdb.base/sigbpt.exp index 9e010e2..0e69e39 100644 --- a/gdb/testsuite/gdb.base/sigbpt.exp +++ b/gdb/testsuite/gdb.base/sigbpt.exp @@ -166,6 +166,10 @@ proc stepi_out { name args } { # trampoline, and back to the instruction that faulted. set test "${name}; stepi out of handler" gdb_test_multiple "stepi" "$test" { + -re "Could not insert single-step breakpoint.*$gdb_prompt $" { + setup_kfail "sparc*-*-openbsd*" gdb/1736 + fail "$test (could not insert single-step breakpoint)" + } -re "keeper.*$gdb_prompt $" { send_gdb "stepi\n" exp_continue diff --git a/gdb/testsuite/gdb.base/siginfo.exp b/gdb/testsuite/gdb.base/siginfo.exp index a081ab8..d600801 100644 --- a/gdb/testsuite/gdb.base/siginfo.exp +++ b/gdb/testsuite/gdb.base/siginfo.exp @@ -75,6 +75,10 @@ gdb_expect_list "backtrace for nexti" ".*$gdb_prompt $" { # Check that GDB can step the inferior back to main set test "step out of handler" gdb_test_multiple "step" "${test}" { + -re "Could not insert single-step breakpoint.*$gdb_prompt $" { + setup_kfail sparc*-*-openbsd* gdb/1736 + fail "$test (could not insert single-step breakpoint)" + } -re "done = 1;.*${gdb_prompt} $" { send_gdb "$i\n" exp_continue diff --git a/gdb/testsuite/gdb.base/sigstep.exp b/gdb/testsuite/gdb.base/sigstep.exp index 6addca7..9069885 100644 --- a/gdb/testsuite/gdb.base/sigstep.exp +++ b/gdb/testsuite/gdb.base/sigstep.exp @@ -79,6 +79,10 @@ proc advance { i } { set test "$prefix; leave handler" gdb_test_multiple "$i" "${test}" { + -re "Could not insert single-step breakpoint.*$gdb_prompt $" { + setup_kfail "sparc*-*-openbsd*" gdb/1736 + fail "$test (could not insert single-step breakpoint)" + } -re "done = 1;.*${gdb_prompt} $" { send_gdb "$i\n" exp_continue -continue_timer @@ -122,6 +126,10 @@ proc advancei { i } { fail "$test (could not set breakpoint)" return } + -re "Could not insert single-step breakpoint.*$gdb_prompt $" { + setup_kfail "sparc*-*-openbsd*" gdb/1736 + fail "$test (could not insert single-step breakpoint)" + } -re "done = 1;.*${gdb_prompt} $" { send_gdb "$i\n" exp_continue -continue_timer diff --git a/gdb/testsuite/gdb.cp/m-static.cc b/gdb/testsuite/gdb.cp/m-static.cc index 6d08cb0..9dae5ee 100644 --- a/gdb/testsuite/gdb.cp/m-static.cc +++ b/gdb/testsuite/gdb.cp/m-static.cc @@ -68,5 +68,6 @@ int main() gnu_obj_3<long> test3(greek); gnu_obj_4 test4; - return 0; // breakpoint: constructs-done + test4.dummy = 0; + return test4.dummy; // breakpoint: constructs-done } diff --git a/gdb/testsuite/gdb.cp/m-static.h b/gdb/testsuite/gdb.cp/m-static.h index 137d3b7..012cd77 100644 --- a/gdb/testsuite/gdb.cp/m-static.h +++ b/gdb/testsuite/gdb.cp/m-static.h @@ -7,5 +7,8 @@ class gnu_obj_4 static const int nowhere; // At some point, perhaps: // static const int everywhere = 317; + + // try to ensure test4 is actually allocated + int dummy; }; diff --git a/gdb/testsuite/gdb.mi/mi-basics.exp b/gdb/testsuite/gdb.mi/mi-basics.exp index f6e82b0..7bf15d7 100644 --- a/gdb/testsuite/gdb.mi/mi-basics.exp +++ b/gdb/testsuite/gdb.mi/mi-basics.exp @@ -160,11 +160,11 @@ proc test_dir_specification {} { set envirodir [string_to_regexp ${srcdir}/${subdir}] mi_gdb_test "202-environment-directory ${srcdir}/${subdir}" \ - "\\\^done,source-path=\"${envirodir}.\\\$cdir.\\\$cwd\"" \ + "202\\\^done,source-path=\"${envirodir}.\\\$cdir.\\\$cwd\"" \ "environment-directory arg operation" mi_gdb_test "203-environment-directory" \ - "\\\^done,source-path=\"${envirodir}.\\\$cdir.\\\$cwd\"" \ + "203\\\^done,source-path=\"${envirodir}.\\\$cdir.\\\$cwd\"" \ "environment-directory empty-string operation" mi_gdb_test "204-environment-directory -r" \ @@ -223,7 +223,7 @@ proc test_path_specification {} { "environment-path no-args operation" mi_gdb_test "208-environment-path $srcdir $objdir" \ - "\\\^done,path=\"$escapedsrcdir.$escapedobjdir.$orig_path\"" \ + "208\\\^done,path=\"$escapedsrcdir.$escapedobjdir.$orig_path\"" \ "environment-path dir1 dir2 operation" mi_gdb_test "209-environment-path -r $objdir" \ diff --git a/gdb/testsuite/gdb.mi/mi-regs.exp b/gdb/testsuite/gdb.mi/mi-regs.exp index 5dbda48..2ca9803 100644 --- a/gdb/testsuite/gdb.mi/mi-regs.exp +++ b/gdb/testsuite/gdb.mi/mi-regs.exp @@ -52,7 +52,7 @@ proc sparc_register_tests_no_exec { } { "wrong arguments" mi_gdb_test "111-data-list-register-values x" \ - ".*111\\^error,msg=\"mi_cmd_data_list_register_values: No registers\.\"" \ + ".*111\\^error,msg=\"No registers\.\"" \ "no executable" } @@ -71,41 +71,41 @@ proc sparc_register_tests { } { set float2 "\\-?\[0-9\]+" mi_gdb_test "111-data-list-register-names" \ - "111\\^done,register-names=\\\[\"g0\",\"g1\",\"g2\",\"g3\",\"g4\",\"g5\",\"g6\",\"g7\",\"o0\",\"o1\",\"o2\",\"o3\",\"o4\",\"o5\",\"sp\",\"o7\",\"l0\",\"l1\",\"l2\",\"l3\",\"l4\",\"l5\",\"l6\",\"l7\",\"i0\",\"i1\",\"i2\",\"i3\",\"i4\",\"i5\",\"fp\",\"i7\",\"f0\",\"f1\",\"f2\",\"f3\",\"f4\",\"f5\",\"f6\",\"f7\",\"f8\",\"f9\",\"f10\",\"f11\",\"f12\",\"f13\",\"f14\",\"f15\",\"f16\",\"f17\",\"f18\",\"f19\",\"f20\",\"f21\",\"f22\",\"f23\",\"f24\",\"f25\",\"f26\",\"f27\",\"f28\",\"f29\",\"f30\",\"f31\",\"y\",\"psr\",\"wim\",\"tbr\",\"pc\",\"npc\",\"fpsr\",\"cpsr\"\\\]" \ + "111\\^done,register-names=\\\[\"g0\",\"g1\",\"g2\",\"g3\",\"g4\",\"g5\",\"g6\",\"g7\",\"o0\",\"o1\",\"o2\",\"o3\",\"o4\",\"o5\",\"sp\",\"o7\",\"l0\",\"l1\",\"l2\",\"l3\",\"l4\",\"l5\",\"l6\",\"l7\",\"i0\",\"i1\",\"i2\",\"i3\",\"i4\",\"i5\",\"fp\",\"i7\",\"f0\",\"f1\",\"f2\",\"f3\",\"f4\",\"f5\",\"f6\",\"f7\",\"f8\",\"f9\",\"f10\",\"f11\",\"f12\",\"f13\",\"f14\",\"f15\",\"f16\",\"f17\",\"f18\",\"f19\",\"f20\",\"f21\",\"f22\",\"f23\",\"f24\",\"f25\",\"f26\",\"f27\",\"f28\",\"f29\",\"f30\",\"f31\",\"y\",\"psr\",\"wim\",\"tbr\",\"pc\",\"npc\",\"fsr\",\"csr\",\"d0\",\"d2\",\"d4\",\"d6\",\"d8\",\"d10\",\"d12\",\"d14\",\"d16\",\"d18\",\"d20\",\"d22\",\"d24\",\"d26\",\"d28\",\"d30\"\\\]" \ "list register names" mi_gdb_test "222-data-list-register-values x" \ - "222\\^done,register-values=\\\[\{number=\"0\",value=\"$hex\"\}.*\{number=\"71\",value=\"$hex\"\}\\\]" \ + "222\\^done,register-values=\\\[\{number=\"0\",value=\"$hex\"\}.*\{number=\"87\",value=\"$hex\"\}\\\]" \ "register values x" mi_gdb_test "333-data-list-register-values f" \ - "333\\^done,register-values=\\\[\{number=\"0\",value=\"$float\"\},\{number=\"1\",value=\"$float\"\},.*\{number=\"71\",value=\"$float\"\}\\\]" \ + "333\\^done,register-values=\\\[\{number=\"0\",value=\"$float\"\},\{number=\"1\",value=\"$float\"\},.*\{number=\"87\",value=\"$float\"\}\\\]" \ "register values f" mi_gdb_test "444-data-list-register-values d" \ - "444\\^done,register-values=\\\[\{number=\"0\",value=\"$decimal\"\}.*\{number=\"71\",value=\"$decimal\"\}\\\]" \ + "444\\^done,register-values=\\\[\{number=\"0\",value=\"-?$decimal\"\}.*\{number=\"87\",value=\"-?$decimal\"\}\\\]" \ "register values d" mi_gdb_test "555-data-list-register-values o" \ - "555\\^done,register-values=\\\[\{number=\"0\",value=\"$octal\"\}.*\{number=\"71\",value=\"$octal\"\}\\\]" \ + "555\\^done,register-values=\\\[\{number=\"0\",value=\"$octal\"\}.*\{number=\"87\",value=\"$octal\"\}\\\]" \ "register values o" mi_gdb_test "666-data-list-register-values t" \ - "666\\^done,register-values=\\\[\{number=\"0\",value=\"$binary\"\}.*\{number=\"71\",value=\"$binary\"\}\\\]" \ + "666\\^done,register-values=\\\[\{number=\"0\",value=\"$binary\"\}.*\{number=\"87\",value=\"$binary\"\}\\\]" \ "register values t" - # On the sparc, registers 0-31 are int, 32-63 float, 64-71 int + # On the sparc, registers 0-31 are int, 32-63 float, 64-71 int, 72-87 float mi_gdb_test "777-data-list-register-values N" \ - "777\\^done,register-values=\\\[\{number=\"0\",value=\"$decimal\"\}.*\{number=\"31\",value=\"$decimal\"\},\{number=\"32\",value=\"$float\"\}.*\{number=\"63\",value=\"$float\"\},\{number=\"64\",value=\"$decimal\"\}.*\{number=\"71\",value=\"$decimal\"\}\\\]" \ + "777\\^done,register-values=\\\[\{number=\"0\",value=\"-?$decimal\"\}.*\{number=\"31\",value=\"-?$decimal\"\},\{number=\"32\",value=\"$float\"\}.*\{number=\"63\",value=\"$float\"\},\{number=\"64\",value=\"-?$decimal\"\}.*\{number=\"71\",value=\"-?$decimal\"\},\{number=\"72\",value=\"$float\"\}.*\{number=\"87\",value=\"$float\"\}\\\]" \ "register values N" mi_gdb_test "888-data-list-register-values r" \ - "888\\^done,register-values=\\\[\{number=\"0\",value=\"$hex\"\}.*\{number=\"71\",value=\"$hex\"\}\\\]" \ + "888\\^done,register-values=\\\[\{number=\"0\",value=\"$hex\"\}.*\{number=\"87\",value=\"$hex\"\}\\\]" \ "register values r" mi_gdb_test "999-data-list-register-names 68 69 70 71" \ - "999\\^done,register-names=\\\[\"pc\",\"npc\",\"fpsr\",\"cpsr\"\\\]" \ + "999\\^done,register-names=\\\[\"pc\",\"npc\",\"fsr\",\"csr\"\\\]" \ "list names of some regs" mi_gdb_test "001-data-list-register-values x 68 69 70 71" \ diff --git a/gdb/testsuite/gdb.mi/mi2-basics.exp b/gdb/testsuite/gdb.mi/mi2-basics.exp index bde6e94..d265888 100644 --- a/gdb/testsuite/gdb.mi/mi2-basics.exp +++ b/gdb/testsuite/gdb.mi/mi2-basics.exp @@ -161,11 +161,11 @@ proc test_dir_specification {} { set envirodir [string_to_regexp ${srcdir}/${subdir}] mi_gdb_test "202-environment-directory ${srcdir}/${subdir}" \ - "\\\^done,source-path=\"${envirodir}.\\\$cdir.\\\$cwd\"" \ + "202\\\^done,source-path=\"${envirodir}.\\\$cdir.\\\$cwd\"" \ "environment-directory arg operation" mi_gdb_test "203-environment-directory" \ - "\\\^done,source-path=\"${envirodir}.\\\$cdir.\\\$cwd\"" \ + "203\\\^done,source-path=\"${envirodir}.\\\$cdir.\\\$cwd\"" \ "environment-directory empty-string operation" mi_gdb_test "204-environment-directory -r" \ @@ -226,7 +226,7 @@ proc test_path_specification {} { "environment-path no-args operation" mi_gdb_test "208-environment-path $srcdir $objdir" \ - "\\\^done,path=\"$escapedsrcdir.$escapedobjdir.$orig_path\"" \ + "208\\\^done,path=\"$escapedsrcdir.$escapedobjdir.$orig_path\"" \ "environment-path dir1 dir2 operation" mi_gdb_test "209-environment-path -r $objdir" \ diff --git a/gdb/testsuite/gdb.mi/mi2-regs.exp b/gdb/testsuite/gdb.mi/mi2-regs.exp index 546cc93..3277ccd 100644 --- a/gdb/testsuite/gdb.mi/mi2-regs.exp +++ b/gdb/testsuite/gdb.mi/mi2-regs.exp @@ -52,7 +52,7 @@ proc sparc_register_tests_no_exec { } { "wrong arguments" mi_gdb_test "111-data-list-register-values x" \ - ".*111\\^error,msg=\"mi_cmd_data_list_register_values: No registers\.\"" \ + ".*111\\^error,msg=\"No registers\.\"" \ "no executable" } @@ -71,41 +71,41 @@ proc sparc_register_tests { } { set float2 "\\-?\[0-9\]+" mi_gdb_test "111-data-list-register-names" \ - "111\\^done,register-names=\\\[\"g0\",\"g1\",\"g2\",\"g3\",\"g4\",\"g5\",\"g6\",\"g7\",\"o0\",\"o1\",\"o2\",\"o3\",\"o4\",\"o5\",\"sp\",\"o7\",\"l0\",\"l1\",\"l2\",\"l3\",\"l4\",\"l5\",\"l6\",\"l7\",\"i0\",\"i1\",\"i2\",\"i3\",\"i4\",\"i5\",\"fp\",\"i7\",\"f0\",\"f1\",\"f2\",\"f3\",\"f4\",\"f5\",\"f6\",\"f7\",\"f8\",\"f9\",\"f10\",\"f11\",\"f12\",\"f13\",\"f14\",\"f15\",\"f16\",\"f17\",\"f18\",\"f19\",\"f20\",\"f21\",\"f22\",\"f23\",\"f24\",\"f25\",\"f26\",\"f27\",\"f28\",\"f29\",\"f30\",\"f31\",\"y\",\"psr\",\"wim\",\"tbr\",\"pc\",\"npc\",\"fpsr\",\"cpsr\"\\\]" \ + "111\\^done,register-names=\\\[\"g0\",\"g1\",\"g2\",\"g3\",\"g4\",\"g5\",\"g6\",\"g7\",\"o0\",\"o1\",\"o2\",\"o3\",\"o4\",\"o5\",\"sp\",\"o7\",\"l0\",\"l1\",\"l2\",\"l3\",\"l4\",\"l5\",\"l6\",\"l7\",\"i0\",\"i1\",\"i2\",\"i3\",\"i4\",\"i5\",\"fp\",\"i7\",\"f0\",\"f1\",\"f2\",\"f3\",\"f4\",\"f5\",\"f6\",\"f7\",\"f8\",\"f9\",\"f10\",\"f11\",\"f12\",\"f13\",\"f14\",\"f15\",\"f16\",\"f17\",\"f18\",\"f19\",\"f20\",\"f21\",\"f22\",\"f23\",\"f24\",\"f25\",\"f26\",\"f27\",\"f28\",\"f29\",\"f30\",\"f31\",\"y\",\"psr\",\"wim\",\"tbr\",\"pc\",\"npc\",\"fsr\",\"csr\",\"d0\",\"d2\",\"d4\",\"d6\",\"d8\",\"d10\",\"d12\",\"d14\",\"d16\",\"d18\",\"d20\",\"d22\",\"d24\",\"d26\",\"d28\",\"d30\"\\\]" \ "list register names" mi_gdb_test "222-data-list-register-values x" \ - "222\\^done,register-values=\\\[\{number=\"0\",value=\"$hex\"\}.*\{number=\"71\",value=\"$hex\"\}\\\]" \ + "222\\^done,register-values=\\\[\{number=\"0\",value=\"$hex\"\}.*\{number=\"87\",value=\"$hex\"\}\\\]" \ "register values x" mi_gdb_test "333-data-list-register-values f" \ - "333\\^done,register-values=\\\[\{number=\"0\",value=\"$float\"\},\{number=\"1\",value=\"$float\"\},.*\{number=\"71\",value=\"$float\"\}\\\]" \ + "333\\^done,register-values=\\\[\{number=\"0\",value=\"$float\"\},\{number=\"1\",value=\"$float\"\},.*\{number=\"87\",value=\"$float\"\}\\\]" \ "register values f" mi_gdb_test "444-data-list-register-values d" \ - "444\\^done,register-values=\\\[\{number=\"0\",value=\"$decimal\"\}.*\{number=\"71\",value=\"$decimal\"\}\\\]" \ + "444\\^done,register-values=\\\[\{number=\"0\",value=\"-?$decimal\"\}.*\{number=\"87\",value=\"-?$decimal\"\}\\\]" \ "register values d" mi_gdb_test "555-data-list-register-values o" \ - "555\\^done,register-values=\\\[\{number=\"0\",value=\"$octal\"\}.*\{number=\"71\",value=\"$octal\"\}\\\]" \ + "555\\^done,register-values=\\\[\{number=\"0\",value=\"$octal\"\}.*\{number=\"87\",value=\"$octal\"\}\\\]" \ "register values o" mi_gdb_test "666-data-list-register-values t" \ - "666\\^done,register-values=\\\[\{number=\"0\",value=\"$binary\"\}.*\{number=\"71\",value=\"$binary\"\}\\\]" \ + "666\\^done,register-values=\\\[\{number=\"0\",value=\"$binary\"\}.*\{number=\"87\",value=\"$binary\"\}\\\]" \ "register values t" - # On the sparc, registers 0-31 are int, 32-63 float, 64-71 int + # On the sparc, registers 0-31 are int, 32-63 float, 64-71 int, 72-87 float mi_gdb_test "777-data-list-register-values N" \ - "777\\^done,register-values=\\\[\{number=\"0\",value=\"$decimal\"\}.*\{number=\"31\",value=\"$decimal\"\},\{number=\"32\",value=\"$float\"\}.*\{number=\"63\",value=\"$float\"\},\{number=\"64\",value=\"$decimal\"\}.*\{number=\"71\",value=\"$decimal\"\}\\\]" \ + "777\\^done,register-values=\\\[\{number=\"0\",value=\"-?$decimal\"\}.*\{number=\"31\",value=\"-?$decimal\"\},\{number=\"32\",value=\"$float\"\}.*\{number=\"63\",value=\"$float\"\},\{number=\"64\",value=\"-?$decimal\"\}.*\{number=\"71\",value=\"-?$decimal\"\},\{number=\"72\",value=\"$float\"\}.*\{number=\"87\",value=\"$float\"\}\\\]" \ "register values N" mi_gdb_test "888-data-list-register-values r" \ - "888\\^done,register-values=\\\[\{number=\"0\",value=\"$hex\"\}.*\{number=\"71\",value=\"$hex\"\}\\\]" \ + "888\\^done,register-values=\\\[\{number=\"0\",value=\"$hex\"\}.*\{number=\"87\",value=\"$hex\"\}\\\]" \ "register values r" mi_gdb_test "999-data-list-register-names 68 69 70 71" \ - "999\\^done,register-names=\\\[\"pc\",\"npc\",\"fpsr\",\"cpsr\"\\\]" \ + "999\\^done,register-names=\\\[\"pc\",\"npc\",\"fsr\",\"csr\"\\\]" \ "list names of some regs" mi_gdb_test "001-data-list-register-values x 68 69 70 71" \ diff --git a/gdb/testsuite/gdb.mi/var-cmd.c b/gdb/testsuite/gdb.mi/var-cmd.c index 2a297d2..4ccd570 100644 --- a/gdb/testsuite/gdb.mi/var-cmd.c +++ b/gdb/testsuite/gdb.mi/var-cmd.c @@ -301,6 +301,12 @@ do_special_tests (void) int a; a = 1; + u.integer = a; + anonu.a = a; + s.integer = a; + anons.a = a; + e = bar; + anone = A; incr_a(2); } diff --git a/gdb/varobj.c b/gdb/varobj.c index c16e088..c664bfd 100644 --- a/gdb/varobj.c +++ b/gdb/varobj.c @@ -2054,10 +2054,16 @@ c_variable_editable (struct varobj *var) static char * c_value_of_variable (struct varobj *var) { - /* BOGUS: if val_print sees a struct/class, it will print out its - children instead of "{...}" */ + /* BOGUS: if val_print sees a struct/class, or a reference to one, + it will print out its children instead of "{...}". So we need to + catch that case explicitly. */ + struct type *type = get_type (var); - switch (TYPE_CODE (get_type (var))) + /* Strip top-level references. */ + while (TYPE_CODE (type) == TYPE_CODE_REF) + type = check_typedef (TYPE_TARGET_TYPE (type)); + + switch (TYPE_CODE (type)) { case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: diff --git a/gdb/version.in b/gdb/version.in index 70f27cd..144b14d 100644 --- a/gdb/version.in +++ b/gdb/version.in @@ -1 +1 @@ -6.4.50.20060420-cvs +6.4.50.20060512-cvs diff --git a/include/ChangeLog b/include/ChangeLog index 0a3787a..6f695ff 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -17,6 +17,11 @@ R_BFIN_GOTOFFLO): New relocs. (EF_BFIN_PIC, EF_BFIN_FDPIC, EF_BFIN_PIC_FLAGS): New macros. +2006-03-23 Michael Matz <matz@suse.de> + + * elf/x86-64.h: Add the new relocations with their official + numbers. + 2006-02-17 Shrirang Khisti <shrirangk@kpitcummins.com> Anil Paranjape <anilp1@kpitcummins.com> Shilin Shakti <shilins@kpitcummins.com> diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index ad4411a..4682f2d 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,4 +1,35 @@ -2006-04-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de> +2006-05-05 Thiemo Seufer <ths@mips.com> + David Ung <davidu@mips.com> + + * mips.h (enum): Add macro M_CACHE_AB. + +2006-05-04 Thiemo Seufer <ths@mips.com> + Nigel Stephens <nigel@mips.com> + David Ung <davidu@mips.com> + + * mips.h: Add INSN_SMARTMIPS define. + +2006-04-30 Thiemo Seufer <ths@mips.com> + David Ung <davidu@mips.com> + + * mips.h: Defines udi bits and masks. Add description of + characters which may appear in the args field of udi + instructions. + +2006-04-26 Thiemo Seufer <ths@networkno.de> + + * mips.h: Improve comments describing the bitfield instruction + fields. + +2006-04-26 Julian Brown <julian@codesourcery.com> + + * arm.h (FPU_VFP_EXT_V3): Define constant. + (FPU_NEON_EXT_V1): Likewise. + (FPU_VFP_HARD): Update. + (FPU_VFP_V3): Define macro. + (FPU_ARCH_VFP_V3, FPU_ARCH_VFP_V3_PLUS_NEON_V1): Define macros. + +2006-04-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de> * avr.h (AVR_ISA_PWMx): New. diff --git a/include/opcode/arm.h b/include/opcode/arm.h index 1d3aa5a..f142fca 100644 --- a/include/opcode/arm.h +++ b/include/opcode/arm.h @@ -58,6 +58,8 @@ #define FPU_VFP_EXT_V1xD 0x08000000 /* Base VFP instruction set. */ #define FPU_VFP_EXT_V1 0x04000000 /* Double-precision insns. */ #define FPU_VFP_EXT_V2 0x02000000 /* ARM10E VFPr1. */ +#define FPU_VFP_EXT_V3 0x01000000 /* VFPv3 insns. */ +#define FPU_NEON_EXT_V1 0x00800000 /* Neon (SIMD) insns. */ /* Architectures are the sum of the base and extensions. The ARM ARM (rev E) defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T, @@ -105,7 +107,9 @@ #define FPU_VFP_V1xD (FPU_VFP_EXT_V1xD | FPU_ENDIAN_PURE) #define FPU_VFP_V1 (FPU_VFP_V1xD | FPU_VFP_EXT_V1) #define FPU_VFP_V2 (FPU_VFP_V1 | FPU_VFP_EXT_V2) -#define FPU_VFP_HARD (FPU_VFP_EXT_V1xD | FPU_VFP_EXT_V1 | FPU_VFP_EXT_V2) +#define FPU_VFP_V3 (FPU_VFP_V2 | FPU_VFP_EXT_V3) +#define FPU_VFP_HARD (FPU_VFP_EXT_V1xD | FPU_VFP_EXT_V1 | FPU_VFP_EXT_V2 \ + | FPU_VFP_EXT_V3 | FPU_NEON_EXT_V1) #define FPU_FPA (FPU_FPA_EXT_V1 | FPU_FPA_EXT_V2) /* Deprecated */ @@ -117,6 +121,10 @@ #define FPU_ARCH_VFP_V1xD ARM_FEATURE (0, FPU_VFP_V1xD) #define FPU_ARCH_VFP_V1 ARM_FEATURE (0, FPU_VFP_V1) #define FPU_ARCH_VFP_V2 ARM_FEATURE (0, FPU_VFP_V2) +#define FPU_ARCH_VFP_V3 ARM_FEATURE (0, FPU_VFP_V3) +#define FPU_ARCH_NEON_V1 ARM_FEATURE (0, FPU_NEON_EXT_V1) +#define FPU_ARCH_VFP_V3_PLUS_NEON_V1 \ + ARM_FEATURE (0, FPU_VFP_V3 | FPU_NEON_EXT_V1) #define FPU_ARCH_VFP_HARD ARM_FEATURE (0, FPU_VFP_HARD) #define FPU_ARCH_ENDIAN_PURE ARM_FEATURE (0, FPU_ENDIAN_PURE) diff --git a/include/opcode/mips.h b/include/opcode/mips.h index 4bec5ed..aa8040a 100644 --- a/include/opcode/mips.h +++ b/include/opcode/mips.h @@ -203,6 +203,16 @@ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, US #define MDMX_FMTSEL_VEC_QH 0x15 #define MDMX_FMTSEL_VEC_OB 0x16 +/* UDI */ +#define OP_SH_UDI1 6 +#define OP_MASK_UDI1 0x1f +#define OP_SH_UDI2 6 +#define OP_MASK_UDI2 0x3ff +#define OP_SH_UDI3 6 +#define OP_MASK_UDI3 0x7fff +#define OP_SH_UDI4 6 +#define OP_MASK_UDI4 0xfffff + /* This structure holds information for a particular instruction. */ struct mips_opcode @@ -268,19 +278,20 @@ struct mips_opcode "x" accept and ignore register name "z" must be zero register "K" 5 bit Hardware Register (rdhwr instruction) (OP_*_RD) - "+A" 5 bit ins/ext position, which becomes LSB (OP_*_SHAMT). + "+A" 5 bit ins/ext/dins/dext/dinsm/dextm position, which becomes + LSB (OP_*_SHAMT). Enforces: 0 <= pos < 32. - "+B" 5 bit ins size, which becomes MSB (OP_*_INSMSB). + "+B" 5 bit ins/dins size, which becomes MSB (OP_*_INSMSB). Requires that "+A" or "+E" occur first to set position. Enforces: 0 < (pos+size) <= 32. - "+C" 5 bit ext size, which becomes MSBD (OP_*_EXTMSBD). + "+C" 5 bit ext/dext size, which becomes MSBD (OP_*_EXTMSBD). Requires that "+A" or "+E" occur first to set position. Enforces: 0 < (pos+size) <= 32. (Also used by "dext" w/ different limits, but limits for that are checked by the M_DEXT macro.) - "+E" 5 bit dins/dext position, which becomes LSB-32 (OP_*_SHAMT). + "+E" 5 bit dinsu/dextu position, which becomes LSB-32 (OP_*_SHAMT). Enforces: 32 <= pos < 64. - "+F" 5 bit "dinsm" size, which becomes MSB-32 (OP_*_INSMSB). + "+F" 5 bit "dinsm/dinsu" size, which becomes MSB-32 (OP_*_INSMSB). Requires that "+A" or "+E" occur first to set position. Enforces: 32 < (pos+size) <= 64. "+G" 5 bit "dextm" size, which becomes MSBD-32 (OP_*_EXTMSBD). @@ -350,6 +361,12 @@ struct mips_opcode "+t" 5 bit coprocessor 0 destination register (OP_*_RT) "+T" 5 bit coprocessor 0 destination register (OP_*_RT) - disassembly only + UDI immediates: + "+1" UDI immediate bits 6-10 + "+2" UDI immediate bits 6-15 + "+3" UDI immediate bits 6-20 + "+4" UDI immediate bits 6-25 + Other: "()" parens surrounding optional value "," separates operands @@ -364,6 +381,7 @@ struct mips_opcode Extension character sequences used so far ("+" followed by the following), for quick reference when adding more: + "1234" "ABCDEFGHIT" "t" */ @@ -467,7 +485,7 @@ struct mips_opcode #define INSN_ISA64R2 0x00000100 /* Masks used for MIPS-defined ASEs. */ -#define INSN_ASE_MASK 0x0400f000 +#define INSN_ASE_MASK 0x0c00f000 /* DSP ASE */ #define INSN_DSP 0x00001000 @@ -500,9 +518,13 @@ struct mips_opcode #define INSN_5400 0x01000000 /* NEC VR5500 instruction. */ #define INSN_5500 0x02000000 + /* MT ASE */ #define INSN_MT 0x04000000 +/* SmartMIPS ASE. */ +#define INSN_SMARTMIPS 0x08000000 + /* MIPS ISA defines, use instead of hardcoding ISA level. */ #define ISA_UNKNOWN 0 /* Gas internal use. */ @@ -624,6 +646,7 @@ enum M_BNE, M_BNE_I, M_BNEL_I, + M_CACHE_AB, M_DABS, M_DADD_I, M_DADDU_I, diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index fb328da..76baa3c 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,7 @@ +2006-04-24 Julian Brown <julian@codesourcery.com> + + * floatformat.c (floatformat_to_double): Fix (biased) exponent=0 case. + 2006-03-29 Jim Blandy <jimb@codesourcery.com> * pex-common.c (pex_input_file, pex_input_pipe): New functions. diff --git a/libiberty/floatformat.c b/libiberty/floatformat.c index bd31efa..0bbb8ed 100644 --- a/libiberty/floatformat.c +++ b/libiberty/floatformat.c @@ -394,7 +394,7 @@ floatformat_to_double (const struct floatformat *fmt, /* Handle denormalized numbers. FIXME: What should we do for non-IEEE formats? */ - if (exponent == 0 && mant != 0) + if (special_exponent && exponent == 0 && mant != 0) dto += ldexp ((double)mant, (- fmt->exp_bias - mant_bits diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 8637a8b..b3c5b6f 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,109 @@ +2006-05-09 H.J. Lu <hongjiu.lu@intel.com> + + * i386-dis.c (grps): Update sgdt/sidt for 64bit. + +2006-05-05 Julian Brown <julian@codesourcery.com> + + * arm-dis.c (coprocessor_opcodes): Don't interpret fldmx/fstmx as + vldm/vstm. + +2006-05-05 Thiemo Seufer <ths@mips.com> + David Ung <davidu@mips.com> + + * mips-opc.c: Add macro for cache instruction. + +2006-05-04 Thiemo Seufer <ths@mips.com> + Nigel Stephens <nigel@mips.com> + David Ung <davidu@mips.com> + + * mips-dis.c (mips_arch_choices): Add smartmips instruction + decoding to MIPS32 and MIPS32R2. Limit DSP decoding to release + 2 ISAs. Add MIPS3D decoding to MIPS32R2. Add MT decoding to + MIPS64R2. + * mips-opc.c: fix random typos in comments. + (INSN_SMARTMIPS): New defines. + (mips_builtin_opcodes): Add paired single support for MIPS32R2. + Move bc3f, bc3fl, bc3t, bc3tl downwards. Move flushi, flushd, + flushid, wb upwards. Move cfc3, ctc3 downwards. Rework the + FP_S and FP_D flags to denote single and double register + accesses separately. Move dmfc3, dmtc3, mfc3, mtc3 downwards. + Allow jr.hb and jalr.hb for release 1 ISAs. Allow luxc1, suxc1 + for MIPS32R2. Add SmartMIPS instructions. Add two-argument + variants of bc2f, bc2fl, bc2t, bc2tl. Add mfhc2, mthc2 to + release 2 ISAs. + * mips16-opc.c (mips16_opcodes): Add sdbbp instruction. + +2006-05-03 Thiemo Seufer <ths@mips.com> + + * mips-opc.c (mips_builtin_opcodes): Fix mftr argument order. + +2006-05-02 Thiemo Seufer <ths@mips.com> + Nigel Stephens <nigel@mips.com> + David Ung <davidu@mips.com> + + * mips-dis.c (print_insn_args): Force mips16 to odd addresses. + (print_mips16_insn_arg): Force mips16 to odd addresses. + +2006-04-30 Thiemo Seufer <ths@mips.com> + David Ung <davidu@mips.com> + + * mips-opc.c (mips_builtin_opcodes): Add udi instructions + "udi0" to "udi15". + * mips-dis.c (print_insn_args): Adds udi argument handling. + +2006-04-28 James E Wilson <wilson@specifix.com> + + * m68k-dis.c (match_insn_m68k): Restore fprintf_func before printing + error message. + +2006-04-28 Thiemo Seufer <ths@mips.com> + David Ung <davidu@mips.com> + Nigel Stephens <nigel@mips.com> + + * mips-dis.c (mips_cp0sel_names_mips3264r2): Add MT register + names. + +2006-04-28 Thiemo Seufer <ths@mips.com> + Nigel Stephens <nigel@mips.com> + David Ung <davidu@mips.com> + + * mips-dis.c (print_insn_args): Add mips_opcode argument. + (print_insn_mips): Adjust print_insn_args call. + +2006-04-28 Thiemo Seufer <ths@mips.com> + Nigel Stephens <nigel@mips.com> + + * mips-dis.c (print_insn_args): Print $fcc only for FP + instructions, use $cc elsewise. + +2006-04-28 Thiemo Seufer <ths@mips.com> + Nigel Stephens <nigel@mips.com> + + * opcodes/mips-dis.c (mips16_to_32_reg_map, mips16_reg_names): + Map MIPS16 registers to O32 names. + (print_mips16_insn_arg): Use mips16_reg_names. + +2006-04-26 Julian Brown <julian@codesourcery.com> + + * arm-dis.c (print_insn_neon): Disassemble floating-point constant + VMOV. + +2006-04-26 Nathan Sidwell <nathan@codesourcery.com> + Julian Brown <julian@codesourcery.com> + + * opcodes/arm-dis.c (coprocessor_opcodes): Add %A, %B, %k, convert + %<code>[zy] into %[zy]<code>. Expand meaning of %<bitfield>['`?]. + Add unified load/store instruction names. + (neon_opcode_table): New. + (arm_opcodes): Expand meaning of %<bitfield>['`?]. + (arm_decode_bitfield): New. + (print_insn_coprocessor): Add pc argument. Add %A & %B specifiers. + Use arm_decode_bitfield and adjust numeric specifiers. Adjust %z & %y. + (print_insn_neon): New. + (print_insn_arm): Adjust print_insn_coprocessor call. Call + print_insn_neon. Use arm_decode_bitfield and adjust numeric specifiers. + (print_insn_thumb32): Likewise. + 2006-04-19 Alan Modra <amodra@bigpond.net.au> * Makefile.am: Run "make dep-am". diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c index bc5b52c..ef80304 100644 --- a/opcodes/arm-dis.c +++ b/opcodes/arm-dis.c @@ -26,6 +26,7 @@ #include "opcode/arm.h" #include "opintl.h" #include "safe-ctype.h" +#include "floatformat.h" /* FIXME: This shouldn't be done here. */ #include "coff/internal.h" @@ -63,6 +64,8 @@ struct opcode16 %c print condition code (always bits 28-31) %A print address for ldc/stc/ldf/stf instruction + %B print vstm/vldm register list + %C print vstr/vldr address operand %I print cirrus signed shift immediate: bits 0..3|4..6 %F print the COUNT field of a LFM/SFM instruction. %P print floating point precision in arithmetic insn @@ -71,6 +74,7 @@ struct opcode16 %<bitfield>r print as an ARM register %<bitfield>d print the bitfield in decimal + %<bitfield>k print immediate for VFPv3 conversion instruction %<bitfield>x print the bitfield in hex %<bitfield>X print the bitfield as 1 hex digit without leading "0x" %<bitfield>f print a floating point constant if >7 else a @@ -78,15 +82,18 @@ struct opcode16 %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us %<bitfield>g print as an iWMMXt 64-bit register %<bitfield>G print as an iWMMXt general purpose or control register + %<bitfield>D print as a NEON D register + %<bitfield>Q print as a NEON Q register - %<code>y print a single precision VFP reg. + %y<code> print a single precision VFP reg. Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair - %<code>z print a double precision VFP reg + %z<code> print a double precision VFP reg Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list - %<bitnum>'c print specified char iff bit is one - %<bitnum>`c print specified char iff bit is zero - %<bitnum>?ab print a if bit is one else print b + %<bitfield>'c print specified char iff bitfield is all ones + %<bitfield>`c print specified char iff bitfield is all zeroes + %<bitfield>?ab... select from array of values in big endian order + %L print as an iWMMXt N/M width field. %Z print the Immediate of a WSHUFH instruction. %l like 'A' except use byte offsets for 'B' & 'H' @@ -201,80 +208,110 @@ static const struct opcode32 coprocessor_opcodes[] = {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"}, {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"}, + /* Register load/store */ + {FPU_NEON_EXT_V1, 0x0d200b00, 0x0fb00f01, "vstmdb%c\t%16-19r%21'!, %B"}, + {FPU_NEON_EXT_V1, 0x0d300b00, 0x0fb00f01, "vldmdb%c\t%16-19r%21'!, %B"}, + {FPU_NEON_EXT_V1, 0x0c800b00, 0x0f900f01, "vstmia%c\t%16-19r%21'!, %B"}, + {FPU_NEON_EXT_V1, 0x0c900b00, 0x0f900f01, "vldmia%c\t%16-19r%21'!, %B"}, + {FPU_NEON_EXT_V1, 0x0d000b00, 0x0f300f00, "vstr%c\t%12-15,22D, %C"}, + {FPU_NEON_EXT_V1, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %C"}, + + /* Data transfer between ARM and NEON registers */ + {FPU_NEON_EXT_V1, 0x0e800b10, 0x0ff00f70, "vdup%c.32\t%16-19,7D, %12-15r"}, + {FPU_NEON_EXT_V1, 0x0e800b30, 0x0ff00f70, "vdup%c.16\t%16-19,7D, %12-15r"}, + {FPU_NEON_EXT_V1, 0x0ea00b10, 0x0ff00f70, "vdup%c.32\t%16-19,7Q, %12-15r"}, + {FPU_NEON_EXT_V1, 0x0ea00b30, 0x0ff00f70, "vdup%c.16\t%16-19,7Q, %12-15r"}, + {FPU_NEON_EXT_V1, 0x0ec00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7D, %12-15r"}, + {FPU_NEON_EXT_V1, 0x0ee00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7Q, %12-15r"}, + {FPU_NEON_EXT_V1, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%0-3,5D, %12-15r, %16-19r"}, + {FPU_NEON_EXT_V1, 0x0c500b10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %0-3,5D"}, + {FPU_NEON_EXT_V1, 0x0e000b10, 0x0fd00f70, "vmov%c.32\t%16-19,7D[%21d], %12-15r"}, + {FPU_NEON_EXT_V1, 0x0e100b10, 0x0f500f70, "vmov%c.32\t%12-15r, %16-19,7D[%21d]"}, + {FPU_NEON_EXT_V1, 0x0e000b30, 0x0fd00f30, "vmov%c.16\t%16-19,7D[%6,21d], %12-15r"}, + {FPU_NEON_EXT_V1, 0x0e100b30, 0x0f500f30, "vmov%c.%23?us16\t%12-15r, %16-19,7D[%6,21d]"}, + {FPU_NEON_EXT_V1, 0x0e400b10, 0x0fd00f10, "vmov%c.8\t%16-19,7D[%5,6,21d], %12-15r"}, + {FPU_NEON_EXT_V1, 0x0e500b10, 0x0f500f10, "vmov%c.%23?us8\t%12-15r, %16-19,7D[%5,6,21d]"}, + /* Floating point coprocessor (VFP) instructions */ - {FPU_VFP_EXT_V1, 0x0eb00bc0, 0x0fff0ff0, "fabsd%c\t%1z, %0z"}, - {FPU_VFP_EXT_V1xD, 0x0eb00ac0, 0x0fbf0fd0, "fabss%c\t%1y, %0y"}, - {FPU_VFP_EXT_V1, 0x0e300b00, 0x0ff00ff0, "faddd%c\t%1z, %2z, %0z"}, - {FPU_VFP_EXT_V1xD, 0x0e300a00, 0x0fb00f50, "fadds%c\t%1y, %2y, %0y"}, - {FPU_VFP_EXT_V1, 0x0eb40b40, 0x0fff0f70, "fcmp%7'ed%c\t%1z, %0z"}, - {FPU_VFP_EXT_V1xD, 0x0eb40a40, 0x0fbf0f50, "fcmp%7'es%c\t%1y, %0y"}, - {FPU_VFP_EXT_V1, 0x0eb50b40, 0x0fff0f70, "fcmp%7'ezd%c\t%1z"}, - {FPU_VFP_EXT_V1xD, 0x0eb50a40, 0x0fbf0f70, "fcmp%7'ezs%c\t%1y"}, - {FPU_VFP_EXT_V1, 0x0eb00b40, 0x0fff0ff0, "fcpyd%c\t%1z, %0z"}, - {FPU_VFP_EXT_V1xD, 0x0eb00a40, 0x0fbf0fd0, "fcpys%c\t%1y, %0y"}, - {FPU_VFP_EXT_V1, 0x0eb70ac0, 0x0fff0fd0, "fcvtds%c\t%1z, %0y"}, - {FPU_VFP_EXT_V1, 0x0eb70bc0, 0x0fbf0ff0, "fcvtsd%c\t%1y, %0z"}, - {FPU_VFP_EXT_V1, 0x0e800b00, 0x0ff00ff0, "fdivd%c\t%1z, %2z, %0z"}, - {FPU_VFP_EXT_V1xD, 0x0e800a00, 0x0fb00f50, "fdivs%c\t%1y, %2y, %0y"}, - {FPU_VFP_EXT_V1, 0x0d100b00, 0x0f700f00, "fldd%c\t%1z, %A"}, - {FPU_VFP_EXT_V1xD, 0x0c900b00, 0x0fd00f00, "fldmia%0?xd%c\t%16-19r%21'!, %3z"}, - {FPU_VFP_EXT_V1xD, 0x0d300b00, 0x0ff00f00, "fldmdb%0?xd%c\t%16-19r!, %3z"}, - {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "flds%c\t%1y, %A"}, - {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "fldmias%c\t%16-19r%21'!, %3y"}, - {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "fldmdbs%c\t%16-19r!, %3y"}, - {FPU_VFP_EXT_V1, 0x0e000b00, 0x0ff00ff0, "fmacd%c\t%1z, %2z, %0z"}, - {FPU_VFP_EXT_V1xD, 0x0e000a00, 0x0fb00f50, "fmacs%c\t%1y, %2y, %0y"}, - {FPU_VFP_EXT_V1, 0x0e200b10, 0x0ff00fff, "fmdhr%c\t%2z, %12-15r"}, - {FPU_VFP_EXT_V1, 0x0e000b10, 0x0ff00fff, "fmdlr%c\t%2z, %12-15r"}, - {FPU_VFP_EXT_V2, 0x0c400b10, 0x0ff00ff0, "fmdrr%c\t%0z, %12-15r, %16-19r"}, - {FPU_VFP_EXT_V1, 0x0e300b10, 0x0ff00fff, "fmrdh%c\t%12-15r, %2z"}, - {FPU_VFP_EXT_V1, 0x0e100b10, 0x0ff00fff, "fmrdl%c\t%12-15r, %2z"}, - {FPU_VFP_EXT_V1, 0x0c500b10, 0x0ff00ff0, "fmrrd%c\t%12-15r, %16-19r, %0z"}, - {FPU_VFP_EXT_V2, 0x0c500a10, 0x0ff00fd0, "fmrrs%c\t%12-15r, %16-19r, %4y"}, - {FPU_VFP_EXT_V1xD, 0x0e100a10, 0x0ff00f7f, "fmrs%c\t%12-15r, %2y"}, {FPU_VFP_EXT_V1xD, 0x0ef1fa10, 0x0fffffff, "fmstat%c"}, - {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpsid"}, - {FPU_VFP_EXT_V1xD, 0x0ef10a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpscr"}, - {FPU_VFP_EXT_V1xD, 0x0ef80a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpexc"}, - {FPU_VFP_EXT_V1xD, 0x0ef90a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst\t@ Impl def"}, - {FPU_VFP_EXT_V1xD, 0x0efa0a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst2\t@ Impl def"}, - {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0ff00fff, "fmrx%c\t%12-15r, <impl def 0x%16-19x>"}, - {FPU_VFP_EXT_V1, 0x0e100b00, 0x0ff00ff0, "fmscd%c\t%1z, %2z, %0z"}, - {FPU_VFP_EXT_V1xD, 0x0e100a00, 0x0fb00f50, "fmscs%c\t%1y, %2y, %0y"}, - {FPU_VFP_EXT_V1xD, 0x0e000a10, 0x0ff00f7f, "fmsr%c\t%2y, %12-15r"}, - {FPU_VFP_EXT_V2, 0x0c400a10, 0x0ff00fd0, "fmsrr%c\t%12-15r, %16-19r, %4y"}, - {FPU_VFP_EXT_V1, 0x0e200b00, 0x0ff00ff0, "fmuld%c\t%1z, %2z, %0z"}, - {FPU_VFP_EXT_V1xD, 0x0e200a00, 0x0fb00f50, "fmuls%c\t%1y, %2y, %0y"}, {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0fff0fff, "fmxr%c\tfpsid, %12-15r"}, {FPU_VFP_EXT_V1xD, 0x0ee10a10, 0x0fff0fff, "fmxr%c\tfpscr, %12-15r"}, {FPU_VFP_EXT_V1xD, 0x0ee80a10, 0x0fff0fff, "fmxr%c\tfpexc, %12-15r"}, {FPU_VFP_EXT_V1xD, 0x0ee90a10, 0x0fff0fff, "fmxr%c\tfpinst, %12-15r\t@ Impl def"}, {FPU_VFP_EXT_V1xD, 0x0eea0a10, 0x0fff0fff, "fmxr%c\tfpinst2, %12-15r\t@ Impl def"}, + {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpsid"}, + {FPU_VFP_EXT_V1xD, 0x0ef10a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpscr"}, + {FPU_VFP_EXT_V1xD, 0x0ef80a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpexc"}, + {FPU_VFP_EXT_V1xD, 0x0ef90a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst\t@ Impl def"}, + {FPU_VFP_EXT_V1xD, 0x0efa0a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst2\t@ Impl def"}, + {FPU_VFP_EXT_V1, 0x0e000b10, 0x0ff00fff, "fmdlr%c\t%z2, %12-15r"}, + {FPU_VFP_EXT_V1, 0x0e100b10, 0x0ff00fff, "fmrdl%c\t%12-15r, %z2"}, + {FPU_VFP_EXT_V1, 0x0e200b10, 0x0ff00fff, "fmdhr%c\t%z2, %12-15r"}, + {FPU_VFP_EXT_V1, 0x0e300b10, 0x0ff00fff, "fmrdh%c\t%12-15r, %z2"}, {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0ff00fff, "fmxr%c\t<impl def 0x%16-19x>, %12-15r"}, - {FPU_VFP_EXT_V1, 0x0eb10b40, 0x0fff0ff0, "fnegd%c\t%1z, %0z"}, - {FPU_VFP_EXT_V1xD, 0x0eb10a40, 0x0fbf0fd0, "fnegs%c\t%1y, %0y"}, - {FPU_VFP_EXT_V1, 0x0e000b40, 0x0ff00ff0, "fnmacd%c\t%1z, %2z, %0z"}, - {FPU_VFP_EXT_V1xD, 0x0e000a40, 0x0fb00f50, "fnmacs%c\t%1y, %2y, %0y"}, - {FPU_VFP_EXT_V1, 0x0e100b40, 0x0ff00ff0, "fnmscd%c\t%1z, %2z, %0z"}, - {FPU_VFP_EXT_V1xD, 0x0e100a40, 0x0fb00f50, "fnmscs%c\t%1y, %2y, %0y"}, - {FPU_VFP_EXT_V1, 0x0e200b40, 0x0ff00ff0, "fnmuld%c\t%1z, %2z, %0z"}, - {FPU_VFP_EXT_V1xD, 0x0e200a40, 0x0fb00f50, "fnmuls%c\t%1y, %2y, %0y"}, - {FPU_VFP_EXT_V1, 0x0eb80bc0, 0x0fff0fd0, "fsitod%c\t%1z, %0y"}, - {FPU_VFP_EXT_V1xD, 0x0eb80ac0, 0x0fbf0fd0, "fsitos%c\t%1y, %0y"}, - {FPU_VFP_EXT_V1, 0x0eb10bc0, 0x0fff0ff0, "fsqrtd%c\t%1z, %0z"}, - {FPU_VFP_EXT_V1xD, 0x0eb10ac0, 0x0fbf0fd0, "fsqrts%c\t%1y, %0y"}, - {FPU_VFP_EXT_V1, 0x0d000b00, 0x0f700f00, "fstd%c\t%1z, %A"}, - {FPU_VFP_EXT_V1xD, 0x0c800b00, 0x0fd00f00, "fstmia%0?xd%c\t%16-19r%21'!, %3z"}, - {FPU_VFP_EXT_V1xD, 0x0d200b00, 0x0ff00f00, "fstmdb%0?xd%c\t%16-19r!, %3z"}, - {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "fsts%c\t%1y, %A"}, - {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "fstmias%c\t%16-19r%21'!, %3y"}, - {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "fstmdbs%c\t%16-19r!, %3y"}, - {FPU_VFP_EXT_V1, 0x0e300b40, 0x0ff00ff0, "fsubd%c\t%1z, %2z, %0z"}, - {FPU_VFP_EXT_V1xD, 0x0e300a40, 0x0fb00f50, "fsubs%c\t%1y, %2y, %0y"}, - {FPU_VFP_EXT_V1, 0x0ebc0b40, 0x0fbe0f70, "fto%16?sui%7'zd%c\t%1y, %0z"}, - {FPU_VFP_EXT_V1xD, 0x0ebc0a40, 0x0fbe0f50, "fto%16?sui%7'zs%c\t%1y, %0y"}, - {FPU_VFP_EXT_V1, 0x0eb80b40, 0x0fff0fd0, "fuitod%c\t%1z, %0y"}, - {FPU_VFP_EXT_V1xD, 0x0eb80a40, 0x0fbf0fd0, "fuitos%c\t%1y, %0y"}, + {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0ff00fff, "fmrx%c\t%12-15r, <impl def 0x%16-19x>"}, + {FPU_VFP_EXT_V1xD, 0x0e000a10, 0x0ff00f7f, "fmsr%c\t%y2, %12-15r"}, + {FPU_VFP_EXT_V1xD, 0x0e100a10, 0x0ff00f7f, "fmrs%c\t%12-15r, %y2"}, + {FPU_VFP_EXT_V1xD, 0x0eb50a40, 0x0fbf0f70, "fcmp%7'ezs%c\t%y1"}, + {FPU_VFP_EXT_V1, 0x0eb50b40, 0x0fbf0f70, "fcmp%7'ezd%c\t%z1"}, + {FPU_VFP_EXT_V1xD, 0x0eb00a40, 0x0fbf0fd0, "fcpys%c\t%y1, %y0"}, + {FPU_VFP_EXT_V1xD, 0x0eb00ac0, 0x0fbf0fd0, "fabss%c\t%y1, %y0"}, + {FPU_VFP_EXT_V1, 0x0eb00b40, 0x0fbf0fd0, "fcpyd%c\t%z1, %z0"}, + {FPU_VFP_EXT_V1, 0x0eb00bc0, 0x0fbf0fd0, "fabsd%c\t%z1, %z0"}, + {FPU_VFP_EXT_V1xD, 0x0eb10a40, 0x0fbf0fd0, "fnegs%c\t%y1, %y0"}, + {FPU_VFP_EXT_V1xD, 0x0eb10ac0, 0x0fbf0fd0, "fsqrts%c\t%y1, %y0"}, + {FPU_VFP_EXT_V1, 0x0eb10b40, 0x0fbf0fd0, "fnegd%c\t%z1, %z0"}, + {FPU_VFP_EXT_V1, 0x0eb10bc0, 0x0fbf0fd0, "fsqrtd%c\t%z1, %z0"}, + {FPU_VFP_EXT_V1, 0x0eb70ac0, 0x0fbf0fd0, "fcvtds%c\t%z1, %y0"}, + {FPU_VFP_EXT_V1, 0x0eb70bc0, 0x0fbf0fd0, "fcvtsd%c\t%y1, %z0"}, + {FPU_VFP_EXT_V1xD, 0x0eb80a40, 0x0fbf0fd0, "fuitos%c\t%y1, %y0"}, + {FPU_VFP_EXT_V1xD, 0x0eb80ac0, 0x0fbf0fd0, "fsitos%c\t%y1, %y0"}, + {FPU_VFP_EXT_V1, 0x0eb80b40, 0x0fbf0fd0, "fuitod%c\t%z1, %y0"}, + {FPU_VFP_EXT_V1, 0x0eb80bc0, 0x0fbf0fd0, "fsitod%c\t%z1, %y0"}, + {FPU_VFP_EXT_V1xD, 0x0eb40a40, 0x0fbf0f50, "fcmp%7'es%c\t%y1, %y0"}, + {FPU_VFP_EXT_V1, 0x0eb40b40, 0x0fbf0f50, "fcmp%7'ed%c\t%z1, %z0"}, + {FPU_VFP_EXT_V3, 0x0eba0a40, 0x0fbe0f50, "f%16?us%7?lhtos%c\t%y1, #%5,0-3k"}, + {FPU_VFP_EXT_V3, 0x0eba0b40, 0x0fbe0f50, "f%16?us%7?lhtod%c\t%z1, #%5,0-3k"}, + {FPU_VFP_EXT_V1xD, 0x0ebc0a40, 0x0fbe0f50, "fto%16?sui%7'zs%c\t%y1, %y0"}, + {FPU_VFP_EXT_V1, 0x0ebc0b40, 0x0fbe0f50, "fto%16?sui%7'zd%c\t%y1, %z0"}, + {FPU_VFP_EXT_V3, 0x0ebe0a40, 0x0fbe0f50, "fto%16?us%7?lhs%c\t%y1, #%5,0-3k"}, + {FPU_VFP_EXT_V3, 0x0ebe0b40, 0x0fbe0f50, "fto%16?us%7?lhd%c\t%z1, #%5,0-3k"}, + {FPU_VFP_EXT_V1, 0x0c500b10, 0x0fb00ff0, "fmrrd%c\t%12-15r, %16-19r, %z0"}, + {FPU_VFP_EXT_V3, 0x0eb00a00, 0x0fb00ff0, "fconsts%c\t%y1, #%16-19,0-3d"}, + {FPU_VFP_EXT_V3, 0x0eb00b00, 0x0fb00ff0, "fconstd%c\t%z1, #%16-19,0-3d"}, + {FPU_VFP_EXT_V2, 0x0c400a10, 0x0ff00fd0, "fmsrr%c\t%12-15r, %16-19r, %y4"}, + {FPU_VFP_EXT_V2, 0x0c400b10, 0x0ff00fd0, "fmdrr%c\t%z0, %12-15r, %16-19r"}, + {FPU_VFP_EXT_V2, 0x0c500a10, 0x0ff00fd0, "fmrrs%c\t%12-15r, %16-19r, %y4"}, + {FPU_VFP_EXT_V1xD, 0x0e000a00, 0x0fb00f50, "fmacs%c\t%y1, %y2, %y0"}, + {FPU_VFP_EXT_V1xD, 0x0e000a40, 0x0fb00f50, "fnmacs%c\t%y1, %y2, %y0"}, + {FPU_VFP_EXT_V1, 0x0e000b00, 0x0fb00f50, "fmacd%c\t%z1, %z2, %z0"}, + {FPU_VFP_EXT_V1, 0x0e000b40, 0x0fb00f50, "fnmacd%c\t%z1, %z2, %z0"}, + {FPU_VFP_EXT_V1xD, 0x0e100a00, 0x0fb00f50, "fmscs%c\t%y1, %y2, %y0"}, + {FPU_VFP_EXT_V1xD, 0x0e100a40, 0x0fb00f50, "fnmscs%c\t%y1, %y2, %y0"}, + {FPU_VFP_EXT_V1, 0x0e100b00, 0x0fb00f50, "fmscd%c\t%z1, %z2, %z0"}, + {FPU_VFP_EXT_V1, 0x0e100b40, 0x0fb00f50, "fnmscd%c\t%z1, %z2, %z0"}, + {FPU_VFP_EXT_V1xD, 0x0e200a00, 0x0fb00f50, "fmuls%c\t%y1, %y2, %y0"}, + {FPU_VFP_EXT_V1xD, 0x0e200a40, 0x0fb00f50, "fnmuls%c\t%y1, %y2, %y0"}, + {FPU_VFP_EXT_V1, 0x0e200b00, 0x0fb00f50, "fmuld%c\t%z1, %z2, %z0"}, + {FPU_VFP_EXT_V1, 0x0e200b40, 0x0fb00f50, "fnmuld%c\t%z1, %z2, %z0"}, + {FPU_VFP_EXT_V1xD, 0x0e300a00, 0x0fb00f50, "fadds%c\t%y1, %y2, %y0"}, + {FPU_VFP_EXT_V1xD, 0x0e300a40, 0x0fb00f50, "fsubs%c\t%y1, %y2, %y0"}, + {FPU_VFP_EXT_V1, 0x0e300b00, 0x0fb00f50, "faddd%c\t%z1, %z2, %z0"}, + {FPU_VFP_EXT_V1, 0x0e300b40, 0x0fb00f50, "fsubd%c\t%z1, %z2, %z0"}, + {FPU_VFP_EXT_V1xD, 0x0e800a00, 0x0fb00f50, "fdivs%c\t%y1, %y2, %y0"}, + {FPU_VFP_EXT_V1, 0x0e800b00, 0x0fb00f50, "fdivd%c\t%z1, %z2, %z0"}, + {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "fstmdbs%c\t%16-19r!, %y3"}, + {FPU_VFP_EXT_V1xD, 0x0d200b00, 0x0fb00f00, "fstmdb%0?xd%c\t%16-19r!, %z3"}, + {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "fldmdbs%c\t%16-19r!, %y3"}, + {FPU_VFP_EXT_V1xD, 0x0d300b00, 0x0fb00f00, "fldmdb%0?xd%c\t%16-19r!, %z3"}, + {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "fsts%c\t%y1, %A"}, + {FPU_VFP_EXT_V1, 0x0d000b00, 0x0f300f00, "fstd%c\t%z1, %A"}, + {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "flds%c\t%y1, %A"}, + {FPU_VFP_EXT_V1, 0x0d100b00, 0x0f300f00, "fldd%c\t%z1, %A"}, + {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "fstmias%c\t%16-19r%21'!, %y3"}, + {FPU_VFP_EXT_V1xD, 0x0c800b00, 0x0f900f00, "fstmia%0?xd%c\t%16-19r%21'!, %z3"}, + {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "fldmias%c\t%16-19r%21'!, %y3"}, + {FPU_VFP_EXT_V1xD, 0x0c900b00, 0x0f900f00, "fldmia%0?xd%c\t%16-19r%21'!, %z3"}, /* Cirrus coprocessor instructions. */ {ARM_CEXT_MAVERICK, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"}, @@ -381,9 +418,286 @@ static const struct opcode32 coprocessor_opcodes[] = {ARM_EXT_V5, 0xfe000000, 0xff000010, "cdp2\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"}, {ARM_EXT_V5, 0xfe000010, 0xff100010, "mcr2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, {ARM_EXT_V5, 0xfe100010, 0xff100010, "mrc2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, + {0, 0, 0, 0} }; +/* Neon opcode table: This does not encode the top byte -- that is + checked by the print_insn_neon routine, as it depends on whether we are + doing thumb32 or arm32 disassembly. */ + +/* print_insn_neon recognizes the following format control codes: + + %% % + + %A print v{st,ld}[1234] operands + %B print v{st,ld}[1234] any one operands + %C print v{st,ld}[1234] single->all operands + %D print scalar + %E print vmov, vmvn, vorr, vbic encoded constant + %F print vtbl,vtbx register list + + %<bitfield>r print as an ARM register + %<bitfield>d print the bitfield in decimal + %<bitfield>e print the 2^N - bitfield in decimal + %<bitfield>D print as a NEON D register + %<bitfield>Q print as a NEON Q register + %<bitfield>R print as a NEON D or Q register + %<bitfield>Sn print byte scaled width limited by n + %<bitfield>Tn print short scaled width limited by n + %<bitfield>Un print long scaled width limited by n + + %<bitfield>'c print specified char iff bitfield is all ones + %<bitfield>`c print specified char iff bitfield is all zeroes + %<bitfield>?ab... select from array of values in big endian order */ + +static const struct opcode32 neon_opcodes[] = +{ + /* Extract */ + {FPU_NEON_EXT_V1, 0xf2b00840, 0xffb00850, "vext.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"}, + {FPU_NEON_EXT_V1, 0xf2b00000, 0xffb00810, "vext.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"}, + + /* Move data element to all lanes */ + {FPU_NEON_EXT_V1, 0xf3b40c00, 0xffb70f90, "vdup.32\t%12-15,22R, %0-3,5D[%19d]"}, + {FPU_NEON_EXT_V1, 0xf3b20c00, 0xffb30f90, "vdup.16\t%12-15,22R, %0-3,5D[%18-19d]"}, + {FPU_NEON_EXT_V1, 0xf3b10c00, 0xffb10f90, "vdup.8\t%12-15,22R, %0-3,5D[%17-19d]"}, + + /* Table lookup */ + {FPU_NEON_EXT_V1, 0xf3b00800, 0xffb00c50, "vtbl.8\t%12-15,22D, %F, %0-3,5D"}, + {FPU_NEON_EXT_V1, 0xf3b00840, 0xffb00c50, "vtbx.8\t%12-15,22D, %F, %0-3,5D"}, + + /* Two registers, miscellaneous */ + {FPU_NEON_EXT_V1, 0xf2880a10, 0xfebf0fd0, "vmovl.%24?us8\t%12-15,22Q, %0-3,5D"}, + {FPU_NEON_EXT_V1, 0xf2900a10, 0xfebf0fd0, "vmovl.%24?us16\t%12-15,22Q, %0-3,5D"}, + {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfebf0fd0, "vmovl.%24?us32\t%12-15,22Q, %0-3,5D"}, + {FPU_NEON_EXT_V1, 0xf3b00500, 0xffbf0f90, "vcnt.8\t%12-15,22R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3b00580, 0xffbf0f90, "vmvn\t%12-15,22R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3b20000, 0xffbf0f90, "vswp\t%12-15,22R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3b20200, 0xffb30fd0, "vmovn.i%18-19S2\t%12-15,22D, %0-3,5Q"}, + {FPU_NEON_EXT_V1, 0xf3b20240, 0xffb30fd0, "vqmovun.s%18-19T2\t%12-15,22D, %0-3,5Q"}, + {FPU_NEON_EXT_V1, 0xf3b20280, 0xffb30fd0, "vqmovn.s%18-19T2\t%12-15,22D, %0-3,5Q"}, + {FPU_NEON_EXT_V1, 0xf3b202c0, 0xffb30fd0, "vqmovn.u%18-19T2\t%12-15,22D, %0-3,5Q"}, + {FPU_NEON_EXT_V1, 0xf3b20300, 0xffb30fd0, "vshll.i%18-19S2\t%12-15,22Q, %0-3,5D, #%18-19S2"}, + {FPU_NEON_EXT_V1, 0xf3bb0400, 0xffbf0e90, "vrecpe.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3bb0480, 0xffbf0e90, "vrsqrte.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3b00000, 0xffb30f90, "vrev64.%18-19S2\t%12-15,22R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3b00080, 0xffb30f90, "vrev32.%18-19S2\t%12-15,22R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3b00100, 0xffb30f90, "vrev16.%18-19S2\t%12-15,22R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3b00400, 0xffb30f90, "vcls.s%18-19S2\t%12-15,22R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3b00480, 0xffb30f90, "vclz.i%18-19S2\t%12-15,22R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3b00700, 0xffb30f90, "vqabs.s%18-19S2\t%12-15,22R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3b00780, 0xffb30f90, "vqneg.s%18-19S2\t%12-15,22R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3b20080, 0xffb30f90, "vtrn.%18-19S2\t%12-15,22R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3b20100, 0xffb30f90, "vuzp.%18-19S2\t%12-15,22R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3b20180, 0xffb30f90, "vzip.%18-19S2\t%12-15,22R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3b10000, 0xffb30b90, "vcgt.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"}, + {FPU_NEON_EXT_V1, 0xf3b10080, 0xffb30b90, "vcge.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"}, + {FPU_NEON_EXT_V1, 0xf3b10100, 0xffb30b90, "vceq.%10?fi%18-19S2\t%12-15,22R, %0-3,5R, #0"}, + {FPU_NEON_EXT_V1, 0xf3b10180, 0xffb30b90, "vcle.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"}, + {FPU_NEON_EXT_V1, 0xf3b10200, 0xffb30b90, "vclt.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"}, + {FPU_NEON_EXT_V1, 0xf3b10300, 0xffb30b90, "vabs.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3b10380, 0xffb30b90, "vneg.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3b00200, 0xffb30f10, "vpaddl.%7?us%18-19S2\t%12-15,22R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3b00600, 0xffb30f10, "vpadal.%7?us%18-19S2\t%12-15,22R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3b30600, 0xffb30e10, "vcvt.%7-8?usff%18-19Sa.%7-8?ffus%18-19Sa\t%12-15,22R, %0-3,5R"}, + + /* Three registers of the same length */ + {FPU_NEON_EXT_V1, 0xf2000110, 0xffb00f10, "vand\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2100110, 0xffb00f10, "vbic\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2200110, 0xffb00f10, "vorr\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2300110, 0xffb00f10, "vorn\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3000110, 0xffb00f10, "veor\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3100110, 0xffb00f10, "vbsl\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3200110, 0xffb00f10, "vbit\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3300110, 0xffb00f10, "vbif\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000d00, 0xffa00f10, "vadd.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000d10, 0xffa00f10, "vmla.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000e00, 0xffa00f10, "vceq.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000f00, 0xffa00f10, "vmax.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000f10, 0xffa00f10, "vrecps.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2200d00, 0xffa00f10, "vsub.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2200d10, 0xffa00f10, "vmls.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2200f00, 0xffa00f10, "vmin.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2200f10, 0xffa00f10, "vrsqrts.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3000d00, 0xffa00f10, "vpadd.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3000d10, 0xffa00f10, "vmul.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3000e00, 0xffa00f10, "vcge.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3000e10, 0xffa00f10, "vacge.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3000f00, 0xffa00f10, "vpmax.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3200d00, 0xffa00f10, "vabd.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3200e00, 0xffa00f10, "vcgt.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3200e10, 0xffa00f10, "vacgt.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3200f00, 0xffa00f10, "vpmin.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000800, 0xff800f10, "vadd.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000810, 0xff800f10, "vtst.%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000900, 0xff800f10, "vmla.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000b00, 0xff800f10, "vqdmulh.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000b10, 0xff800f10, "vpadd.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3000800, 0xff800f10, "vsub.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3000810, 0xff800f10, "vceq.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3000900, 0xff800f10, "vmls.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf3000b00, 0xff800f10, "vqrdmulh.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000000, 0xfe800f10, "vhadd.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000010, 0xfe800f10, "vqadd.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000100, 0xfe800f10, "vrhadd.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000200, 0xfe800f10, "vhsub.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000210, 0xfe800f10, "vqsub.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000300, 0xfe800f10, "vcgt.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000310, 0xfe800f10, "vcge.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000400, 0xfe800f10, "vshl.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000410, 0xfe800f10, "vqshl.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000500, 0xfe800f10, "vrshl.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000510, 0xfe800f10, "vqrshl.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000600, 0xfe800f10, "vmax.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000610, 0xfe800f10, "vmin.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000700, 0xfe800f10, "vabd.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000710, 0xfe800f10, "vaba.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000910, 0xfe800f10, "vmul.%24?pi%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000a00, 0xfe800f10, "vpmax.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {FPU_NEON_EXT_V1, 0xf2000a10, 0xfe800f10, "vpmin.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, + + /* One register and an immediate value */ + {FPU_NEON_EXT_V1, 0xf2800e10, 0xfeb80fb0, "vmov.i8\t%12-15,22R, %E"}, + {FPU_NEON_EXT_V1, 0xf2800e30, 0xfeb80fb0, "vmov.i64\t%12-15,22R, %E"}, + {FPU_NEON_EXT_V1, 0xf2800f10, 0xfeb80fb0, "vmov.f32\t%12-15,22R, %E"}, + {FPU_NEON_EXT_V1, 0xf2800810, 0xfeb80db0, "vmov.i16\t%12-15,22R, %E"}, + {FPU_NEON_EXT_V1, 0xf2800830, 0xfeb80db0, "vmvn.i16\t%12-15,22R, %E"}, + {FPU_NEON_EXT_V1, 0xf2800910, 0xfeb80db0, "vorr.i16\t%12-15,22R, %E"}, + {FPU_NEON_EXT_V1, 0xf2800930, 0xfeb80db0, "vbic.i16\t%12-15,22R, %E"}, + {FPU_NEON_EXT_V1, 0xf2800c10, 0xfeb80eb0, "vmov.i32\t%12-15,22R, %E"}, + {FPU_NEON_EXT_V1, 0xf2800c30, 0xfeb80eb0, "vmvn.i32\t%12-15,22R, %E"}, + {FPU_NEON_EXT_V1, 0xf2800110, 0xfeb809b0, "vorr.i32\t%12-15,22R, %E"}, + {FPU_NEON_EXT_V1, 0xf2800130, 0xfeb809b0, "vbic.i32\t%12-15,22R, %E"}, + {FPU_NEON_EXT_V1, 0xf2800010, 0xfeb808b0, "vmov.i32\t%12-15,22R, %E"}, + {FPU_NEON_EXT_V1, 0xf2800030, 0xfeb808b0, "vmvn.i32\t%12-15,22R, %E"}, + + /* Two registers and a shift amount */ + {FPU_NEON_EXT_V1, 0xf2880810, 0xffb80fd0, "vshrn.i16\t%12-15,22D, %0-3,5Q, #%16-18e"}, + {FPU_NEON_EXT_V1, 0xf2880850, 0xffb80fd0, "vrshrn.i16\t%12-15,22D, %0-3,5Q, #%16-18e"}, + {FPU_NEON_EXT_V1, 0xf2880810, 0xfeb80fd0, "vqshrun.s16\t%12-15,22D, %0-3,5Q, #%16-18e"}, + {FPU_NEON_EXT_V1, 0xf2880850, 0xfeb80fd0, "vqrshrun.s16\t%12-15,22D, %0-3,5Q, #%16-18e"}, + {FPU_NEON_EXT_V1, 0xf2880910, 0xfeb80fd0, "vqshrn.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"}, + {FPU_NEON_EXT_V1, 0xf2880950, 0xfeb80fd0, "vqrshrn.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"}, + {FPU_NEON_EXT_V1, 0xf2880a10, 0xfeb80fd0, "vshll.%24?us8\t%12-15,22D, %0-3,5Q, #%16-18d"}, + {FPU_NEON_EXT_V1, 0xf2900810, 0xffb00fd0, "vshrn.i32\t%12-15,22D, %0-3,5Q, #%16-19e"}, + {FPU_NEON_EXT_V1, 0xf2900850, 0xffb00fd0, "vrshrn.i32\t%12-15,22D, %0-3,5Q, #%16-19e"}, + {FPU_NEON_EXT_V1, 0xf2880510, 0xffb80f90, "vshl.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"}, + {FPU_NEON_EXT_V1, 0xf3880410, 0xffb80f90, "vsri.8\t%12-15,22R, %0-3,5R, #%16-18e"}, + {FPU_NEON_EXT_V1, 0xf3880510, 0xffb80f90, "vsli.8\t%12-15,22R, %0-3,5R, #%16-18d"}, + {FPU_NEON_EXT_V1, 0xf3880610, 0xffb80f90, "vqshlu.s8\t%12-15,22R, %0-3,5R, #%16-18d"}, + {FPU_NEON_EXT_V1, 0xf2900810, 0xfeb00fd0, "vqshrun.s32\t%12-15,22D, %0-3,5Q, #%16-19e"}, + {FPU_NEON_EXT_V1, 0xf2900850, 0xfeb00fd0, "vqrshrun.s32\t%12-15,22D, %0-3,5Q, #%16-19e"}, + {FPU_NEON_EXT_V1, 0xf2900910, 0xfeb00fd0, "vqshrn.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"}, + {FPU_NEON_EXT_V1, 0xf2900950, 0xfeb00fd0, "vqrshrn.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"}, + {FPU_NEON_EXT_V1, 0xf2900a10, 0xfeb00fd0, "vshll.%24?us16\t%12-15,22D, %0-3,5Q, #%16-19d"}, + {FPU_NEON_EXT_V1, 0xf2880010, 0xfeb80f90, "vshr.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"}, + {FPU_NEON_EXT_V1, 0xf2880110, 0xfeb80f90, "vsra.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"}, + {FPU_NEON_EXT_V1, 0xf2880210, 0xfeb80f90, "vrshr.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"}, + {FPU_NEON_EXT_V1, 0xf2880310, 0xfeb80f90, "vrsra.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"}, + {FPU_NEON_EXT_V1, 0xf2880710, 0xfeb80f90, "vqshl.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"}, + {FPU_NEON_EXT_V1, 0xf2a00810, 0xffa00fd0, "vshrn.i64\t%12-15,22D, %0-3,5Q, #%16-20e"}, + {FPU_NEON_EXT_V1, 0xf2a00850, 0xffa00fd0, "vrshrn.i64\t%12-15,22D, %0-3,5Q, #%16-20e"}, + {FPU_NEON_EXT_V1, 0xf2900510, 0xffb00f90, "vshl.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"}, + {FPU_NEON_EXT_V1, 0xf3900410, 0xffb00f90, "vsri.16\t%12-15,22R, %0-3,5R, #%16-19e"}, + {FPU_NEON_EXT_V1, 0xf3900510, 0xffb00f90, "vsli.16\t%12-15,22R, %0-3,5R, #%16-19d"}, + {FPU_NEON_EXT_V1, 0xf3900610, 0xffb00f90, "vqshlu.s16\t%12-15,22R, %0-3,5R, #%16-19d"}, + {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfea00fd0, "vshll.%24?us32\t%12-15,22D, %0-3,5Q, #%16-20d"}, + {FPU_NEON_EXT_V1, 0xf2900010, 0xfeb00f90, "vshr.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"}, + {FPU_NEON_EXT_V1, 0xf2900110, 0xfeb00f90, "vsra.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"}, + {FPU_NEON_EXT_V1, 0xf2900210, 0xfeb00f90, "vrshr.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"}, + {FPU_NEON_EXT_V1, 0xf2900310, 0xfeb00f90, "vrsra.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"}, + {FPU_NEON_EXT_V1, 0xf2900710, 0xfeb00f90, "vqshl.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"}, + {FPU_NEON_EXT_V1, 0xf2800810, 0xfec00fd0, "vqshrun.s64\t%12-15,22D, %0-3,5Q, #%16-20e"}, + {FPU_NEON_EXT_V1, 0xf2800850, 0xfec00fd0, "vqrshrun.s64\t%12-15,22D, %0-3,5Q, #%16-20e"}, + {FPU_NEON_EXT_V1, 0xf2800910, 0xfec00fd0, "vqshrn.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"}, + {FPU_NEON_EXT_V1, 0xf2800950, 0xfec00fd0, "vqrshrn.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"}, + {FPU_NEON_EXT_V1, 0xf2a00510, 0xffa00f90, "vshl.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"}, + {FPU_NEON_EXT_V1, 0xf3a00410, 0xffa00f90, "vsri.32\t%12-15,22R, %0-3,5R, #%16-20e"}, + {FPU_NEON_EXT_V1, 0xf3a00510, 0xffa00f90, "vsli.32\t%12-15,22R, %0-3,5R, #%16-20d"}, + {FPU_NEON_EXT_V1, 0xf3a00610, 0xffa00f90, "vqshlu.s32\t%12-15,22R, %0-3,5R, #%16-20d"}, + {FPU_NEON_EXT_V1, 0xf2a00010, 0xfea00f90, "vshr.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"}, + {FPU_NEON_EXT_V1, 0xf2a00110, 0xfea00f90, "vsra.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"}, + {FPU_NEON_EXT_V1, 0xf2a00210, 0xfea00f90, "vrshr.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"}, + {FPU_NEON_EXT_V1, 0xf2a00310, 0xfea00f90, "vrsra.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"}, + {FPU_NEON_EXT_V1, 0xf2a00710, 0xfea00f90, "vqshl.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"}, + {FPU_NEON_EXT_V1, 0xf2800590, 0xff800f90, "vshl.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"}, + {FPU_NEON_EXT_V1, 0xf3800490, 0xff800f90, "vsri.64\t%12-15,22R, %0-3,5R, #%16-21e"}, + {FPU_NEON_EXT_V1, 0xf3800590, 0xff800f90, "vsli.64\t%12-15,22R, %0-3,5R, #%16-21d"}, + {FPU_NEON_EXT_V1, 0xf3800690, 0xff800f90, "vqshlu.s64\t%12-15,22R, %0-3,5R, #%16-21d"}, + {FPU_NEON_EXT_V1, 0xf2800090, 0xfe800f90, "vshr.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"}, + {FPU_NEON_EXT_V1, 0xf2800190, 0xfe800f90, "vsra.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"}, + {FPU_NEON_EXT_V1, 0xf2800290, 0xfe800f90, "vrshr.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"}, + {FPU_NEON_EXT_V1, 0xf2800390, 0xfe800f90, "vrsra.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"}, + {FPU_NEON_EXT_V1, 0xf2800790, 0xfe800f90, "vqshl.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"}, + {FPU_NEON_EXT_V1, 0xf2a00e10, 0xfea00e90, "vcvt.%24,8?usff32.%24,8?ffus32\t%12-15,22R, %0-3,5R, #%16-20e"}, + + /* Three registers of different lengths */ + {FPU_NEON_EXT_V1, 0xf2800e00, 0xfea00f50, "vmull.p%20S0\t%12-15,22Q, %16-19,7D, %0-3,5D"}, + {FPU_NEON_EXT_V1, 0xf2800400, 0xff800f50, "vaddhn.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"}, + {FPU_NEON_EXT_V1, 0xf2800600, 0xff800f50, "vsubhn.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"}, + {FPU_NEON_EXT_V1, 0xf2800900, 0xff800f50, "vqdmlal.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"}, + {FPU_NEON_EXT_V1, 0xf2800b00, 0xff800f50, "vqdmlsl.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"}, + {FPU_NEON_EXT_V1, 0xf2800d00, 0xff800f50, "vqdmull.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"}, + {FPU_NEON_EXT_V1, 0xf3800400, 0xff800f50, "vraddhn.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"}, + {FPU_NEON_EXT_V1, 0xf3800600, 0xff800f50, "vrsubhn.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"}, + {FPU_NEON_EXT_V1, 0xf2800000, 0xfe800f50, "vaddl.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"}, + {FPU_NEON_EXT_V1, 0xf2800100, 0xfe800f50, "vaddw.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"}, + {FPU_NEON_EXT_V1, 0xf2800200, 0xfe800f50, "vsubl.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"}, + {FPU_NEON_EXT_V1, 0xf2800300, 0xfe800f50, "vsubw.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"}, + {FPU_NEON_EXT_V1, 0xf2800500, 0xfe800f50, "vabal.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"}, + {FPU_NEON_EXT_V1, 0xf2800700, 0xfe800f50, "vabdl.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"}, + {FPU_NEON_EXT_V1, 0xf2800800, 0xfe800f50, "vmlal.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"}, + {FPU_NEON_EXT_V1, 0xf2800a00, 0xfe800f50, "vmlsl.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"}, + {FPU_NEON_EXT_V1, 0xf2800c00, 0xfe800f50, "vmull.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"}, + + /* Two registers and a scalar */ + {FPU_NEON_EXT_V1, 0xf2800040, 0xff800f50, "vmla.i%20-21S6\t%12-15,22D, %16-19,7D, %D"}, + {FPU_NEON_EXT_V1, 0xf2800140, 0xff800f50, "vmla.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"}, + {FPU_NEON_EXT_V1, 0xf2800340, 0xff800f50, "vqdmlal.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"}, + {FPU_NEON_EXT_V1, 0xf2800440, 0xff800f50, "vmls.i%20-21S6\t%12-15,22D, %16-19,7D, %D"}, + {FPU_NEON_EXT_V1, 0xf2800540, 0xff800f50, "vmls.f%20-21S6\t%12-15,22D, %16-19,7D, %D"}, + {FPU_NEON_EXT_V1, 0xf2800740, 0xff800f50, "vqdmlsl.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"}, + {FPU_NEON_EXT_V1, 0xf2800840, 0xff800f50, "vmul.i%20-21S6\t%12-15,22D, %16-19,7D, %D"}, + {FPU_NEON_EXT_V1, 0xf2800940, 0xff800f50, "vmul.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"}, + {FPU_NEON_EXT_V1, 0xf2800b40, 0xff800f50, "vqdmull.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"}, + {FPU_NEON_EXT_V1, 0xf2800c40, 0xff800f50, "vqdmulh.s%20-21S6\t%12-15,22D, %16-19,7D, %D"}, + {FPU_NEON_EXT_V1, 0xf2800d40, 0xff800f50, "vqrdmulh.s%20-21S6\t%12-15,22D, %16-19,7D, %D"}, + {FPU_NEON_EXT_V1, 0xf3800040, 0xff800f50, "vmla.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"}, + {FPU_NEON_EXT_V1, 0xf3800140, 0xff800f50, "vmla.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"}, + {FPU_NEON_EXT_V1, 0xf3800440, 0xff800f50, "vmls.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"}, + {FPU_NEON_EXT_V1, 0xf3800540, 0xff800f50, "vmls.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"}, + {FPU_NEON_EXT_V1, 0xf3800840, 0xff800f50, "vmul.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"}, + {FPU_NEON_EXT_V1, 0xf3800940, 0xff800f50, "vmul.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"}, + {FPU_NEON_EXT_V1, 0xf3800c40, 0xff800f50, "vqdmulh.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"}, + {FPU_NEON_EXT_V1, 0xf3800d40, 0xff800f50, "vqrdmulh.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"}, + {FPU_NEON_EXT_V1, 0xf2800240, 0xfe800f50, "vmlal.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"}, + {FPU_NEON_EXT_V1, 0xf2800640, 0xfe800f50, "vmlsl.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"}, + {FPU_NEON_EXT_V1, 0xf2800a40, 0xfe800f50, "vmull.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"}, + + /* Element and structure load/store */ + {FPU_NEON_EXT_V1, 0xf4a00fc0, 0xffb00fc0, "vld4.32\t%C"}, + {FPU_NEON_EXT_V1, 0xf4a00c00, 0xffb00f00, "vld1.%6-7S2\t%C"}, + {FPU_NEON_EXT_V1, 0xf4a00d00, 0xffb00f00, "vld2.%6-7S2\t%C"}, + {FPU_NEON_EXT_V1, 0xf4a00e00, 0xffb00f00, "vld3.%6-7S2\t%C"}, + {FPU_NEON_EXT_V1, 0xf4a00f00, 0xffb00f00, "vld4.%6-7S2\t%C"}, + {FPU_NEON_EXT_V1, 0xf4000200, 0xff900f00, "v%21?ls%21?dt1.%6-7S3\t%A"}, + {FPU_NEON_EXT_V1, 0xf4000300, 0xff900f00, "v%21?ls%21?dt2.%6-7S2\t%A"}, + {FPU_NEON_EXT_V1, 0xf4000400, 0xff900f00, "v%21?ls%21?dt3.%6-7S2\t%A"}, + {FPU_NEON_EXT_V1, 0xf4000500, 0xff900f00, "v%21?ls%21?dt3.%6-7S2\t%A"}, + {FPU_NEON_EXT_V1, 0xf4000600, 0xff900f00, "v%21?ls%21?dt1.%6-7S3\t%A"}, + {FPU_NEON_EXT_V1, 0xf4000700, 0xff900f00, "v%21?ls%21?dt1.%6-7S3\t%A"}, + {FPU_NEON_EXT_V1, 0xf4000800, 0xff900f00, "v%21?ls%21?dt2.%6-7S2\t%A"}, + {FPU_NEON_EXT_V1, 0xf4000900, 0xff900f00, "v%21?ls%21?dt2.%6-7S2\t%A"}, + {FPU_NEON_EXT_V1, 0xf4000a00, 0xff900f00, "v%21?ls%21?dt1.%6-7S3\t%A"}, + {FPU_NEON_EXT_V1, 0xf4000000, 0xff900e00, "v%21?ls%21?dt4.%6-7S2\t%A"}, + {FPU_NEON_EXT_V1, 0xf4800000, 0xff900300, "v%21?ls%21?dt1.%10-11S2\t%B"}, + {FPU_NEON_EXT_V1, 0xf4800100, 0xff900300, "v%21?ls%21?dt2.%10-11S2\t%B"}, + {FPU_NEON_EXT_V1, 0xf4800200, 0xff900300, "v%21?ls%21?dt3.%10-11S2\t%B"}, + {FPU_NEON_EXT_V1, 0xf4800300, 0xff900300, "v%21?ls%21?dt4.%10-11S2\t%B"}, + + {0,0 ,0, 0} +}; + /* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb. All three are partially ordered: they must be searched linearly from the top to obtain a correct match. */ @@ -410,10 +724,10 @@ static const struct opcode32 coprocessor_opcodes[] = %<bitfield>W print the bitfield plus one in decimal %<bitfield>x print the bitfield in hex %<bitfield>X print the bitfield as 1 hex digit without leading "0x" - - %<bitnum>'c print specified char iff bit is one - %<bitnum>`c print specified char iff bit is zero - %<bitnum>?ab print a if bit is one else print b + + %<bitfield>'c print specified char iff bitfield is all ones + %<bitfield>`c print specified char iff bitfield is all zeroes + %<bitfield>?ab... select from array of values in big endian order %e print arm SMI operand (bits 0..7,8..19). %E print the LSB and WIDTH fields of a BFI or BFC instruction. @@ -844,9 +1158,9 @@ static const struct opcode16 thumb_opcodes[] = %<bitfield>r print bitfield as an ARM register %<bitfield>c print bitfield as a condition code - %<bitnum>'c print "c" iff bit is one - %<bitnum>`c print "c" iff bit is zero - %<bitnum>?ab print "a" if bit is one, else "b" + %<bitfield>'c print specified char iff bitfield is all ones + %<bitfield>`c print specified char iff bitfield is all zeroes + %<bitfield>?ab... select from array of values in big endian order With one exception at the bottom (done because BL and BLX(1) need to come dead last), this table was machine-sorted first in @@ -1149,6 +1463,43 @@ get_arm_regnames (int option, const char **setname, const char **setdescription, return 16; } +/* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?. + Returns pointer to following character of the format string and + fills in *VALUEP and *WIDTHP with the extracted value and number of + bits extracted. WIDTHP can be NULL. */ + +static const char * +arm_decode_bitfield (const char *ptr, unsigned long insn, + unsigned long *valuep, int *widthp) +{ + unsigned long value = 0; + int width = 0; + + do + { + int start, end; + int bits; + + for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++) + start = start * 10 + *ptr - '0'; + if (*ptr == '-') + for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++) + end = end * 10 + *ptr - '0'; + else + end = start; + bits = end - start; + if (bits < 0) + abort (); + value |= ((insn >> start) & ((2ul << bits) - 1)) << width; + width += bits + 1; + } + while (*ptr++ == ','); + *valuep = value; + if (widthp) + *widthp = width; + return ptr - 1; +} + static void arm_decode_shift (long given, fprintf_ftype func, void *stream) { @@ -1185,7 +1536,7 @@ arm_decode_shift (long given, fprintf_ftype func, void *stream) recognised coprocessor instruction. */ static bfd_boolean -print_insn_coprocessor (struct disassemble_info *info, long given, +print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given, bfd_boolean thumb) { const struct opcode32 *insn; @@ -1265,6 +1616,46 @@ print_insn_coprocessor (struct disassemble_info *info, long given, } break; + case 'B': + { + int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10); + int offset = (given >> 1) & 0x3f; + + if (offset == 1) + func (stream, "{d%d}", regno); + else if (regno + offset > 32) + func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1); + else + func (stream, "{d%d-d%d}", regno, regno + offset - 1); + } + break; + + case 'C': + { + int rn = (given >> 16) & 0xf; + int offset = (given & 0xff) * 4; + int add = (given >> 23) & 1; + + func (stream, "[%s", arm_regnames[rn]); + + if (offset) + { + if (!add) + offset = -offset; + func (stream, ", #%d", offset); + } + func (stream, "]"); + if (rn == 15) + { + func (stream, "\t; "); + /* FIXME: Unsure if info->bytes_per_chunk is the + right thing to use here. */ + info->print_address_func (offset + pc + + info->bytes_per_chunk * 2, info); + } + } + break; + case 'c': func (stream, "%s", arm_conditional [(given >> 28) & 0xf]); @@ -1360,206 +1751,158 @@ print_insn_coprocessor (struct disassemble_info *info, long given, case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { - int bitstart = *c++ - '0'; - int bitend = 0; - while (*c >= '0' && *c <= '9') - bitstart = (bitstart * 10) + *c++ - '0'; + int width; + unsigned long value; + + c = arm_decode_bitfield (c, given, &value, &width); switch (*c) { - case '-': - c++; - - while (*c >= '0' && *c <= '9') - bitend = (bitend * 10) + *c++ - '0'; - - if (!bitend) - abort (); - - switch (*c) - { - case 'r': - { - long reg; - - reg = given >> bitstart; - reg &= (2 << (bitend - bitstart)) - 1; + case 'r': + func (stream, "%s", arm_regnames[value]); + break; + case 'D': + func (stream, "d%ld", value); + break; + case 'Q': + if (value & 1) + func (stream, "<illegal reg q%ld.5>", value >> 1); + else + func (stream, "q%ld", value >> 1); + break; + case 'd': + func (stream, "%ld", value); + break; + case 'k': + { + int from = (given & (1 << 7)) ? 32 : 16; + func (stream, "%ld", from - value); + } + break; + + case 'f': + if (value > 7) + func (stream, "#%s", arm_fp_const[value & 7]); + else + func (stream, "f%ld", value); + break; - func (stream, "%s", arm_regnames[reg]); - } - break; - case 'd': - { - long reg; + case 'w': + if (width == 2) + func (stream, "%s", iwmmxt_wwnames[value]); + else + func (stream, "%s", iwmmxt_wwssnames[value]); + break; - reg = given >> bitstart; - reg &= (2 << (bitend - bitstart)) - 1; + case 'g': + func (stream, "%s", iwmmxt_regnames[value]); + break; + case 'G': + func (stream, "%s", iwmmxt_cregnames[value]); + break; + case '`': + c++; + if (value == 0) + func (stream, "%c", *c); + break; + case '\'': + c++; + if (value == ((1ul << width) - 1)) + func (stream, "%c", *c); + break; + case '?': + func (stream, "%c", c[(1 << width) - (int)value]); + c += 1 << width; + break; + default: + abort (); + } + break; - func (stream, "%ld", reg); - } - break; - case 'f': + case 'y': + case 'z': + { + int single = *c++ == 'y'; + int regno; + + switch (*c) + { + case '4': /* Sm pair */ + func (stream, "{"); + /* Fall through. */ + case '0': /* Sm, Dm */ + regno = given & 0x0000000f; + if (single) { - long reg; - - reg = given >> bitstart; - reg &= (2 << (bitend - bitstart)) - 1; - - if (reg > 7) - func (stream, "#%s", - arm_fp_const[reg & 7]); - else - func (stream, "f%ld", reg); + regno <<= 1; + regno += (given >> 5) & 1; } - break; + else + regno += ((given >> 5) & 1) << 4; + break; - case 'w': + case '1': /* Sd, Dd */ + regno = (given >> 12) & 0x0000000f; + if (single) { - long reg; - - if (bitstart != bitend) - { - reg = given >> bitstart; - reg &= (2 << (bitend - bitstart)) - 1; - if (bitend - bitstart == 1) - func (stream, "%s", iwmmxt_wwnames[reg]); - else - func (stream, "%s", iwmmxt_wwssnames[reg]); - } - else - { - reg = (((given >> 8) & 0x1) | - ((given >> 22) & 0x1)); - func (stream, "%s", iwmmxt_wwnames[reg]); - } + regno <<= 1; + regno += (given >> 22) & 1; } - break; + else + regno += ((given >> 22) & 1) << 4; + break; - case 'g': + case '2': /* Sn, Dn */ + regno = (given >> 16) & 0x0000000f; + if (single) { - long reg; - reg = given >> bitstart; - reg &= (2 << (bitend - bitstart)) - 1; - func (stream, "%s", iwmmxt_regnames[reg]); + regno <<= 1; + regno += (given >> 7) & 1; } - break; - - case 'G': + else + regno += ((given >> 7) & 1) << 4; + break; + + case '3': /* List */ + func (stream, "{"); + regno = (given >> 12) & 0x0000000f; + if (single) { - long reg; - reg = given >> bitstart; - reg &= (2 << (bitend - bitstart)) - 1; - func (stream, "%s", iwmmxt_cregnames[reg]); + regno <<= 1; + regno += (given >> 22) & 1; } - break; + else + regno += ((given >> 22) & 1) << 4; + break; + + default: + abort (); + } - default: - abort (); - } - break; + func (stream, "%c%d", single ? 's' : 'd', regno); - case 'y': - case 'z': + if (*c == '3') { - int single = *c == 'y'; - int regno; - - switch (bitstart) - { - case 4: /* Sm pair */ - func (stream, "{"); - /* Fall through. */ - case 0: /* Sm, Dm */ - regno = given & 0x0000000f; - if (single) - { - regno <<= 1; - regno += (given >> 5) & 1; - } - break; - - case 1: /* Sd, Dd */ - regno = (given >> 12) & 0x0000000f; - if (single) - { - regno <<= 1; - regno += (given >> 22) & 1; - } - break; - - case 2: /* Sn, Dn */ - regno = (given >> 16) & 0x0000000f; - if (single) - { - regno <<= 1; - regno += (given >> 7) & 1; - } - break; - - case 3: /* List */ - func (stream, "{"); - regno = (given >> 12) & 0x0000000f; - if (single) - { - regno <<= 1; - regno += (given >> 22) & 1; - } - break; - - - default: - abort (); - } - - func (stream, "%c%d", single ? 's' : 'd', regno); - - if (bitstart == 3) + int count = given & 0xff; + + if (single == 0) + count >>= 1; + + if (--count) { - int count = given & 0xff; - - if (single == 0) - count >>= 1; - - if (--count) - { - func (stream, "-%c%d", - single ? 's' : 'd', - regno + count); - } - - func (stream, "}"); + func (stream, "-%c%d", + single ? 's' : 'd', + regno + count); } - else if (bitstart == 4) - func (stream, ", %c%d}", single ? 's' : 'd', - regno + 1); - - break; + + func (stream, "}"); } - - break; - - case '`': - c++; - if ((given & (1 << bitstart)) == 0) - func (stream, "%c", *c); - break; - case '\'': - c++; - if ((given & (1 << bitstart)) != 0) - func (stream, "%c", *c); - break; - case '?': - ++c; - if ((given & (1 << bitstart)) != 0) - func (stream, "%c", *c++); - else - func (stream, "%c", *++c); - break; - default: - abort (); - } + else if (*c == '4') + func (stream, ", %c%d}", single ? 's' : 'd', + regno + 1); + } break; - + case 'L': switch (given & 0x00400100) { @@ -1712,6 +2055,458 @@ print_arm_address (bfd_vma pc, struct disassemble_info *info, long given) } } +/* Print one neon instruction on INFO->STREAM. + Return TRUE if the instuction matched, FALSE if this is not a + recognised neon instruction. */ + +static bfd_boolean +print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb) +{ + const struct opcode32 *insn; + void *stream = info->stream; + fprintf_ftype func = info->fprintf_func; + + if (thumb) + { + if ((given & 0xef000000) == 0xef000000) + { + /* move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */ + unsigned long bit28 = given & (1 << 28); + + given &= 0x00ffffff; + if (bit28) + given |= 0xf3000000; + else + given |= 0xf2000000; + } + else if ((given & 0xff000000) == 0xf9000000) + given ^= 0xf9000000 ^ 0xf4000000; + else + return FALSE; + } + + for (insn = neon_opcodes; insn->assembler; insn++) + { + if ((given & insn->mask) == insn->value) + { + const char *c; + + for (c = insn->assembler; *c; c++) + { + if (*c == '%') + { + switch (*++c) + { + case '%': + func (stream, "%%"); + break; + + case 'A': + { + static const unsigned char enc[16] = + { + 0x4, 0x14, /* st4 0,1 */ + 0x4, /* st1 2 */ + 0x4, /* st2 3 */ + 0x3, /* st3 4 */ + 0x13, /* st3 5 */ + 0x3, /* st1 6 */ + 0x1, /* st1 7 */ + 0x2, /* st2 8 */ + 0x12, /* st2 9 */ + 0x2, /* st1 10 */ + 0, 0, 0, 0, 0 + }; + int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4); + int rn = ((given >> 16) & 0xf); + int rm = ((given >> 0) & 0xf); + int align = ((given >> 4) & 0x3); + int type = ((given >> 8) & 0xf); + int n = enc[type] & 0xf; + int stride = (enc[type] >> 4) + 1; + int ix; + + func (stream, "{"); + if (stride > 1) + for (ix = 0; ix != n; ix++) + func (stream, "%sd%d", ix ? "," : "", rd + ix * stride); + else if (n == 1) + func (stream, "d%d", rd); + else + func (stream, "d%d-d%d", rd, rd + n - 1); + func (stream, "}, [%s", arm_regnames[rn]); + if (align) + func (stream, ", :%d", 32 << align); + func (stream, "]"); + if (rm == 0xd) + func (stream, "!"); + else if (rm != 0xf) + func (stream, ", %s", arm_regnames[rm]); + } + break; + + case 'B': + { + int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4); + int rn = ((given >> 16) & 0xf); + int rm = ((given >> 0) & 0xf); + int idx_align = ((given >> 4) & 0xf); + int align = 0; + int size = ((given >> 10) & 0x3); + int idx = idx_align >> (size + 1); + int length = ((given >> 8) & 3) + 1; + int stride = 1; + int i; + + if (length > 1 && size > 0) + stride = (idx_align & (1 << size)) ? 2 : 1; + + switch (length) + { + case 1: + { + int amask = (1 << size) - 1; + if ((idx_align & (1 << size)) != 0) + return FALSE; + if (size > 0) + { + if ((idx_align & amask) == amask) + align = 8 << size; + else if ((idx_align & amask) != 0) + return FALSE; + } + } + break; + + case 2: + if (size == 2 && (idx_align & 2) != 0) + return FALSE; + align = (idx_align & 1) ? 16 << size : 0; + break; + + case 3: + if ((size == 2 && (idx_align & 3) != 0) + || (idx_align & 1) != 0) + return FALSE; + break; + + case 4: + if (size == 2) + { + if ((idx_align & 3) == 3) + return FALSE; + align = (idx_align & 3) * 64; + } + else + align = (idx_align & 1) ? 32 << size : 0; + break; + + default: + abort (); + } + + func (stream, "{"); + for (i = 0; i < length; i++) + func (stream, "%sd%d[%d]", (i == 0) ? "" : ",", + rd + i * stride, idx); + func (stream, "}, [%s", arm_regnames[rn]); + if (align) + func (stream, ", :%d", align); + func (stream, "]"); + if (rm == 0xd) + func (stream, "!"); + else if (rm != 0xf) + func (stream, ", %s", arm_regnames[rm]); + } + break; + + case 'C': + { + int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4); + int rn = ((given >> 16) & 0xf); + int rm = ((given >> 0) & 0xf); + int align = ((given >> 4) & 0x1); + int size = ((given >> 6) & 0x3); + int type = ((given >> 8) & 0x3); + int n = type + 1; + int stride = ((given >> 5) & 0x1); + int ix; + + if (stride && (n == 1)) + n++; + else + stride++; + + func (stream, "{"); + if (stride > 1) + for (ix = 0; ix != n; ix++) + func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride); + else if (n == 1) + func (stream, "d%d[]", rd); + else + func (stream, "d%d[]-d%d[]", rd, rd + n - 1); + func (stream, "}, [%s", arm_regnames[rn]); + if (align) + { + int align = (8 * (type + 1)) << size; + if (type == 3) + align = (size > 1) ? align >> 1 : align; + if (type == 2 || (type == 0 && !size)) + func (stream, ", :<bad align %d>", align); + else + func (stream, ", :%d", align); + } + func (stream, "]"); + if (rm == 0xd) + func (stream, "!"); + else if (rm != 0xf) + func (stream, ", %s", arm_regnames[rm]); + } + break; + + case 'D': + { + int raw_reg = (given & 0xf) | ((given >> 1) & 0x10); + int size = (given >> 20) & 3; + int reg = raw_reg & ((4 << size) - 1); + int ix = raw_reg >> size >> 2; + + func (stream, "d%d[%d]", reg, ix); + } + break; + + case 'E': + /* Neon encoded constant for mov, mvn, vorr, vbic */ + { + int bits = 0; + int cmode = (given >> 8) & 0xf; + int op = (given >> 5) & 0x1; + unsigned long value = 0, hival = 0; + unsigned shift; + int size = 0; + int isfloat = 0; + + bits |= ((given >> 24) & 1) << 7; + bits |= ((given >> 16) & 7) << 4; + bits |= ((given >> 0) & 15) << 0; + + if (cmode < 8) + { + shift = (cmode >> 1) & 3; + value = (unsigned long)bits << (8 * shift); + size = 32; + } + else if (cmode < 12) + { + shift = (cmode >> 1) & 1; + value = (unsigned long)bits << (8 * shift); + size = 16; + } + else if (cmode < 14) + { + shift = (cmode & 1) + 1; + value = (unsigned long)bits << (8 * shift); + value |= (1ul << (8 * shift)) - 1; + size = 32; + } + else if (cmode == 14) + { + if (op) + { + /* bit replication into bytes */ + int ix; + unsigned long mask; + + value = 0; + hival = 0; + for (ix = 7; ix >= 0; ix--) + { + mask = ((bits >> ix) & 1) ? 0xff : 0; + if (ix <= 3) + value = (value << 8) | mask; + else + hival = (hival << 8) | mask; + } + size = 64; + } + else + { + /* byte replication */ + value = (unsigned long)bits; + size = 8; + } + } + else if (!op) + { + /* floating point encoding */ + int tmp; + + value = (unsigned long)(bits & 0x7f) << 19; + value |= (unsigned long)(bits & 0x80) << 24; + tmp = bits & 0x40 ? 0x3c : 0x40; + value |= (unsigned long)tmp << 24; + size = 32; + isfloat = 1; + } + else + { + func (stream, "<illegal constant %.8x:%x:%x>", + bits, cmode, op); + size = 32; + break; + } + switch (size) + { + case 8: + func (stream, "#%ld\t; 0x%.2lx", value, value); + break; + + case 16: + func (stream, "#%ld\t; 0x%.4lx", value, value); + break; + + case 32: + if (isfloat) + { + unsigned char valbytes[4]; + double fvalue; + + /* Do this a byte at a time so we don't have to + worry about the host's endianness. */ + valbytes[0] = value & 0xff; + valbytes[1] = (value >> 8) & 0xff; + valbytes[2] = (value >> 16) & 0xff; + valbytes[3] = (value >> 24) & 0xff; + + floatformat_to_double + (&floatformat_ieee_single_little, valbytes, + &fvalue); + + func (stream, "#%.7g\t; 0x%.8lx", fvalue, + value); + } + else + func (stream, "#%ld\t; 0x%.8lx", value, value); + break; + + case 64: + func (stream, "#0x%.8lx%.8lx", hival, value); + break; + + default: + abort (); + } + } + break; + + case 'F': + { + int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10); + int num = (given >> 8) & 0x3; + + if (!num) + func (stream, "{d%d}", regno); + else if (num + regno >= 32) + func (stream, "{d%d-<overflow reg d%d}", regno, regno + num); + else + func (stream, "{d%d-d%d}", regno, regno + num); + } + break; + + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + { + int width; + unsigned long value; + + c = arm_decode_bitfield (c, given, &value, &width); + + switch (*c) + { + case 'r': + func (stream, "%s", arm_regnames[value]); + break; + case 'd': + func (stream, "%ld", value); + break; + case 'e': + func (stream, "%ld", (1ul << width) - value); + break; + + case 'S': + case 'T': + case 'U': + /* various width encodings */ + { + int base = 8 << (*c - 'S'); /* 8,16 or 32 */ + int limit; + unsigned low, high; + + c++; + if (*c >= '0' && *c <= '9') + limit = *c - '0'; + else if (*c >= 'a' && *c <= 'f') + limit = *c - 'a' + 10; + else + abort (); + low = limit >> 2; + high = limit & 3; + + if (value < low || value > high) + func (stream, "<illegal width %d>", base << value); + else + func (stream, "%d", base << value); + } + break; + case 'R': + if (given & (1 << 6)) + goto Q; + /* FALLTHROUGH */ + case 'D': + func (stream, "d%ld", value); + break; + case 'Q': + Q: + if (value & 1) + func (stream, "<illegal reg q%ld.5>", value >> 1); + else + func (stream, "q%ld", value >> 1); + break; + + case '`': + c++; + if (value == 0) + func (stream, "%c", *c); + break; + case '\'': + c++; + if (value == ((1ul << width) - 1)) + func (stream, "%c", *c); + break; + case '?': + func (stream, "%c", c[(1 << width) - (int)value]); + c += 1 << width; + break; + default: + abort (); + } + break; + + default: + abort (); + } + } + } + else + func (stream, "%c", *c); + } + return TRUE; + } + } + return FALSE; +} + /* Print one ARM instruction from PC on INFO->STREAM. */ static void @@ -1721,7 +2516,10 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given) void *stream = info->stream; fprintf_ftype func = info->fprintf_func; - if (print_insn_coprocessor (info, given, FALSE)) + if (print_insn_coprocessor (pc, info, given, FALSE)) + return; + + if (print_insn_neon (info, given, FALSE)) return; for (insn = arm_opcodes; insn->assembler; insn++) @@ -1964,102 +2762,51 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given) case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { - int bitstart = *c++ - '0'; - int bitend = 0; - while (*c >= '0' && *c <= '9') - bitstart = (bitstart * 10) + *c++ - '0'; + int width; + unsigned long value; + c = arm_decode_bitfield (c, given, &value, &width); + switch (*c) { - case '-': - c++; - - while (*c >= '0' && *c <= '9') - bitend = (bitend * 10) + *c++ - '0'; - - if (!bitend) - abort (); - - switch (*c) - { - case 'r': - { - long reg; - - reg = given >> bitstart; - reg &= (2 << (bitend - bitstart)) - 1; - - func (stream, "%s", arm_regnames[reg]); - } - break; - case 'd': - { - long reg; - - reg = given >> bitstart; - reg &= (2 << (bitend - bitstart)) - 1; - - func (stream, "%ld", reg); - } - break; - case 'W': - { - long reg; - - reg = given >> bitstart; - reg &= (2 << (bitend - bitstart)) - 1; - - func (stream, "%ld", reg + 1); - } - break; - case 'x': - { - long reg; - - reg = given >> bitstart; - reg &= (2 << (bitend - bitstart)) - 1; - - func (stream, "0x%08lx", reg); - - /* Some SWI instructions have special - meanings. */ - if ((given & 0x0fffffff) == 0x0FF00000) - func (stream, "\t; IMB"); - else if ((given & 0x0fffffff) == 0x0FF00001) - func (stream, "\t; IMBRange"); - } - break; - case 'X': - { - long reg; - - reg = given >> bitstart; - reg &= (2 << (bitend - bitstart)) - 1; - - func (stream, "%01lx", reg & 0xf); - } - break; - default: - abort (); - } + case 'r': + func (stream, "%s", arm_regnames[value]); + break; + case 'd': + func (stream, "%ld", value); + break; + case 'b': + func (stream, "%ld", value * 8); + break; + case 'W': + func (stream, "%ld", value + 1); + break; + case 'x': + func (stream, "0x%08lx", value); + + /* Some SWI instructions have special + meanings. */ + if ((given & 0x0fffffff) == 0x0FF00000) + func (stream, "\t; IMB"); + else if ((given & 0x0fffffff) == 0x0FF00001) + func (stream, "\t; IMBRange"); + break; + case 'X': + func (stream, "%01lx", value & 0xf); break; - case '`': c++; - if ((given & (1 << bitstart)) == 0) + if (value == 0) func (stream, "%c", *c); break; case '\'': c++; - if ((given & (1 << bitstart)) != 0) + if (value == ((1ul << width) - 1)) func (stream, "%c", *c); break; case '?': - ++c; - if ((given & (1 << bitstart)) != 0) - func (stream, "%c", *c++); - else - func (stream, "%c", *++c); + func (stream, "%c", c[(1 << width) - (int)value]); + c += 1 << width; break; default: abort (); @@ -2373,7 +3120,10 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) void *stream = info->stream; fprintf_ftype func = info->fprintf_func; - if (print_insn_coprocessor (info, given, TRUE)) + if (print_insn_coprocessor (pc, info, given, TRUE)) + return; + + if (print_insn_neon (info, given, TRUE)) return; for (insn = thumb32_opcodes; insn->assembler; insn++) @@ -2752,30 +3502,15 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { - int bitstart = *c++ - '0'; - int bitend = 0; - unsigned int val; - while (*c >= '0' && *c <= '9') - bitstart = (bitstart * 10) + *c++ - '0'; - - if (*c == '-') - { - c++; - while (*c >= '0' && *c <= '9') - bitend = (bitend * 10) + *c++ - '0'; - if (!bitend) - abort (); - - val = given >> bitstart; - val &= (2 << (bitend - bitstart)) - 1; - } - else - val = (given >> bitstart) & 1; + int width; + unsigned long val; + c = arm_decode_bitfield (c, given, &val, &width); + switch (*c) { - case 'd': func (stream, "%u", val); break; - case 'W': func (stream, "%u", val * 4); break; + case 'd': func (stream, "%lu", val); break; + case 'W': func (stream, "%lu", val * 4); break; case 'r': func (stream, "%s", arm_regnames[val]); break; case 'c': @@ -2786,20 +3521,20 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) break; case '\'': - if (val) - func (stream, "%c", c[1]); c++; + if (val == ((1ul << width) - 1)) + func (stream, "%c", *c); break; case '`': - if (!val) - func (stream, "%c", c[1]); c++; + if (val == 0) + func (stream, "%c", *c); break; case '?': - func (stream, "%c", val ? c[1] : c[2]); - c += 2; + func (stream, "%c", c[(1 << width) - (int)val]); + c += 1 << width; break; default: diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index f73e883..4c8949f 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -1400,8 +1400,8 @@ static const struct dis386 grps[][8] = { }, /* GRP7 */ { - { "sgdtIQ", VMX_Fixup, 0, XX, XX }, - { "sidtIQ", PNI_Fixup, 0, XX, XX }, + { "sgdt{Q|IQ||}", VMX_Fixup, 0, XX, XX }, + { "sidt{Q|IQ||}", PNI_Fixup, 0, XX, XX }, { "lgdt{Q|Q||}", M, XX, XX }, { "lidt{Q|Q||}", SVME_Fixup, 0, XX, XX }, { "smswQ", Ev, XX, XX }, diff --git a/opcodes/m68k-dis.c b/opcodes/m68k-dis.c index 8fc70152..3094963 100644 --- a/opcodes/m68k-dis.c +++ b/opcodes/m68k-dis.c @@ -1308,12 +1308,14 @@ match_insn_m68k (bfd_vma memaddr, } else { + /* We must restore the print functions before trying to print the + error message. */ + info->fprintf_func = save_printer; + info->print_address_func = save_print_address; info->fprintf_func (info->stream, /* xgettext:c-format */ _("<internal error in opcode table: %s %s>\n"), best->name, best->args); - info->fprintf_func = save_printer; - info->print_address_func = save_print_address; return 2; } } diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c index 9a48d86..64a1fa1 100644 --- a/opcodes/mips-dis.c +++ b/opcodes/mips-dis.c @@ -51,12 +51,15 @@ struct mips_cp0sel_name const char * const name; }; -/* The mips16 register names. */ -static const char * const mips16_reg_names[] = +/* The mips16 registers. */ +static const unsigned int mips16_to_32_reg_map[] = { - "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3" + 16, 17, 2, 3, 4, 5, 6, 7 }; +#define mips16_reg_names(rn) mips_gpr_names[mips16_to_32_reg_map[rn]] + + static const char * const mips_gpr_names_numeric[32] = { "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", @@ -181,7 +184,28 @@ static const char * const mips_cp0_names_mips3264r2[32] = static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] = { { 4, 1, "c0_contextconfig" }, + { 0, 1, "c0_mvpcontrol" }, + { 0, 2, "c0_mvpconf0" }, + { 0, 3, "c0_mvpconf1" }, + { 1, 1, "c0_vpecontrol" }, + { 1, 2, "c0_vpeconf0" }, + { 1, 3, "c0_vpeconf1" }, + { 1, 4, "c0_yqmask" }, + { 1, 5, "c0_vpeschedule" }, + { 1, 6, "c0_vpeschefback" }, + { 2, 1, "c0_tcstatus" }, + { 2, 2, "c0_tcbind" }, + { 2, 3, "c0_tcrestart" }, + { 2, 4, "c0_tchalt" }, + { 2, 5, "c0_tccontext" }, + { 2, 6, "c0_tcschedule" }, + { 2, 7, "c0_tcschefback" }, { 5, 1, "c0_pagegrain" }, + { 6, 1, "c0_srsconf0" }, + { 6, 2, "c0_srsconf1" }, + { 6, 3, "c0_srsconf2" }, + { 6, 4, "c0_srsconf3" }, + { 6, 5, "c0_srsconf4" }, { 12, 1, "c0_intctl" }, { 12, 2, "c0_srsctl" }, { 12, 3, "c0_srsmap" }, @@ -370,26 +394,28 @@ const struct mips_arch_choice mips_arch_choices[] = MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95), page 1. */ { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32, - ISA_MIPS32 | INSN_MIPS16 | INSN_DSP, + ISA_MIPS32 | INSN_MIPS16 | INSN_SMARTMIPS, mips_cp0_names_mips3264, mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264), mips_hwr_names_numeric }, { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2, - ISA_MIPS32R2 | INSN_MIPS16 | INSN_DSP | INSN_MT, + (ISA_MIPS32R2 | INSN_MIPS16 | INSN_SMARTMIPS | INSN_DSP | INSN_MIPS3D + | INSN_MT), mips_cp0_names_mips3264r2, mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), mips_hwr_names_mips3264r2 }, /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */ { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64, - ISA_MIPS64 | INSN_MIPS16 | INSN_MIPS3D | INSN_MDMX | INSN_DSP, + ISA_MIPS64 | INSN_MIPS16 | INSN_MIPS3D | INSN_MDMX, mips_cp0_names_mips3264, mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264), mips_hwr_names_numeric }, { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2, - ISA_MIPS64R2 | INSN_MIPS16 | INSN_MIPS3D | INSN_MDMX | INSN_DSP, + (ISA_MIPS64R2 | INSN_MIPS16 | INSN_MIPS3D | INSN_DSP + | INSN_MT | INSN_MDMX), mips_cp0_names_mips3264r2, mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), mips_hwr_names_mips3264r2 }, @@ -688,7 +714,8 @@ static void print_insn_args (const char *d, register unsigned long int l, bfd_vma pc, - struct disassemble_info *info) + struct disassemble_info *info, + const struct mips_opcode *opp) { int op, delta; unsigned int lsb, msb, msbd; @@ -728,6 +755,26 @@ print_insn_args (const char *d, (*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1); break; + case '1': + (*info->fprintf_func) (info->stream, "0x%lx", + (l >> OP_SH_UDI1) & OP_MASK_UDI1); + break; + + case '2': + (*info->fprintf_func) (info->stream, "0x%lx", + (l >> OP_SH_UDI2) & OP_MASK_UDI2); + break; + + case '3': + (*info->fprintf_func) (info->stream, "0x%lx", + (l >> OP_SH_UDI3) & OP_MASK_UDI3); + break; + + case '4': + (*info->fprintf_func) (info->stream, "0x%lx", + (l >> OP_SH_UDI4) & OP_MASK_UDI4); + break; + case 'C': case 'H': msbd = (l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD; @@ -939,6 +986,10 @@ print_insn_args (const char *d, case 'a': info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff) | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)); + /* For gdb disassembler, force odd address on jalx. */ + if (info->flavour == bfd_target_unknown_flavour + && strcmp (opp->name, "jalx") == 0) + info->target |= 1; (*info->print_address_func) (info->target, info); break; @@ -1069,7 +1120,9 @@ print_insn_args (const char *d, break; case 'N': - (*info->fprintf_func) (info->stream, "$fcc%ld", + (*info->fprintf_func) (info->stream, + ((opp->pinfo & (FP_D | FP_S)) != 0 + ? "$fcc%ld" : "$cc%ld"), (l >> OP_SH_BCC) & OP_MASK_BCC); break; @@ -1247,7 +1300,7 @@ print_insn_mips (bfd_vma memaddr, if (d != NULL && *d != '\0') { (*info->fprintf_func) (info->stream, "\t"); - print_insn_args (d, word, memaddr, info); + print_insn_args (d, word, memaddr, info, op); } return INSNLEN; @@ -1283,27 +1336,27 @@ print_mips16_insn_arg (char type, case 'y': case 'w': (*info->fprintf_func) (info->stream, "%s", - mips16_reg_names[((l >> MIPS16OP_SH_RY) - & MIPS16OP_MASK_RY)]); + mips16_reg_names(((l >> MIPS16OP_SH_RY) + & MIPS16OP_MASK_RY))); break; case 'x': case 'v': (*info->fprintf_func) (info->stream, "%s", - mips16_reg_names[((l >> MIPS16OP_SH_RX) - & MIPS16OP_MASK_RX)]); + mips16_reg_names(((l >> MIPS16OP_SH_RX) + & MIPS16OP_MASK_RX))); break; case 'z': (*info->fprintf_func) (info->stream, "%s", - mips16_reg_names[((l >> MIPS16OP_SH_RZ) - & MIPS16OP_MASK_RZ)]); + mips16_reg_names(((l >> MIPS16OP_SH_RZ) + & MIPS16OP_MASK_RZ))); break; case 'Z': (*info->fprintf_func) (info->stream, "%s", - mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z) - & MIPS16OP_MASK_MOVE32Z)]); + mips16_reg_names(((l >> MIPS16OP_SH_MOVE32Z) + & MIPS16OP_MASK_MOVE32Z))); break; case '0': @@ -1585,15 +1638,26 @@ print_mips16_insn_arg (char type, } } info->target = (baseaddr & ~((1 << shift) - 1)) + immed; + if (pcrel && branch + && info->flavour == bfd_target_unknown_flavour) + /* For gdb disassembler, maintain odd address. */ + info->target |= 1; (*info->print_address_func) (info->target, info); } } break; case 'a': - if (! use_extend) - extend = 0; - l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2); + { + int jalx = l & 0x400; + + if (! use_extend) + extend = 0; + l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2); + if (!jalx && info->flavour == bfd_target_unknown_flavour) + /* For gdb disassembler, maintain odd address. */ + l |= 1; + } info->target = ((memaddr + 4) & ~(bfd_vma) 0x0fffffff) | l; (*info->print_address_func) (info->target, info); info->insn_type = dis_jsr; diff --git a/opcodes/mips-opc.c b/opcodes/mips-opc.c index 42da748..0270a8e 100644 --- a/opcodes/mips-opc.c +++ b/opcodes/mips-opc.c @@ -89,12 +89,15 @@ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, US #define I33 INSN_ISA32R2 #define I65 INSN_ISA64R2 -/* MIPS64 MIPS-3D ASE support. */ +/* MIPS16 ASE support. */ #define I16 INSN_MIPS16 /* MIPS64 MIPS-3D ASE support. */ #define M3D INSN_MIPS3D +/* MIPS32 SmartMIPS ASE support. */ +#define SMT INSN_SMARTMIPS + /* MIPS64 MDMX ASE support. */ #define MX INSN_MDMX @@ -125,29 +128,29 @@ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, US of original HI and LO. $ac1, $ac2 and $ac3 are new registers, and have the same structure as $ac0 (HI + LO). For DSP instructions that write or read accumulators (that may be $ac0), we add WR_a (WR_HILO) or RD_a - (RD_HILO) attritubes, such that HILO dependences are maintained + (RD_HILO) attributes, such that HILO dependencies are maintained conservatively. 2. For some mul. instructions that use integer registers as destinations - but destroy HI+LO as side-effect, we add WR_HILO to their attritubes. + but destroy HI+LO as side-effect, we add WR_HILO to their attributes. 3. MIPS DSP ASE includes a new DSP control register, which has 6 fields (ccond, outflag, EFI, c, scount, pos). Many DSP instructions read or write certain fields of the DSP control register. For simplicity, we decide not - to track dependences of these fields. + to track dependencies of these fields. However, "bposge32" is a branch instruction that depends on the "pos" field. In order to make sure that GAS does not reorder DSP instructions that writes the "pos" field and "bposge32", we add DSP_VOLA (INSN_TRAP) - attritube to those instructions that write the "pos" field. */ + attribute to those instructions that write the "pos" field. */ #define WR_a WR_HILO /* Write dsp accumulators (reuse WR_HILO) */ #define RD_a RD_HILO /* Read dsp accumulators (reuse RD_HILO) */ #define MOD_a WR_a|RD_a #define DSP_VOLA INSN_TRAP -#define D32 (INSN_DSP) +#define D32 INSN_DSP /* MIPS MT ASE support. */ -#define MT32 (INSN_MT) +#define MT32 INSN_MT /* The order of overloaded instructions matters. Label arguments and register arguments look the same. Instructions that can have either @@ -187,7 +190,7 @@ const struct mips_opcode mips_builtin_opcodes[] = {"abs", "d,v", 0, (int) M_ABS, INSN_MACRO, 0, I1 }, {"abs.s", "D,V", 0x46000005, 0xffff003f, WR_D|RD_S|FP_S, 0, I1 }, {"abs.d", "D,V", 0x46200005, 0xffff003f, WR_D|RD_S|FP_D, 0, I1 }, -{"abs.ps", "D,V", 0x46c00005, 0xffff003f, WR_D|RD_S|FP_D, 0, I5 }, +{"abs.ps", "D,V", 0x46c00005, 0xffff003f, WR_D|RD_S|FP_D, 0, I5|I33 }, {"add", "d,v,t", 0x00000020, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I1 }, {"add", "t,r,I", 0, (int) M_ADD_I, INSN_MACRO, 0, I1 }, {"add.s", "D,V,T", 0x46000000, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, 0, I1 }, @@ -196,7 +199,7 @@ const struct mips_opcode mips_builtin_opcodes[] = {"add.ob", "D,S,T", 0x4ac0000b, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, {"add.ob", "D,S,T[e]", 0x4800000b, 0xfe20003f, WR_D|RD_S|RD_T, 0, N54 }, {"add.ob", "D,S,k", 0x4bc0000b, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"add.ps", "D,V,T", 0x46c00000, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I5 }, +{"add.ps", "D,V,T", 0x46c00000, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I5|I33 }, {"add.qh", "X,Y,Q", 0x7820000b, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, {"adda.ob", "Y,Q", 0x78000037, 0xfc2007ff, RD_S|RD_T|FP_D, WR_MACC, MX|SB1 }, {"adda.qh", "Y,Q", 0x78200037, 0xfc2007ff, RD_S|RD_T|FP_D, WR_MACC, MX }, @@ -210,7 +213,7 @@ const struct mips_opcode mips_builtin_opcodes[] = {"alni.ob", "X,Y,Z,O", 0x78000018, 0xff00003f, WR_D|RD_S|RD_T|FP_D, 0, MX|SB1 }, {"alni.ob", "D,S,T,%", 0x48000018, 0xff00003f, WR_D|RD_S|RD_T, 0, N54 }, {"alni.qh", "X,Y,Z,O", 0x7800001a, 0xff00003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"alnv.ps", "D,V,T,s", 0x4c00001e, 0xfc00003f, WR_D|RD_S|RD_T|FP_D, 0, I5 }, +{"alnv.ps", "D,V,T,s", 0x4c00001e, 0xfc00003f, WR_D|RD_S|RD_T|FP_D, 0, I5|I33 }, {"alnv.ob", "X,Y,Z,s", 0x78000019, 0xfc00003f, WR_D|RD_S|RD_T|RD_s|FP_D, 0, MX|SB1 }, {"alnv.qh", "X,Y,Z,s", 0x7800001b, 0xfc00003f, WR_D|RD_S|RD_T|RD_s|FP_D, 0, MX }, {"and", "d,v,t", 0x00000024, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I1 }, @@ -237,10 +240,7 @@ const struct mips_opcode mips_builtin_opcodes[] = {"bc1tl", "p", 0x45030000, 0xffff0000, CBL|RD_CC|FP_S, 0, I2|T3 }, {"bc1tl", "N,p", 0x45030000, 0xffe30000, CBL|RD_CC|FP_S, 0, I4|I32 }, /* bc2* are at the bottom of the table. */ -{"bc3f", "p", 0x4d000000, 0xffff0000, CBD|RD_CC, 0, I1 }, -{"bc3fl", "p", 0x4d020000, 0xffff0000, CBL|RD_CC, 0, I2|T3 }, -{"bc3t", "p", 0x4d010000, 0xffff0000, CBD|RD_CC, 0, I1 }, -{"bc3tl", "p", 0x4d030000, 0xffff0000, CBL|RD_CC, 0, I2|T3 }, +/* bc3* are at the bottom of the table. */ {"beqz", "s,p", 0x10000000, 0xfc1f0000, CBD|RD_s, 0, I1 }, {"beqzl", "s,p", 0x50000000, 0xfc1f0000, CBL|RD_s, 0, I2|T3 }, {"beq", "s,t,p", 0x10000000, 0xfc000000, CBD|RD_s|RD_t, 0, I1 }, @@ -304,14 +304,14 @@ const struct mips_opcode mips_builtin_opcodes[] = {"c.f.d", "M,S,T", 0x46200030, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4|I32 }, {"c.f.s", "S,T", 0x46000030, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, {"c.f.s", "M,S,T", 0x46000030, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4|I32 }, -{"c.f.ps", "S,T", 0x46c00030, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, -{"c.f.ps", "M,S,T", 0x46c00030, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, +{"c.f.ps", "S,T", 0x46c00030, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, +{"c.f.ps", "M,S,T", 0x46c00030, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, {"c.un.d", "S,T", 0x46200031, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, {"c.un.d", "M,S,T", 0x46200031, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4|I32 }, {"c.un.s", "S,T", 0x46000031, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, {"c.un.s", "M,S,T", 0x46000031, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4|I32 }, -{"c.un.ps", "S,T", 0x46c00031, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, -{"c.un.ps", "M,S,T", 0x46c00031, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, +{"c.un.ps", "S,T", 0x46c00031, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, +{"c.un.ps", "M,S,T", 0x46c00031, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, {"c.eq.d", "S,T", 0x46200032, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, {"c.eq.d", "M,S,T", 0x46200032, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4|I32 }, {"c.eq.s", "S,T", 0x46000032, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, @@ -320,63 +320,63 @@ const struct mips_opcode mips_builtin_opcodes[] = {"c.eq.ob", "S,T", 0x4ac00001, 0xffe007ff, WR_CC|RD_S|RD_T, 0, N54 }, {"c.eq.ob", "S,T[e]", 0x48000001, 0xfe2007ff, WR_CC|RD_S|RD_T, 0, N54 }, {"c.eq.ob", "S,k", 0x4bc00001, 0xffe007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"c.eq.ps", "S,T", 0x46c00032, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, -{"c.eq.ps", "M,S,T", 0x46c00032, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, +{"c.eq.ps", "S,T", 0x46c00032, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, +{"c.eq.ps", "M,S,T", 0x46c00032, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, {"c.eq.qh", "Y,Q", 0x78200001, 0xfc2007ff, WR_CC|RD_S|RD_T|FP_D, 0, MX }, {"c.ueq.d", "S,T", 0x46200033, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, {"c.ueq.d", "M,S,T", 0x46200033, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4|I32 }, {"c.ueq.s", "S,T", 0x46000033, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, {"c.ueq.s", "M,S,T", 0x46000033, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4|I32 }, -{"c.ueq.ps","S,T", 0x46c00033, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, -{"c.ueq.ps","M,S,T", 0x46c00033, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, +{"c.ueq.ps","S,T", 0x46c00033, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, +{"c.ueq.ps","M,S,T", 0x46c00033, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, {"c.olt.d", "S,T", 0x46200034, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, {"c.olt.d", "M,S,T", 0x46200034, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4|I32 }, {"c.olt.s", "S,T", 0x46000034, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, {"c.olt.s", "M,S,T", 0x46000034, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4|I32 }, -{"c.olt.ps","S,T", 0x46c00034, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, -{"c.olt.ps","M,S,T", 0x46c00034, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, +{"c.olt.ps","S,T", 0x46c00034, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, +{"c.olt.ps","M,S,T", 0x46c00034, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, {"c.ult.d", "S,T", 0x46200035, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, {"c.ult.d", "M,S,T", 0x46200035, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4|I32 }, {"c.ult.s", "S,T", 0x46000035, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, {"c.ult.s", "M,S,T", 0x46000035, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4|I32 }, -{"c.ult.ps","S,T", 0x46c00035, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, -{"c.ult.ps","M,S,T", 0x46c00035, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, +{"c.ult.ps","S,T", 0x46c00035, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, +{"c.ult.ps","M,S,T", 0x46c00035, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, {"c.ole.d", "S,T", 0x46200036, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, {"c.ole.d", "M,S,T", 0x46200036, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4|I32 }, {"c.ole.s", "S,T", 0x46000036, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, {"c.ole.s", "M,S,T", 0x46000036, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4|I32 }, -{"c.ole.ps","S,T", 0x46c00036, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, -{"c.ole.ps","M,S,T", 0x46c00036, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, +{"c.ole.ps","S,T", 0x46c00036, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, +{"c.ole.ps","M,S,T", 0x46c00036, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, {"c.ule.d", "S,T", 0x46200037, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, {"c.ule.d", "M,S,T", 0x46200037, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4|I32 }, {"c.ule.s", "S,T", 0x46000037, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, {"c.ule.s", "M,S,T", 0x46000037, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4|I32 }, -{"c.ule.ps","S,T", 0x46c00037, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, -{"c.ule.ps","M,S,T", 0x46c00037, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, +{"c.ule.ps","S,T", 0x46c00037, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, +{"c.ule.ps","M,S,T", 0x46c00037, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, {"c.sf.d", "S,T", 0x46200038, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, {"c.sf.d", "M,S,T", 0x46200038, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4|I32 }, {"c.sf.s", "S,T", 0x46000038, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, {"c.sf.s", "M,S,T", 0x46000038, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4|I32 }, -{"c.sf.ps", "S,T", 0x46c00038, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, -{"c.sf.ps", "M,S,T", 0x46c00038, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, +{"c.sf.ps", "S,T", 0x46c00038, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, +{"c.sf.ps", "M,S,T", 0x46c00038, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, {"c.ngle.d","S,T", 0x46200039, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, {"c.ngle.d","M,S,T", 0x46200039, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4|I32 }, {"c.ngle.s","S,T", 0x46000039, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, {"c.ngle.s","M,S,T", 0x46000039, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4|I32 }, -{"c.ngle.ps","S,T", 0x46c00039, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, -{"c.ngle.ps","M,S,T", 0x46c00039, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, +{"c.ngle.ps","S,T", 0x46c00039, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, +{"c.ngle.ps","M,S,T", 0x46c00039, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, {"c.seq.d", "S,T", 0x4620003a, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, {"c.seq.d", "M,S,T", 0x4620003a, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4|I32 }, {"c.seq.s", "S,T", 0x4600003a, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, {"c.seq.s", "M,S,T", 0x4600003a, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4|I32 }, -{"c.seq.ps","S,T", 0x46c0003a, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, -{"c.seq.ps","M,S,T", 0x46c0003a, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, +{"c.seq.ps","S,T", 0x46c0003a, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, +{"c.seq.ps","M,S,T", 0x46c0003a, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, {"c.ngl.d", "S,T", 0x4620003b, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, {"c.ngl.d", "M,S,T", 0x4620003b, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4|I32 }, {"c.ngl.s", "S,T", 0x4600003b, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, {"c.ngl.s", "M,S,T", 0x4600003b, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4|I32 }, -{"c.ngl.ps","S,T", 0x46c0003b, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, -{"c.ngl.ps","M,S,T", 0x46c0003b, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, +{"c.ngl.ps","S,T", 0x46c0003b, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, +{"c.ngl.ps","M,S,T", 0x46c0003b, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, {"c.lt.d", "S,T", 0x4620003c, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, {"c.lt.d", "M,S,T", 0x4620003c, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4|I32 }, {"c.lt.s", "S,T", 0x4600003c, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, @@ -385,15 +385,15 @@ const struct mips_opcode mips_builtin_opcodes[] = {"c.lt.ob", "S,T", 0x4ac00004, 0xffe007ff, WR_CC|RD_S|RD_T, 0, N54 }, {"c.lt.ob", "S,T[e]", 0x48000004, 0xfe2007ff, WR_CC|RD_S|RD_T, 0, N54 }, {"c.lt.ob", "S,k", 0x4bc00004, 0xffe007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"c.lt.ps", "S,T", 0x46c0003c, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, -{"c.lt.ps", "M,S,T", 0x46c0003c, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, +{"c.lt.ps", "S,T", 0x46c0003c, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, +{"c.lt.ps", "M,S,T", 0x46c0003c, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, {"c.lt.qh", "Y,Q", 0x78200004, 0xfc2007ff, WR_CC|RD_S|RD_T|FP_D, 0, MX }, {"c.nge.d", "S,T", 0x4620003d, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, {"c.nge.d", "M,S,T", 0x4620003d, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4|I32 }, {"c.nge.s", "S,T", 0x4600003d, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, {"c.nge.s", "M,S,T", 0x4600003d, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4|I32 }, -{"c.nge.ps","S,T", 0x46c0003d, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, -{"c.nge.ps","M,S,T", 0x46c0003d, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, +{"c.nge.ps","S,T", 0x46c0003d, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, +{"c.nge.ps","M,S,T", 0x46c0003d, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, {"c.le.d", "S,T", 0x4620003e, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, {"c.le.d", "M,S,T", 0x4620003e, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4|I32 }, {"c.le.s", "S,T", 0x4600003e, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, @@ -402,15 +402,15 @@ const struct mips_opcode mips_builtin_opcodes[] = {"c.le.ob", "S,T", 0x4ac00005, 0xffe007ff, WR_CC|RD_S|RD_T, 0, N54 }, {"c.le.ob", "S,T[e]", 0x48000005, 0xfe2007ff, WR_CC|RD_S|RD_T, 0, N54 }, {"c.le.ob", "S,k", 0x4bc00005, 0xffe007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"c.le.ps", "S,T", 0x46c0003e, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, -{"c.le.ps", "M,S,T", 0x46c0003e, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, +{"c.le.ps", "S,T", 0x46c0003e, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, +{"c.le.ps", "M,S,T", 0x46c0003e, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, {"c.le.qh", "Y,Q", 0x78200005, 0xfc2007ff, WR_CC|RD_S|RD_T|FP_D, 0, MX }, {"c.ngt.d", "S,T", 0x4620003f, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, {"c.ngt.d", "M,S,T", 0x4620003f, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4|I32 }, {"c.ngt.s", "S,T", 0x4600003f, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, {"c.ngt.s", "M,S,T", 0x4600003f, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4|I32 }, -{"c.ngt.ps","S,T", 0x46c0003f, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, -{"c.ngt.ps","M,S,T", 0x46c0003f, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5 }, +{"c.ngt.ps","S,T", 0x46c0003f, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, +{"c.ngt.ps","M,S,T", 0x46c0003f, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5|I33 }, {"cabs.eq.d", "M,S,T", 0x46200072, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, {"cabs.eq.ps", "M,S,T", 0x46c00072, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, {"cabs.eq.s", "M,S,T", 0x46000072, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, M3D }, @@ -459,7 +459,13 @@ const struct mips_opcode mips_builtin_opcodes[] = {"cabs.un.d", "M,S,T", 0x46200071, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, {"cabs.un.ps", "M,S,T", 0x46c00071, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, {"cabs.un.s", "M,S,T", 0x46000071, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, M3D }, +/* CW4010 instructions which are aliases for the cache instruction. */ +{"flushi", "", 0xbc010000, 0xffffffff, 0, 0, L1 }, +{"flushd", "", 0xbc020000, 0xffffffff, 0, 0, L1 }, +{"flushid", "", 0xbc030000, 0xffffffff, 0, 0, L1 }, +{"wb", "o(b)", 0xbc040000, 0xfc1f0000, SM|RD_b, 0, L1 }, {"cache", "k,o(b)", 0xbc000000, 0xfc000000, RD_b, 0, I3|I32|T3}, +{"cache", "k,A(b)", 0, (int) M_CACHE_AB, INSN_MACRO, 0, I3|I32|T3}, {"ceil.l.d", "D,S", 0x4620000a, 0xffff003f, WR_D|RD_S|FP_D, 0, I3|I33 }, {"ceil.l.s", "D,S", 0x4600000a, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I3|I33 }, {"ceil.w.d", "D,S", 0x4620000e, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I2 }, @@ -468,7 +474,7 @@ const struct mips_opcode mips_builtin_opcodes[] = {"cfc1", "t,G", 0x44400000, 0xffe007ff, LCD|WR_t|RD_C1|FP_S, 0, I1 }, {"cfc1", "t,S", 0x44400000, 0xffe007ff, LCD|WR_t|RD_C1|FP_S, 0, I1 }, /* cfc2 is at the bottom of the table. */ -{"cfc3", "t,G", 0x4c400000, 0xffe007ff, LCD|WR_t|RD_C3, 0, I1 }, +/* cfc3 is at the bottom of the table. */ {"cftc1", "d,E", 0x41000023, 0xffe007ff, TRAP|LCD|WR_d|RD_C1|FP_S, 0, MT32 }, {"cftc1", "d,T", 0x41000023, 0xffe007ff, TRAP|LCD|WR_d|RD_C1|FP_S, 0, MT32 }, {"cftc2", "d,E", 0x41000025, 0xffe007ff, TRAP|LCD|WR_d|RD_C2, 0, MT32 }, @@ -478,7 +484,7 @@ const struct mips_opcode mips_builtin_opcodes[] = {"ctc1", "t,G", 0x44c00000, 0xffe007ff, COD|RD_t|WR_CC|FP_S, 0, I1 }, {"ctc1", "t,S", 0x44c00000, 0xffe007ff, COD|RD_t|WR_CC|FP_S, 0, I1 }, /* ctc2 is at the bottom of the table. */ -{"ctc3", "t,G", 0x4cc00000, 0xffe007ff, COD|RD_t|WR_CC, 0, I1 }, +/* ctc3 is at the bottom of the table. */ {"cttc1", "t,g", 0x41800023, 0xffe007ff, TRAP|COD|RD_t|WR_CC|FP_S, 0, MT32 }, {"cttc1", "t,S", 0x41800023, 0xffe007ff, TRAP|COD|RD_t|WR_CC|FP_S, 0, MT32 }, {"cttc2", "t,g", 0x41800025, 0xffe007ff, TRAP|COD|RD_t|WR_CC, 0, MT32 }, @@ -486,16 +492,16 @@ const struct mips_opcode mips_builtin_opcodes[] = {"cvt.d.s", "D,S", 0x46000021, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I1 }, {"cvt.d.w", "D,S", 0x46800021, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I1 }, {"cvt.l.d", "D,S", 0x46200025, 0xffff003f, WR_D|RD_S|FP_D, 0, I3|I33 }, -{"cvt.l.s", "D,S", 0x46000025, 0xffff003f, WR_D|RD_S|FP_S|FP_S, 0, I3|I33 }, -{"cvt.s.l", "D,S", 0x46a00020, 0xffff003f, WR_D|RD_S|FP_S|FP_S, 0, I3|I33 }, +{"cvt.l.s", "D,S", 0x46000025, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I3|I33 }, +{"cvt.s.l", "D,S", 0x46a00020, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I3|I33 }, {"cvt.s.d", "D,S", 0x46200020, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I1 }, {"cvt.s.w", "D,S", 0x46800020, 0xffff003f, WR_D|RD_S|FP_S, 0, I1 }, -{"cvt.s.pl","D,S", 0x46c00028, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I5 }, -{"cvt.s.pu","D,S", 0x46c00020, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I5 }, +{"cvt.s.pl","D,S", 0x46c00028, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I5|I33 }, +{"cvt.s.pu","D,S", 0x46c00020, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I5|I33 }, {"cvt.w.d", "D,S", 0x46200024, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I1 }, {"cvt.w.s", "D,S", 0x46000024, 0xffff003f, WR_D|RD_S|FP_S, 0, I1 }, {"cvt.ps.pw", "D,S", 0x46800026, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, M3D }, -{"cvt.ps.s","D,V,T", 0x46000026, 0xffe0003f, WR_D|RD_S|RD_T|FP_S|FP_D, 0, I5 }, +{"cvt.ps.s","D,V,T", 0x46000026, 0xffe0003f, WR_D|RD_S|RD_T|FP_S|FP_D, 0, I5|I33 }, {"cvt.pw.ps", "D,S", 0x46c00024, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, M3D }, {"dabs", "d,v", 0, (int) M_DABS, INSN_MACRO, 0, I3 }, {"dadd", "d,v,t", 0x0000002c, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I3 }, @@ -573,10 +579,8 @@ const struct mips_opcode mips_builtin_opcodes[] = {"dmtc1", "t,G", 0x44a00000, 0xffe007ff, COD|RD_t|WR_S|FP_D, 0, I3 }, /* dmfc2 is at the bottom of the table. */ /* dmtc2 is at the bottom of the table. */ -{"dmfc3", "t,G", 0x4c200000, 0xffe007ff, LCD|WR_t|RD_C3, 0, I3 }, -{"dmfc3", "t,G,H", 0x4c200000, 0xffe007f8, LCD|WR_t|RD_C3, 0, I64 }, -{"dmtc3", "t,G", 0x4ca00000, 0xffe007ff, COD|RD_t|WR_C3|WR_CC, 0, I3 }, -{"dmtc3", "t,G,H", 0x4ca00000, 0xffe007f8, COD|RD_t|WR_C3|WR_CC, 0, I64 }, +/* dmfc3 is at the bottom of the table. */ +/* dmtc3 is at the bottom of the table. */ {"dmul", "d,v,t", 0, (int) M_DMUL, INSN_MACRO, 0, I3 }, {"dmul", "d,v,I", 0, (int) M_DMUL_I, INSN_MACRO, 0, I3 }, {"dmulo", "d,v,t", 0, (int) M_DMULO, INSN_MACRO, 0, I3 }, @@ -639,16 +643,15 @@ const struct mips_opcode mips_builtin_opcodes[] = {"evpe", "t", 0x41600021, 0xffe0ffff, TRAP|WR_t, 0, MT32 }, {"ext", "t,r,+A,+C", 0x7c000000, 0xfc00003f, WR_t|RD_s, 0, I33 }, {"floor.l.d", "D,S", 0x4620000b, 0xffff003f, WR_D|RD_S|FP_D, 0, I3|I33 }, -{"floor.l.s", "D,S", 0x4600000b, 0xffff003f, WR_D|RD_S|FP_S|FP_S, 0, I3|I33 }, +{"floor.l.s", "D,S", 0x4600000b, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I3|I33 }, {"floor.w.d", "D,S", 0x4620000f, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I2 }, {"floor.w.s", "D,S", 0x4600000f, 0xffff003f, WR_D|RD_S|FP_S, 0, I2 }, -{"flushi", "", 0xbc010000, 0xffffffff, 0, 0, L1 }, -{"flushd", "", 0xbc020000, 0xffffffff, 0, 0, L1 }, -{"flushid", "", 0xbc030000, 0xffffffff, 0, 0, L1 }, {"hibernate","", 0x42000023, 0xffffffff, 0, 0, V1 }, {"ins", "t,r,+A,+B", 0x7c000004, 0xfc00003f, WR_t|RD_s, 0, I33 }, {"jr", "s", 0x00000008, 0xfc1fffff, UBD|RD_s, 0, I1 }, -{"jr.hb", "s", 0x00000408, 0xfc1fffff, UBD|RD_s, 0, I33 }, +/* jr.hb is officially MIPS{32,64}R2, but it works on R1 as jr with + the same hazard barrier effect. */ +{"jr.hb", "s", 0x00000408, 0xfc1fffff, UBD|RD_s, 0, I32 }, {"j", "s", 0x00000008, 0xfc1fffff, UBD|RD_s, 0, I1 }, /* jr */ /* SVR4 PIC code requires special handling for j, so it must be a macro. */ @@ -659,8 +662,10 @@ const struct mips_opcode mips_builtin_opcodes[] = {"j", "a", 0x08000000, 0xfc000000, UBD, 0, I1 }, {"jalr", "s", 0x0000f809, 0xfc1fffff, UBD|RD_s|WR_d, 0, I1 }, {"jalr", "d,s", 0x00000009, 0xfc1f07ff, UBD|RD_s|WR_d, 0, I1 }, -{"jalr.hb", "s", 0x0000fc09, 0xfc1fffff, UBD|RD_s|WR_d, 0, I33 }, -{"jalr.hb", "d,s", 0x00000409, 0xfc1f07ff, UBD|RD_s|WR_d, 0, I33 }, +/* jalr.hb is officially MIPS{32,64}R2, but it works on R1 as jalr + with the same hazard barrier effect. */ +{"jalr.hb", "s", 0x0000fc09, 0xfc1fffff, UBD|RD_s|WR_d, 0, I32 }, +{"jalr.hb", "d,s", 0x00000409, 0xfc1f07ff, UBD|RD_s|WR_d, 0, I32 }, /* SVR4 PIC code requires special handling for jal, so it must be a macro. */ {"jal", "d,s", 0, (int) M_JAL_2, INSN_MACRO, 0, I1 }, @@ -710,7 +715,7 @@ const struct mips_opcode mips_builtin_opcodes[] = {"lld", "t,o(b)", 0xd0000000, 0xfc000000, LDD|RD_b|WR_t, 0, I3 }, {"lld", "t,A(b)", 0, (int) M_LLD_AB, INSN_MACRO, 0, I3 }, {"lui", "t,u", 0x3c000000, 0xffe00000, WR_t, 0, I1 }, -{"luxc1", "D,t(b)", 0x4c000005, 0xfc00f83f, LDD|WR_D|RD_t|RD_b, 0, I5|N55 }, +{"luxc1", "D,t(b)", 0x4c000005, 0xfc00f83f, LDD|WR_D|RD_t|RD_b|FP_D, 0, I5|I33|N55}, {"lw", "t,o(b)", 0x8c000000, 0xfc000000, LDD|RD_b|WR_t, 0, I1 }, {"lw", "t,A(b)", 0, (int) M_LW_AB, INSN_MACRO, 0, I1 }, {"lwc0", "E,o(b)", 0xc0000000, 0xfc000000, CLD|RD_b|WR_CC, 0, I1 }, @@ -737,6 +742,7 @@ const struct mips_opcode mips_builtin_opcodes[] = {"lwu", "t,o(b)", 0x9c000000, 0xfc000000, LDD|RD_b|WR_t, 0, I3 }, {"lwu", "t,A(b)", 0, (int) M_LWU_AB, INSN_MACRO, 0, I3 }, {"lwxc1", "D,t(b)", 0x4c000000, 0xfc00f83f, LDD|WR_D|RD_t|RD_b|FP_D, 0, I4|I33 }, +{"lwxs", "d,t(b)", 0x70000088, 0xfc0007ff, LDD|RD_b|RD_t|WR_d, 0, SMT }, {"macc", "d,s,t", 0x00000028, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N412 }, {"macc", "d,s,t", 0x00000158, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N5 }, {"maccs", "d,s,t", 0x00000428, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N412 }, @@ -753,13 +759,14 @@ const struct mips_opcode mips_builtin_opcodes[] = {"madu", "s,t", 0x70000001, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, P3 }, {"madd.d", "D,R,S,T", 0x4c000021, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0, I4|I33 }, {"madd.s", "D,R,S,T", 0x4c000020, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_S, 0, I4|I33 }, -{"madd.ps", "D,R,S,T", 0x4c000026, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0, I5 }, -{"madd", "s,t", 0x0000001c, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, L1 }, -{"madd", "s,t", 0x70000000, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, I32|N55}, -{"madd", "s,t", 0x70000000, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0, G1 }, -{"madd", "d,s,t", 0x70000000, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d|IS_M, 0, G1 }, -{"maddu", "s,t", 0x0000001d, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, L1 }, -{"maddu", "s,t", 0x70000001, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, I32|N55}, +{"madd.ps", "D,R,S,T", 0x4c000026, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0, I5|I33 }, +{"madd", "s,t", 0x0000001c, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, L1 }, +{"madd", "s,t", 0x70000000, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, I32|N55 }, +{"madd", "s,t", 0x70000000, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0, G1 }, +{"madd", "d,s,t", 0x70000000, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d|IS_M, 0, G1 }, +{"maddp", "s,t", 0x70000441, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, SMT }, +{"maddu", "s,t", 0x0000001d, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, L1 }, +{"maddu", "s,t", 0x70000001, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, I32|N55 }, {"maddu", "s,t", 0x70000001, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0, G1 }, {"maddu", "d,s,t", 0x70000001, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d|IS_M, 0, G1 }, {"madd16", "s,t", 0x00000028, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, N411 }, @@ -787,7 +794,7 @@ const struct mips_opcode mips_builtin_opcodes[] = {"mfthi", "d,*", 0x41010021, 0xfff307ff, TRAP|WR_d|RD_a, 0, MT32 }, {"mftlo", "d", 0x41000021, 0xffff07ff, TRAP|WR_d|RD_a, 0, MT32 }, {"mftlo", "d,*", 0x41000021, 0xfff307ff, TRAP|WR_d|RD_a, 0, MT32 }, -{"mftr", "t,d,!,H,$", 0x41000000, 0xffe007c8, TRAP|WR_d, 0, MT32 }, +{"mftr", "d,t,!,H,$", 0x41000000, 0xffe007c8, TRAP|WR_d, 0, MT32 }, {"mfc0", "t,G", 0x40000000, 0xffe007ff, LCD|WR_t|RD_C0, 0, I1 }, {"mfc0", "t,+D", 0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 0, I32 }, {"mfc0", "t,G,H", 0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 0, I32 }, @@ -797,13 +804,13 @@ const struct mips_opcode mips_builtin_opcodes[] = {"mfhc1", "t,G", 0x44600000, 0xffe007ff, LCD|WR_t|RD_S|FP_D, 0, I33 }, /* mfc2 is at the bottom of the table. */ /* mfhc2 is at the bottom of the table. */ -{"mfc3", "t,G", 0x4c000000, 0xffe007ff, LCD|WR_t|RD_C3, 0, I1 }, -{"mfc3", "t,G,H", 0x4c000000, 0xffe007f8, LCD|WR_t|RD_C3, 0, I32 }, +/* mfc3 is at the bottom of the table. */ {"mfdr", "t,G", 0x7000003d, 0xffe007ff, LCD|WR_t|RD_C0, 0, N5 }, {"mfhi", "d", 0x00000010, 0xffff07ff, WR_d|RD_HI, 0, I1 }, {"mfhi", "d,9", 0x00000010, 0xff9f07ff, WR_d|RD_HI, 0, D32 }, {"mflo", "d", 0x00000012, 0xffff07ff, WR_d|RD_LO, 0, I1 }, {"mflo", "d,9", 0x00000012, 0xff9f07ff, WR_d|RD_LO, 0, D32 }, +{"mflhxu", "d", 0x00000052, 0xffff07ff, WR_d|MOD_HILO, 0, SMT }, {"min.ob", "X,Y,Q", 0x78000006, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX|SB1 }, {"min.ob", "D,S,T", 0x4ac00006, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, {"min.ob", "D,S,T[e]", 0x48000006, 0xfe20003f, WR_D|RD_S|RD_T, 0, N54 }, @@ -811,33 +818,33 @@ const struct mips_opcode mips_builtin_opcodes[] = {"min.qh", "X,Y,Q", 0x78200006, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, {"mov.d", "D,S", 0x46200006, 0xffff003f, WR_D|RD_S|FP_D, 0, I1 }, {"mov.s", "D,S", 0x46000006, 0xffff003f, WR_D|RD_S|FP_S, 0, I1 }, -{"mov.ps", "D,S", 0x46c00006, 0xffff003f, WR_D|RD_S|FP_D, 0, I5 }, +{"mov.ps", "D,S", 0x46c00006, 0xffff003f, WR_D|RD_S|FP_D, 0, I5|I33 }, {"movf", "d,s,N", 0x00000001, 0xfc0307ff, WR_d|RD_s|RD_CC|FP_S|FP_D, 0, I4|I32 }, {"movf.d", "D,S,N", 0x46200011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, I4|I32 }, {"movf.l", "D,S,N", 0x46a00011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, MX|SB1 }, {"movf.l", "X,Y,N", 0x46a00011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, MX|SB1 }, {"movf.s", "D,S,N", 0x46000011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_S, 0, I4|I32 }, -{"movf.ps", "D,S,N", 0x46c00011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, I5 }, +{"movf.ps", "D,S,N", 0x46c00011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, I5|I33 }, {"movn", "d,v,t", 0x0000000b, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I4|I32 }, {"ffc", "d,v", 0x0000000b, 0xfc1f07ff, WR_d|RD_s, 0, L1 }, {"movn.d", "D,S,t", 0x46200013, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, I4|I32 }, {"movn.l", "D,S,t", 0x46a00013, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, MX|SB1 }, {"movn.l", "X,Y,t", 0x46a00013, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, MX|SB1 }, {"movn.s", "D,S,t", 0x46000013, 0xffe0003f, WR_D|RD_S|RD_t|FP_S, 0, I4|I32 }, -{"movn.ps", "D,S,t", 0x46c00013, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, I5 }, +{"movn.ps", "D,S,t", 0x46c00013, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, I5|I33 }, {"movt", "d,s,N", 0x00010001, 0xfc0307ff, WR_d|RD_s|RD_CC|FP_S|FP_D, 0, I4|I32 }, {"movt.d", "D,S,N", 0x46210011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, I4|I32 }, {"movt.l", "D,S,N", 0x46a10011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, MX|SB1 }, {"movt.l", "X,Y,N", 0x46a10011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, MX|SB1 }, {"movt.s", "D,S,N", 0x46010011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_S, 0, I4|I32 }, -{"movt.ps", "D,S,N", 0x46c10011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, I5 }, +{"movt.ps", "D,S,N", 0x46c10011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, I5|I33 }, {"movz", "d,v,t", 0x0000000a, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I4|I32 }, {"ffs", "d,v", 0x0000000a, 0xfc1f07ff, WR_d|RD_s, 0, L1 }, {"movz.d", "D,S,t", 0x46200012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, I4|I32 }, {"movz.l", "D,S,t", 0x46a00012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, MX|SB1 }, {"movz.l", "X,Y,t", 0x46a00012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, MX|SB1 }, {"movz.s", "D,S,t", 0x46000012, 0xffe0003f, WR_D|RD_S|RD_t|FP_S, 0, I4|I32 }, -{"movz.ps", "D,S,t", 0x46c00012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, I5 }, +{"movz.ps", "D,S,t", 0x46c00012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, I5|I33 }, {"msac", "d,s,t", 0x000001d8, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N5 }, {"msacu", "d,s,t", 0x000001d9, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N5 }, {"msachi", "d,s,t", 0x000003d8, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N5 }, @@ -846,7 +853,7 @@ const struct mips_opcode mips_builtin_opcodes[] = {"msgn.qh", "X,Y,Q", 0x78200000, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, {"msub.d", "D,R,S,T", 0x4c000029, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0, I4|I33 }, {"msub.s", "D,R,S,T", 0x4c000028, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_S, 0, I4|I33 }, -{"msub.ps", "D,R,S,T", 0x4c00002e, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0, I5 }, +{"msub.ps", "D,R,S,T", 0x4c00002e, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0, I5|I33 }, {"msub", "s,t", 0x0000001e, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, L1 }, {"msub", "s,t", 0x70000004, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, I32|N55 }, {"msubu", "s,t", 0x0000001f, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, L1 }, @@ -862,13 +869,13 @@ const struct mips_opcode mips_builtin_opcodes[] = {"mthc1", "t,G", 0x44e00000, 0xffe007ff, COD|RD_t|WR_S|FP_D, 0, I33 }, /* mtc2 is at the bottom of the table. */ /* mthc2 is at the bottom of the table. */ -{"mtc3", "t,G", 0x4c800000, 0xffe007ff, COD|RD_t|WR_C3|WR_CC, 0, I1 }, -{"mtc3", "t,G,H", 0x4c800000, 0xffe007f8, COD|RD_t|WR_C3|WR_CC, 0, I32 }, +/* mtc3 is at the bottom of the table. */ {"mtdr", "t,G", 0x7080003d, 0xffe007ff, COD|RD_t|WR_C0, 0, N5 }, {"mthi", "s", 0x00000011, 0xfc1fffff, RD_s|WR_HI, 0, I1 }, {"mthi", "s,7", 0x00000011, 0xfc1fe7ff, RD_s|WR_HI, 0, D32 }, {"mtlo", "s", 0x00000013, 0xfc1fffff, RD_s|WR_LO, 0, I1 }, {"mtlo", "s,7", 0x00000013, 0xfc1fe7ff, RD_s|WR_LO, 0, D32 }, +{"mtlhx", "s", 0x00000053, 0xfc1fffff, RD_s|MOD_HILO, 0, SMT }, {"mttc0", "t,G", 0x41800000, 0xffe007ff, TRAP|COD|RD_t|WR_C0|WR_CC, 0, MT32 }, {"mttc0", "t,+D", 0x41800000, 0xffe007f8, TRAP|COD|RD_t|WR_C0|WR_CC, 0, MT32 }, {"mttc0", "t,G,H", 0x41800000, 0xffe007f8, TRAP|COD|RD_t|WR_C0|WR_CC, 0, MT32 }, @@ -893,7 +900,7 @@ const struct mips_opcode mips_builtin_opcodes[] = {"mul.ob", "D,S,T", 0x4ac00030, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, {"mul.ob", "D,S,T[e]", 0x48000030, 0xfe20003f, WR_D|RD_S|RD_T, 0, N54 }, {"mul.ob", "D,S,k", 0x4bc00030, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"mul.ps", "D,V,T", 0x46c00002, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I5 }, +{"mul.ps", "D,V,T", 0x46c00002, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I5|I33 }, {"mul.qh", "X,Y,Q", 0x78200030, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, {"mul", "d,v,t", 0x70000002, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0, I32|P3|N55}, {"mul", "d,s,t", 0x00000058, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N54 }, @@ -932,6 +939,7 @@ const struct mips_opcode mips_builtin_opcodes[] = {"mulsl.qh", "Y,Q", 0x78200432, 0xfc2007ff, RD_S|RD_T|FP_D, WR_MACC, MX }, {"mult", "s,t", 0x00000018, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0, I1 }, {"mult", "d,s,t", 0x00000018, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d|IS_M, 0, G1 }, +{"multp", "s,t", 0x00000459, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, SMT }, {"multu", "s,t", 0x00000019, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0, I1 }, {"multu", "d,s,t", 0x00000019, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d|IS_M, 0, G1 }, {"mulu", "d,s,t", 0x00000059, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N5 }, @@ -939,13 +947,13 @@ const struct mips_opcode mips_builtin_opcodes[] = {"negu", "d,w", 0x00000023, 0xffe007ff, WR_d|RD_t, 0, I1 }, /* subu 0 */ {"neg.d", "D,V", 0x46200007, 0xffff003f, WR_D|RD_S|FP_D, 0, I1 }, {"neg.s", "D,V", 0x46000007, 0xffff003f, WR_D|RD_S|FP_S, 0, I1 }, -{"neg.ps", "D,V", 0x46c00007, 0xffff003f, WR_D|RD_S|FP_D, 0, I5 }, +{"neg.ps", "D,V", 0x46c00007, 0xffff003f, WR_D|RD_S|FP_D, 0, I5|I33 }, {"nmadd.d", "D,R,S,T", 0x4c000031, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0, I4|I33 }, {"nmadd.s", "D,R,S,T", 0x4c000030, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_S, 0, I4|I33 }, -{"nmadd.ps","D,R,S,T", 0x4c000036, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0, I5 }, +{"nmadd.ps","D,R,S,T", 0x4c000036, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0, I5|I33 }, {"nmsub.d", "D,R,S,T", 0x4c000039, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0, I4|I33 }, {"nmsub.s", "D,R,S,T", 0x4c000038, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_S, 0, I4|I33 }, -{"nmsub.ps","D,R,S,T", 0x4c00003e, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0, I5 }, +{"nmsub.ps","D,R,S,T", 0x4c00003e, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0, I5|I33 }, /* nop is at the start of the table. */ {"nor", "d,v,t", 0x00000027, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I1 }, {"nor", "t,r,I", 0, (int) M_NOR_I, INSN_MACRO, 0, I1 }, @@ -976,11 +984,12 @@ const struct mips_opcode mips_builtin_opcodes[] = {"pickt.ob", "D,S,T[e]",0x48000003, 0xfe20003f, WR_D|RD_S|RD_T, 0, N54 }, {"pickt.ob", "D,S,k", 0x4bc00003, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, {"pickt.qh", "X,Y,Q", 0x78200003, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"pll.ps", "D,V,T", 0x46c0002c, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I5 }, -{"plu.ps", "D,V,T", 0x46c0002d, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I5 }, +{"pll.ps", "D,V,T", 0x46c0002c, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I5|I33 }, +{"plu.ps", "D,V,T", 0x46c0002d, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I5|I33 }, /* pref and prefx are at the start of the table. */ -{"pul.ps", "D,V,T", 0x46c0002e, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I5 }, -{"puu.ps", "D,V,T", 0x46c0002f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I5 }, +{"pul.ps", "D,V,T", 0x46c0002e, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I5|I33 }, +{"puu.ps", "D,V,T", 0x46c0002f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I5|I33 }, +{"pperm", "s,t", 0x70000481, 0xfc00ffff, MOD_HILO|RD_s|RD_t, 0, SMT }, {"rach.ob", "X", 0x7a00003f, 0xfffff83f, WR_D|FP_D, RD_MACC, MX|SB1 }, {"rach.ob", "D", 0x4a00003f, 0xfffff83f, WR_D, 0, N54 }, {"rach.qh", "X", 0x7a20003f, 0xfffff83f, WR_D|FP_D, RD_MACC, MX }, @@ -1018,15 +1027,15 @@ const struct mips_opcode mips_builtin_opcodes[] = {"rol", "d,v,I", 0, (int) M_ROL_I, INSN_MACRO, 0, I1 }, {"ror", "d,v,t", 0, (int) M_ROR, INSN_MACRO, 0, I1 }, {"ror", "d,v,I", 0, (int) M_ROR_I, INSN_MACRO, 0, I1 }, -{"ror", "d,w,<", 0x00200002, 0xffe0003f, WR_d|RD_t, 0, N5|I33 }, -{"rorv", "d,t,s", 0x00000046, 0xfc0007ff, RD_t|RD_s|WR_d, 0, N5|I33 }, -{"rotl", "d,v,t", 0, (int) M_ROL, INSN_MACRO, 0, I33 }, -{"rotl", "d,v,I", 0, (int) M_ROL_I, INSN_MACRO, 0, I33 }, -{"rotr", "d,v,t", 0, (int) M_ROR, INSN_MACRO, 0, I33 }, -{"rotr", "d,v,I", 0, (int) M_ROR_I, INSN_MACRO, 0, I33 }, -{"rotrv", "d,t,s", 0x00000046, 0xfc0007ff, RD_t|RD_s|WR_d, 0, I33 }, +{"ror", "d,w,<", 0x00200002, 0xffe0003f, WR_d|RD_t, 0, N5|I33|SMT }, +{"rorv", "d,t,s", 0x00000046, 0xfc0007ff, RD_t|RD_s|WR_d, 0, N5|I33|SMT }, +{"rotl", "d,v,t", 0, (int) M_ROL, INSN_MACRO, 0, I33|SMT }, +{"rotl", "d,v,I", 0, (int) M_ROL_I, INSN_MACRO, 0, I33|SMT }, +{"rotr", "d,v,t", 0, (int) M_ROR, INSN_MACRO, 0, I33|SMT }, +{"rotr", "d,v,I", 0, (int) M_ROR_I, INSN_MACRO, 0, I33|SMT }, +{"rotrv", "d,t,s", 0x00000046, 0xfc0007ff, RD_t|RD_s|WR_d, 0, I33|SMT }, {"round.l.d", "D,S", 0x46200008, 0xffff003f, WR_D|RD_S|FP_D, 0, I3|I33 }, -{"round.l.s", "D,S", 0x46000008, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I3 }, +{"round.l.s", "D,S", 0x46000008, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I3|I33 }, {"round.w.d", "D,S", 0x4620000c, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I2 }, {"round.w.s", "D,S", 0x4600000c, 0xffff003f, WR_D|RD_S|FP_S, 0, I2 }, {"rsqrt.d", "D,S", 0x46200016, 0xffff003f, WR_D|RD_S|FP_D, 0, I4|I33 }, @@ -1145,7 +1154,7 @@ const struct mips_opcode mips_builtin_opcodes[] = {"sub.ob", "D,S,T", 0x4ac0000a, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, {"sub.ob", "D,S,T[e]", 0x4800000a, 0xfe20003f, WR_D|RD_S|RD_T, 0, N54 }, {"sub.ob", "D,S,k", 0x4bc0000a, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"sub.ps", "D,V,T", 0x46c00001, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I5 }, +{"sub.ps", "D,V,T", 0x46c00001, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I5|I33 }, {"sub.qh", "X,Y,Q", 0x7820000a, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, {"suba.ob", "Y,Q", 0x78000036, 0xfc2007ff, RD_S|RD_T|FP_D, WR_MACC, MX|SB1 }, {"suba.qh", "Y,Q", 0x78200036, 0xfc2007ff, RD_S|RD_T|FP_D, WR_MACC, MX }, @@ -1154,7 +1163,7 @@ const struct mips_opcode mips_builtin_opcodes[] = {"subu", "d,v,t", 0x00000023, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I1 }, {"subu", "d,v,I", 0, (int) M_SUBU_I, INSN_MACRO, 0, I1 }, {"suspend", "", 0x42000022, 0xffffffff, 0, 0, V1 }, -{"suxc1", "S,t(b)", 0x4c00000d, 0xfc0007ff, SM|RD_S|RD_t|RD_b, 0, I5|N55 }, +{"suxc1", "S,t(b)", 0x4c00000d, 0xfc0007ff, SM|RD_S|RD_t|RD_b, 0, I5|I33|N55}, {"sw", "t,o(b)", 0xac000000, 0xfc000000, SM|RD_t|RD_b, 0, I1 }, {"sw", "t,A(b)", 0, (int) M_SW_AB, INSN_MACRO, 0, I1 }, {"swc0", "E,o(b)", 0xe0000000, 0xfc000000, SM|RD_C0|RD_b, 0, I1 }, @@ -1249,7 +1258,6 @@ const struct mips_opcode mips_builtin_opcodes[] = {"wait", "", 0x42000020, 0xffffffff, TRAP, 0, I3|I32 }, {"wait", "J", 0x42000020, 0xfe00003f, TRAP, 0, I32|N55 }, {"waiti", "", 0x42000020, 0xffffffff, TRAP, 0, L1 }, -{"wb", "o(b)", 0xbc040000, 0xfc1f0000, SM|RD_b, 0, L1 }, {"wrpgpr", "d,w", 0x41c00000, 0xffe007ff, RD_t, 0, I33 }, {"wsbh", "d,w", 0x7c0000a0, 0xffe007ff, WR_d|RD_t, 0, I33 }, {"xor", "d,v,t", 0x00000026, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I1 }, @@ -1263,12 +1271,82 @@ const struct mips_opcode mips_builtin_opcodes[] = {"yield", "s", 0x7c000009, 0xfc1fffff, TRAP|RD_s, 0, MT32 }, {"yield", "d,s", 0x7c000009, 0xfc1f07ff, TRAP|WR_d|RD_s, 0, MT32 }, +/* User Defined Instruction. */ +{"udi0", "s,t,d,+1",0x70000010, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi0", "s,t,+2", 0x70000010, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi0", "s,+3", 0x70000010, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi0", "+4", 0x70000010, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi1", "s,t,d,+1",0x70000011, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi1", "s,t,+2", 0x70000011, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi1", "s,+3", 0x70000011, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi1", "+4", 0x70000011, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi2", "s,t,d,+1",0x70000012, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi2", "s,t,+2", 0x70000012, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi2", "s,+3", 0x70000012, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi2", "+4", 0x70000012, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi3", "s,t,d,+1",0x70000013, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi3", "s,t,+2", 0x70000013, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi3", "s,+3", 0x70000013, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi3", "+4", 0x70000013, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi4", "s,t,d,+1",0x70000014, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi4", "s,t,+2", 0x70000014, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi4", "s,+3", 0x70000014, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi4", "+4", 0x70000014, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi5", "s,t,d,+1",0x70000015, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi5", "s,t,+2", 0x70000015, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi5", "s,+3", 0x70000015, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi5", "+4", 0x70000015, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi6", "s,t,d,+1",0x70000016, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi6", "s,t,+2", 0x70000016, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi6", "s,+3", 0x70000016, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi6", "+4", 0x70000016, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi7", "s,t,d,+1",0x70000017, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi7", "s,t,+2", 0x70000017, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi7", "s,+3", 0x70000017, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi7", "+4", 0x70000017, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi8", "s,t,d,+1",0x70000018, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi8", "s,t,+2", 0x70000018, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi8", "s,+3", 0x70000018, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi8", "+4", 0x70000018, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi9", "s,t,d,+1",0x70000019, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi9", "s,t,+2", 0x70000019, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi9", "s,+3", 0x70000019, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi9", "+4", 0x70000019, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi10", "s,t,d,+1",0x7000001a, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi10", "s,t,+2", 0x7000001a, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi10", "s,+3", 0x7000001a, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi10", "+4", 0x7000001a, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi11", "s,t,d,+1",0x7000001b, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi11", "s,t,+2", 0x7000001b, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi11", "s,+3", 0x7000001b, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi11", "+4", 0x7000001b, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi12", "s,t,d,+1",0x7000001c, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi12", "s,t,+2", 0x7000001c, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi12", "s,+3", 0x7000001c, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi12", "+4", 0x7000001c, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi13", "s,t,d,+1",0x7000001d, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi13", "s,t,+2", 0x7000001d, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi13", "s,+3", 0x7000001d, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi13", "+4", 0x7000001d, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi14", "s,t,d,+1",0x7000001e, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi14", "s,t,+2", 0x7000001e, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi14", "s,+3", 0x7000001e, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi14", "+4", 0x7000001e, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi15", "s,t,d,+1",0x7000001f, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi15", "s,t,+2", 0x7000001f, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi15", "s,+3", 0x7000001f, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +{"udi15", "+4", 0x7000001f, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, + /* Coprocessor 2 move/branch operations overlap with VR5400 .ob format instructions so they are here for the latters to take precedence. */ {"bc2f", "p", 0x49000000, 0xffff0000, CBD|RD_CC, 0, I1 }, +{"bc2f", "N,p", 0x49000000, 0xffe30000, CBD|RD_CC, 0, I32 }, {"bc2fl", "p", 0x49020000, 0xffff0000, CBL|RD_CC, 0, I2|T3 }, +{"bc2fl", "N,p", 0x49020000, 0xffe30000, CBL|RD_CC, 0, I32 }, {"bc2t", "p", 0x49010000, 0xffff0000, CBD|RD_CC, 0, I1 }, +{"bc2t", "N,p", 0x49010000, 0xffe30000, CBD|RD_CC, 0, I32 }, {"bc2tl", "p", 0x49030000, 0xffff0000, CBL|RD_CC, 0, I2|T3 }, +{"bc2tl", "N,p", 0x49030000, 0xffe30000, CBL|RD_CC, 0, I32 }, {"cfc2", "t,G", 0x48400000, 0xffe007ff, LCD|WR_t|RD_C2, 0, I1 }, {"ctc2", "t,G", 0x48c00000, 0xffe007ff, COD|RD_t|WR_CC, 0, I1 }, {"dmfc2", "t,G", 0x48200000, 0xffe007ff, LCD|WR_t|RD_C2, 0, I3 }, @@ -1277,11 +1355,30 @@ const struct mips_opcode mips_builtin_opcodes[] = {"dmtc2", "t,G,H", 0x48a00000, 0xffe007f8, COD|RD_t|WR_C2|WR_CC, 0, I64 }, {"mfc2", "t,G", 0x48000000, 0xffe007ff, LCD|WR_t|RD_C2, 0, I1 }, {"mfc2", "t,G,H", 0x48000000, 0xffe007f8, LCD|WR_t|RD_C2, 0, I32 }, +{"mfhc2", "t,G", 0x48600000, 0xffe007ff, LCD|WR_t|RD_C2, 0, I33 }, +{"mfhc2", "t,G,H", 0x48600000, 0xffe007f8, LCD|WR_t|RD_C2, 0, I33 }, {"mfhc2", "t,i", 0x48600000, 0xffe00000, LCD|WR_t|RD_C2, 0, I33 }, {"mtc2", "t,G", 0x48800000, 0xffe007ff, COD|RD_t|WR_C2|WR_CC, 0, I1 }, {"mtc2", "t,G,H", 0x48800000, 0xffe007f8, COD|RD_t|WR_C2|WR_CC, 0, I32 }, +{"mthc2", "t,G", 0x48e00000, 0xffe007ff, COD|RD_t|WR_C2|WR_CC, 0, I33 }, +{"mthc2", "t,G,H", 0x48e00000, 0xffe007f8, COD|RD_t|WR_C2|WR_CC, 0, I33 }, {"mthc2", "t,i", 0x48e00000, 0xffe00000, COD|RD_t|WR_C2|WR_CC, 0, I33 }, +/* Coprocessor 3 move/branch operations overlap with MIPS IV COP1X + instructions, so they are here for the latters to take precedence. */ +{"bc3f", "p", 0x4d000000, 0xffff0000, CBD|RD_CC, 0, I1 }, +{"bc3fl", "p", 0x4d020000, 0xffff0000, CBL|RD_CC, 0, I2|T3 }, +{"bc3t", "p", 0x4d010000, 0xffff0000, CBD|RD_CC, 0, I1 }, +{"bc3tl", "p", 0x4d030000, 0xffff0000, CBL|RD_CC, 0, I2|T3 }, +{"cfc3", "t,G", 0x4c400000, 0xffe007ff, LCD|WR_t|RD_C3, 0, I1 }, +{"ctc3", "t,G", 0x4cc00000, 0xffe007ff, COD|RD_t|WR_CC, 0, I1 }, +{"dmfc3", "t,G", 0x4c200000, 0xffe007ff, LCD|WR_t|RD_C3, 0, I3 }, +{"dmtc3", "t,G", 0x4ca00000, 0xffe007ff, COD|RD_t|WR_C3|WR_CC, 0, I3 }, +{"mfc3", "t,G", 0x4c000000, 0xffe007ff, LCD|WR_t|RD_C3, 0, I1 }, +{"mfc3", "t,G,H", 0x4c000000, 0xffe007f8, LCD|WR_t|RD_C3, 0, I32 }, +{"mtc3", "t,G", 0x4c800000, 0xffe007ff, COD|RD_t|WR_C3|WR_CC, 0, I1 }, +{"mtc3", "t,G,H", 0x4c800000, 0xffe007f8, COD|RD_t|WR_C3|WR_CC, 0, I32 }, + /* No hazard protection on coprocessor instructions--they shouldn't change the state of the processor and if they do it's up to the user to put in nops as necessary. These are at the end so that the diff --git a/opcodes/mips16-opc.c b/opcodes/mips16-opc.c index 4e5ae44..24b6107 100644 --- a/opcodes/mips16-opc.c +++ b/opcodes/mips16-opc.c @@ -64,6 +64,7 @@ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA const struct mips_opcode mips16_opcodes[] = { +/* name, args, match, mask, pinfo, pinfo2, membership */ {"nop", "", 0x6500, 0xffff, RD_Z, 0, 0 }, /* move $0,$Z */ {"la", "x,A", 0x0800, 0xf800, WR_x|RD_PC, 0, 0 }, {"abs", "x,w", 0, (int) M_ABS, INSN_MACRO, 0, 0 }, @@ -228,6 +229,7 @@ const struct mips_opcode mips16_opcodes[] = {"jrc", "R", 0xe8a0, 0xffff, RD_31|TRAP, 0, 0 }, {"restore", "M", 0x6400, 0xff80, WR_31|RD_SP|WR_SP|TRAP, 0, 0 }, {"save", "m", 0x6480, 0xff80, RD_31|RD_SP|WR_SP|TRAP, 0, 0 }, +{"sdbbp", "6", 0xe801, 0xf81f, TRAP, 0, 0 }, {"seb", "x", 0xe891, 0xf8ff, WR_x|RD_x, 0, 0 }, {"seh", "x", 0xe8b1, 0xf8ff, WR_x|RD_x, 0, 0 }, {"sew", "x", 0xe8d1, 0xf8ff, WR_x|RD_x, 0, I3 }, diff --git a/readline/CHANGELOG b/readline/CHANGELOG index 350defa..b6499c3 100644 --- a/readline/CHANGELOG +++ b/readline/CHANGELOG @@ -697,3 +697,224 @@ doc/Makefile.in - new maybe-clean target that removes the generated documentation if the build directory differs from the source directory - distclean target now depends on maybe-clean + + 7/17 + ---- +[readline-4.3 released] + + 7/18 + ---- +shlib/Makefile.in + - fix bad dependency: text.so: terminal.c, make it depend on text.c + + 8/7 + --- +support/shlib-install + - break `linux' out into its own stanza: it seems that linux + distributions are all moving to the following scheme: + + libreadline.so.4.3 installed version + libreadline.so.4 -> libreadline.so.4.3 symlink + libreadline.so -> libreadline.so.4 symlink + + 10/29 + ----- +support/shlib-install + - change INSTALL_LINK[12] to use `&&' instead of `;' so it only + tries the link if the cd succeeds; put ${echo} in there, too + - use $LN instead of `ln -s' so it works on machines without symlinks + - change special linux stanza to use cd before ln also + - change to use $INSTALL_LINK1 and $INSTALL_LINK2 appropriately + instead of explicit commands in various stanzas + + 2/1 + --- +config.h.in + - add HAVE_MBRTOWC and HAVE_MBRLEN + - add NO_MULTIBYTE_SUPPORT for new configure argument + - add STDC_HEADERS + +configure.in + - new argument --enable-multibyte (enabled by default), allows + multibyte support to be turned off even on systems that support it + - add check for ansi stdc headers with call to AC_HEADER_STDC + + 2/3 + --- +configure.in + - add call to BASH_FUNC_CTYPE_NONASCII + +config.h.in + - add CTYPE_NON_ASCII + + 2/20 + ---- + +doc/manvers.texinfo + - renamed to version.texi to match other GNU software + - UPDATE-MONTH variable is now `UPDATED-MONTH' + +doc/{hist,rlman,rluserman}.texinfo + - include version.texi + +doc/{rltech,rluser,hstech,hsuser}.texi + - changed the suffix from `texinfo' to `texi' + +doc/Makefile.in + - made appropriate changes for {{rl,hs}tech,{rl,hs}user}.texi + +doc/{rlman,rluserman}.texinfo + - changed the suffix from `texinfo' to `texi' + +doc/hist.texinfo + - renamed to history.texi to be more consistent + + 6/11 + ---- +shlib/Makefile.in + - have configure substitute value of `@LDFLAGS@' into the assignment + to SHLIB_XLDFLAGS + + 6/16 + ---- +configure.in + - readline and history libraries are now at version 5.0 + + 8/18 + ---- +support/shlib-install + - support for FreeBSD-gnu (from Robert Millan) + + 12/4 + ---- +Makefile.in + - add variables for localedir and the PACKAGE_* variables, auto-set + by configure + + 12/9 + ---- +Makefile.in + - use mkinstalldirs instead of mkdirs + + 4/22 + ---- +Makefile.in + - separate doc install/uninstall out into two new targets: + install-doc and uninstall-doc + - make install-doc and uninstall-doc prerequisites of appropriate + install and uninstall targets + +examples/rl-fgets.c + - new example from Harold Levy that wraps fgets replacement functions + that call readline in a shared library that can be interposed with + LD_PRELOAD + + 7/27 + ---- +[readline-5.0 released] + + 11/15 + ----- +examples/rlfe/{ChangeLog,Makefile.in,README,config.h.in,configure,configure.in,extern.h,os.h,pty.c,rlfe.c,screen.h} + - new version of rlfe, rlfe-0.4, from Per Bothner; now a standalone + application + + 11/16 + ----- +shlib/Makefile.in + - substitute TERMCAP_LIB in from configure + +configure.in + - if SHLIB_LIBS doesn't include a termcap library (curses, ncurses, + termcap, termlib), append the value of $TERMCAP_LIB to it + + 11/30 + ----- +configure.in + - take out change from 11/16; it doesn't work for some systems (e.g., + SunOS 4.x and Solaris 2.6) + - add support for --enable-purify configure argument + - pass TERMCAP_LIB in environment when calling shobj-conf + +examples/Makefile.in + - add support for building examples with purify + + 1/23/2005 + --------- +configure.in + - set BUILD_DIR to contain backslashes to escape any spaces in the + directory name -- this is what make will accept in targets and + prerequisites, so it's better than trying to use double quotes + + 2/25 + ---- +configure.in + - change check for sys/ptem.h to include sys/stream.h if present, to + avoid the `present but cannot be compiled' messages on Solaris and + SVR4.2 (does anyone still use SVR4.2?) + + 5/7 + --- +configure.in + - add cross-compiling support from the bash configure.in, which cygwin + and mingw have apparently adopted + - add check for pwd.h, fcntl.h + - add checks for fcntl, kill system calls + - add checks for getpw{ent,nam,uid} C library functions + - pass a compile-time option through to Makefiles if cross-compiling + +config.h.in + - add HAVE_PWD_H for <pwd.h>, HAVE_FCNTL_H for <fcntl.h> + - add HAVE_FCNTL, HAVE_KILL for respective system calls + - add HAVE_GETPW{ENT,NAM,UID} for passwd functions + +Makefile.in,shlib/Makefile.in + - @CROSS_COMPILE@ is substituted into DEFS (equal to -DCROSS_COMPILING + if bash is being cross-compiled) + + 8/2 + --- +examples/Makefile.in + - use $(READLINE_LIB) instead of -lreadline to get around MacOS X 10.4's + preference for (incompatible) shared libraries over static libraries + in the load path + + 8/11 + ---- +support/shobj-conf + - new variable: SHLIB_LIBPREF, prefix for shared library name (defaults + to `lib' + - new variable: SHLIB_DLLVERSION, used on Cygwin to set the library + version number + - new variable: SHLIB_DOT, separator character between library name and + suffix and version information (defaults to `.') + - new stanza for cygwin to generate windows-compatible dll + +support/shlib-install + - add new option `-b bindir' for systems like cygwin/windows that + require it + - new stanza for cygwin that installs a dll into $bindir and an implied + link library into $libdir + +configure.in + - substitute new variables from shobj-conf + +shlib/Makefile.in + - substitute bindir, SHLIB_DOT, SHLIB_LIBPREF, SHLIB_DLLVERSION from + configure + - pass `-b $(bindir)' to shlib-install for install and uninstall targets + - library names now use $SHLIB_LIBPREF and $SHLIB_DOT + +INSTALL,README + - document new SHLIB_DOT, SHLIB_LIBPREF, and SHLIB_DLLVERSION variables + + 10/4 + ---- +[readline-5.1-beta1 frozen] + + 12/1 + ---- +configure.in + - changed release status to `release' + +[readline-5.1 frozen] diff --git a/readline/CHANGES b/readline/CHANGES index bc9fe94..1ba0c12 100644 --- a/readline/CHANGES +++ b/readline/CHANGES @@ -1,3 +1,312 @@ +This document details the changes between this version, readline-5.1, +and the previous version, readline-5.0. + +1. Changes to Readline + +a. Fixed a bug that caused multiliine prompts to be wrapped and displayed + incorrectly. + +b. Fixed a bug that caused ^P/^N in emacs mode to fail to display the current + line correctly. + +c. Fixed a problem in computing the number of invisible characters on the first + line of a prompt whose length exceeds the screen width. + +d. Fixed vi-mode searching so that failure preserves the current line rather + than the last line in the history list. + +e. Fixed the vi-mode `~' command (change-case) to have the correct behavior at + end-of-line when manipulating multibyte characters. + +f. Fixed the vi-mode `r' command (change-char) to have the correct behavior at + end-of-line when manipulating multibyte characters. + +g. Fixed multiple bugs in the redisplay of multibyte characters: displaying + prompts longer than the screen width containing multibyte characters, + +h. Fix the calculation of the number of physical characters in the prompt + string when it contains multibyte characters. + +i. A non-zero value for the `rl_complete_suppress_append' variable now causes + no `/' to be appended to a directory name. + +j. Fixed forward-word and backward-word to work when words contained + multibyte characters. + +k. Fixed a bug in finding the delimiter of a `?' substring when performing + history expansion in a locale that supports multibyte characters. + +l. Fixed a memory leak caused by not freeing the timestamp in a history entry. + +m. Fixed a bug that caused "\M-x" style key bindings to not obey the setting + of the `convert-meta' variable. + +n. Fixed saving and restoring primary prompt when prompting for incremental + and non-incremental searches; search prompts now display multibyte + characters correctly. + +o. Fixed a bug that caused keys originally bound to self-insert but shadowed + by a multi-character key sequence to not be inserted. + +p. Fixed code so rl_prep_term_function and rl_deprep_term_function aren't + dereferenced if NULL (matching the documentation). + +q. Extensive changes to readline to add enough state so that commands + requiring additional characters (searches, multi-key sequences, numeric + arguments, commands requiring an additional specifier character like + vi-mode change-char, etc.) work without synchronously waiting for + additional input. + +r. Lots of changes so readline builds and runs on MinGW. + +s. Readline no longer tries to modify the terminal settings when running in + callback mode. + +t. The Readline display code no longer sets the location of the last invisible + character in the prompt if the \[\] sequence is empty. + +u. The `change-case' command now correctly changes the case of multibyte + characters. + +v. Changes to the shared library construction scripts to deal with Windows + DLL naming conventions for Cygwin. + +w. Fixed the redisplay code to avoid core dumps resulting from a poorly-timed + SIGWINCH. + +x. Fixed the non-incremental search code in vi mode to dispose of any current + undo list when copying a line from the history into the current editing + buffer. + +y. Fixed a bug that caused reversing the incremental search direction to + not work correctly. + +z. Fixed the vi-mode `U' command to only undo up to the first time insert mode + was entered, as Posix specifies. + +aa. Fixed a bug in the vi-mode `r' command that left the cursor in the wrong + place. + +bb. Fixed a redisplay bug caused by moving the cursor vertically to a line + with invisible characters in the prompt in a multibyte locale. + +cc. Fixed a bug that could cause the terminal special chars to be bound in the + wrong keymap in vi mode. + +2. New Features in Readline + +a. The key sequence sent by the keypad `delete' key is now automatically + bound to delete-char. + +b. A negative argument to menu-complete now cycles backward through the + completion list. + +c. A new bindable readline variable: bind-tty-special-chars. If non-zero, + readline will bind the terminal special characters to their readline + equivalents when it's called (on by default). + +d. New bindable command: vi-rubout. Saves deleted text for possible + reinsertion, as with any vi-mode `text modification' command; `X' is bound + to this in vi command mode. + +e. If the rl_completion_query_items is set to a value < 0, readline never + asks the user whether or not to view the possible completions. + +f. The `C-w' binding in incremental search now understands multibyte + characters. + +g. New application-callable auxiliary function, rl_variable_value, returns + a string corresponding to a readline variable's value. + +h. When parsing inputrc files and variable binding commands, the parser + strips trailing whitespace from values assigned to boolean variables + before checking them. + +i. A new external application-controllable variable that allows the LINES + and COLUMNS environment variables to set the window size regardless of + what the kernel returns. + +------------------------------------------------------------------------------- +This document details the changes between this version, readline-5.0, +and the previous version, readline-4.3. + +1. Changes to Readline + +a. Fixes to avoid core dumps because of null pointer references in the + multibyte character code. + +b. Fix to avoid infinite recursion caused by certain key combinations. + +c. Fixed a bug that caused the vi-mode `last command' to be set incorrectly. + +d. Readline no longer tries to read ahead more than one line of input, even + when more is available. + +e. Fixed the code that adjusts the point to not mishandle null wide + characters. + +f. Fixed a bug in the history expansion `g' modifier that caused it to skip + every other match. + +g. Fixed a bug that caused the prompt to overwrite previous output when the + output doesn't contain a newline and the locale supports multibyte + characters. This same change fixes the problem of readline redisplay + slowing down dramatically as the line gets longer in multibyte locales. + +h. History traversal with arrow keys in vi insertion mode causes the cursor + to be placed at the end of the new line, like in emacs mode. + +i. The locale initialization code does a better job of using the right + precedence and defaulting when checking the appropriate environment + variables. + +j. Fixed the history word tokenizer to handle <( and >( better when used as + part of bash. + +k. The overwrite mode code received several bug fixes to improve undo. + +l. Many speedups to the multibyte character redisplay code. + +m. The callback character reading interface should not hang waiting to read + keyboard input. + +n. Fixed a bug with redoing vi-mode `s' command. + +o. The code that initializes the terminal tracks changes made to the terminal + special characters with stty(1) (or equivalent), so that these changes + are reflected in the readline bindings. New application-callable function + to make it work: rl_tty_unset_default_bindings(). + +p. Fixed a bug that could cause garbage to be inserted in the buffer when + changing character case in vi mode when using a multibyte locale. + +q. Fixed a bug in the redisplay code that caused problems on systems + supporting multibyte characters when moving between history lines when the + new line has more glyphs but fewer bytes. + +r. Undo and redo now work better after exiting vi insertion mode. + +s. Make sure system calls are restarted after a SIGWINCH is received using + SA_RESTART. + +t. Improvements to the code that displays possible completions when using + multibyte characters. + +u. Fixed a problem when parsing nested if statements in inputrc files. + +v. The completer now takes multibyte characters into account when looking for + quoted substrings on which to perform completion. + +w. The history search functions now perform better bounds checking on the + history list. + +x. Change to history expansion functions to treat `^' as equivalent to word + one, as the documention states. + +y. Some changes to the display code to improve display and redisplay of + multibyte characters. + +z. Changes to speed up the multibyte character redisplay code. + +aa. Fixed a bug in the vi-mode `E' command that caused it to skip over the + last character of a word if invoked while point was on the word's + next-to-last character. + +bb. Fixed a bug that could cause incorrect filename quoting when + case-insensitive completion was enabled and the word being completed + contained backslashes quoting word break characters. + +cc. Fixed a bug in redisplay triggered when the prompt string contains + invisible characters. + +dd. Fixed some display (and other) bugs encountered in multibyte locales + when a non-ascii character was the last character on a line. + +ee. Fixed some display bugs caused by multibyte characters in prompt strings. + +ff. Fixed a problem with history expansion caused by non-whitespace characters + used as history word delimiters. + +gg. Fixed a problem that could cause readline to refer to freed memory when + moving between history lines while doing searches. + +hh. Improvements to the code that expands and displays prompt strings + containing multibyte characters. + +ii. Fixed a problem with vi-mode not correctly remembering the numeric argument + to the last `c'hange command for later use with `.'. + +jj. Fixed a bug in vi-mode that caused multi-digit count arguments to work + incorrectly. + +kk. Fixed a problem in vi-mode that caused the last text modification command + to not be remembered across different command lines. + +ll. Fixed problems with changing characters and changing case at the end of + the line. + +mm. Fixed a problem with readline saving the contents of the current line + before beginning a non-interactive search. + +nn. Fixed a problem with EOF detection when using rl_event_hook. + +oo. Fixed a problem with the vi mode `p' and `P' commands ignoring numeric + arguments. + +2. New Features in Readline + +a. History expansion has a new `a' modifier equivalent to the `g' modifier + for compatibility with the BSD csh. + +b. History expansion has a new `G' modifier equivalent to the BSD csh `g' + modifier, which performs a substitution once per word. + +c. All non-incremental search operations may now undo the operation of + replacing the current line with the history line. + +d. The text inserted by an `a' command in vi mode can be reinserted with + `.'. + +e. New bindable variable, `show-all-if-unmodified'. If set, the readline + completer will list possible completions immediately if there is more + than one completion and partial completion cannot be performed. + +f. There is a new application-callable `free_history_entry()' function. + +g. History list entries now contain timestamp information; the history file + functions know how to read and write timestamp information associated + with each entry. + +h. Four new key binding functions have been added: + + rl_bind_key_if_unbound() + rl_bind_key_if_unbound_in_map() + rl_bind_keyseq_if_unbound() + rl_bind_keyseq_if_unbound_in_map() + +i. New application variable, rl_completion_quote_character, set to any + quote character readline finds before it calls the application completion + function. + +j. New application variable, rl_completion_suppress_quote, settable by an + application completion function. If set to non-zero, readline does not + attempt to append a closing quote to a completed word. + +k. New application variable, rl_completion_found_quote, set to a non-zero + value if readline determines that the word to be completed is quoted. + Set before readline calls any application completion function. + +l. New function hook, rl_completion_word_break_hook, called when readline + needs to break a line into words when completion is attempted. Allows + the word break characters to vary based on position in the line. + +m. New bindable command: unix-filename-rubout. Does the same thing as + unix-word-rubout, but adds `/' to the set of word delimiters. + +n. When listing completions, directories have a `/' appended if the + `mark-directories' option has been enabled. + +------------------------------------------------------------------------------- This document details the changes between this version, readline-4.3, and the previous version, readline-4.2a. diff --git a/readline/ChangeLog.gdb b/readline/ChangeLog.gdb index e956193..c357426 100644 --- a/readline/ChangeLog.gdb +++ b/readline/ChangeLog.gdb @@ -1,3 +1,7 @@ +2006-04-24 Daniel Jacobowitz <dan@codesourcery.com> + + Imported readline 5.1, and upstream patches 001-004. + 2006-03-21 Denis Pilat <denis.pilat@st.com> * histfile.c (read_history_range): Remove '\r' character from diff --git a/readline/INSTALL b/readline/INSTALL index adb27a9..1a73c77 100644 --- a/readline/INSTALL +++ b/readline/INSTALL @@ -1,7 +1,7 @@ Basic Installation ================== -These are installation instructions for Readline-4.3. +These are installation instructions for Readline-5.1. The simplest way to compile readline is: @@ -238,6 +238,9 @@ SHLIB_XLDFLAGS Additional flags to pass to SHOBJ_LD for shared library SHLIB_LIBS Any additional libraries that shared libraries should be linked against when they are created. +SHLIB_LIBPREF The prefix to use when generating the filename of the shared + library. The default is `lib'; Cygwin uses `cyg'. + SHLIB_LIBSUFF The suffix to add to `libreadline' and `libhistory' when generating the filename of the shared library. Many systems use `so'; HP-UX uses `sl'. @@ -254,6 +257,17 @@ SHLIB_LIBVERSION The string to append to the filename to indicate the version numbers; use `$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' on those systems. Other Unix versions use different schemes. +SHLIB_DLLVERSION The version number for shared libraries that determines API + compatibility between readline versions and the underlying + system. Used only on Cygwin. Defaults to $SHLIB_MAJOR, but + can be overridden at configuration time by defining DLLVERSION + in the environment. + +SHLIB_DOT The character used to separate the name of the shared library + from the suffix and version information. The default is `.'; + systems like Cygwin which don't separate version information + from the library name should set this to the empty string. + SHLIB_STATUS Set this to `supported' when you have defined the other necessary variables. Make uses this to determine whether or not shared library creation should be attempted. If diff --git a/readline/MANIFEST b/readline/MANIFEST index 1507eda..b288fb6 100644 --- a/readline/MANIFEST +++ b/readline/MANIFEST @@ -3,6 +3,7 @@ # doc d examples d +examples/rlfe d support d shlib d COPYING f @@ -11,6 +12,7 @@ MANIFEST f INSTALL f CHANGELOG f CHANGES f +NEWS f USAGE f aclocal.m4 f config.h.in f @@ -74,23 +76,26 @@ histfile.c f histsearch.c f shlib/Makefile.in f support/config.guess f +support/config.rpath f support/config.sub f support/install.sh f support/mkdirs f support/mkdist f +support/mkinstalldirs f support/shobj-conf f support/shlib-install f support/wcwidth.c f doc/Makefile.in f doc/texinfo.tex f -doc/manvers.texinfo f -doc/rlman.texinfo f -doc/rltech.texinfo f -doc/rluser.texinfo f -doc/rluserman.texinfo f -doc/hist.texinfo f -doc/hstech.texinfo f -doc/hsuser.texinfo f +doc/version.texi f +doc/fdl.texi f +doc/rlman.texi f +doc/rltech.texi f +doc/rluser.texi f +doc/rluserman.texi f +doc/history.texi f +doc/hstech.texi f +doc/hsuser.texi f doc/readline.3 f doc/history.3 f doc/texi2dvi f @@ -100,13 +105,25 @@ examples/excallback.c f examples/fileman.c f examples/manexamp.c f examples/readlinebuf.h f +examples/rl-fgets.c f examples/rlcat.c f -examples/rlfe.c f examples/rltest.c f examples/rl.c f +examples/rlptytest.c f examples/rlversion.c f examples/histexamp.c f examples/Inputrc f +examples/rlfe/ChangeLog f +examples/rlfe/Makefile.in f +examples/rlfe/README f +examples/rlfe/config.h.in f +examples/rlfe/configure f +examples/rlfe/configure.in f +examples/rlfe/extern.h f +examples/rlfe/os.h f +examples/rlfe/pty.c f +examples/rlfe/rlfe.c f +examples/rlfe/screen.h f # formatted documentation, from MANIFEST.doc doc/readline.ps f doc/history.ps f @@ -124,3 +141,6 @@ doc/readline.0 f doc/history.0 f doc/readline_3.ps f doc/history_3.ps f +doc/history.pdf f +doc/readline.pdf f +doc/rluserman.pdf f diff --git a/readline/Makefile.in b/readline/Makefile.in index f039ec6..2dbd4bb 100644 --- a/readline/Makefile.in +++ b/readline/Makefile.in @@ -1,6 +1,6 @@ ## -*- text -*- ## # Master Makefile for the GNU readline library. -# Copyright (C) 1994, 1998 Free Software Foundation, Inc. +# Copyright (C) 1994-2004 Free Software Foundation, Inc. # 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 @@ -18,6 +18,14 @@ RL_LIBRARY_VERSION = @LIBVERSION@ RL_LIBRARY_NAME = readline +PACKAGE = @PACKAGE_NAME@ +VERSION = @PACKAGE_VERSION@ + +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_VERSION = @PACKAGE_VERSION@ + srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @@ -35,6 +43,8 @@ RM = rm -f CP = cp MV = mv +PURIFY = @PURIFY@ + @SET_MAKE@ SHELL = @MAKE_SHELL@ @@ -45,6 +55,8 @@ bindir = @bindir@ libdir = @libdir@ mandir = @mandir@ includedir = @includedir@ +datadir = @datadir@ +localedir = $(datadir)/locale infodir = @infodir@ @@ -61,7 +73,7 @@ CFLAGS = @CFLAGS@ LOCAL_CFLAGS = @LOCAL_CFLAGS@ -DRL_LIBRARY_VERSION='"$(RL_LIBRARY_VERSION)"' CPPFLAGS = @CPPFLAGS@ -DEFS = @DEFS@ +DEFS = @DEFS@ @CROSS_COMPILE@ LOCAL_DEFS = @LOCAL_DEFS@ TERMCAP_LIB = @TERMCAP_LIB@ @@ -211,7 +223,7 @@ uninstall-headers: maybe-uninstall-headers: uninstall-headers -## CYGNUS LOCAL +## GDB LOCAL ## Don't mess with people's installed readline's. ## This tries to install this version of readline over whatever ## version is already installed on the system (which could be a @@ -223,38 +235,42 @@ install: #install: $(INSTALL_TARGETS) -install-static: installdirs $(STATIC_LIBS) install-headers +install-static: installdirs $(STATIC_LIBS) install-headers install-doc -$(MV) $(DESTDIR)$(libdir)/libreadline.a $(DESTDIR)$(libdir)/libreadline.old $(INSTALL_DATA) libreadline.a $(DESTDIR)$(libdir)/libreadline.a -test -n "$(RANLIB)" && $(RANLIB) $(DESTDIR)$(libdir)/libreadline.a -$(MV) $(DESTDIR)$(libdir)/libhistory.a $(DESTDIR)$(libdir)/libhistory.old $(INSTALL_DATA) libhistory.a $(DESTDIR)$(libdir)/libhistory.a -test -n "$(RANLIB)" && $(RANLIB) $(DESTDIR)$(libdir)/libhistory.a - -( if test -d doc ; then \ - cd doc && \ - ${MAKE} ${MFLAGS} infodir=$(infodir) DESTDIR=${DESTDIR} install; \ - fi ) -installdirs: $(srcdir)/support/mkdirs - -$(SHELL) $(srcdir)/support/mkdirs $(DESTDIR)$(includedir) \ +installdirs: $(srcdir)/support/mkinstalldirs + -$(SHELL) $(srcdir)/support/mkinstalldirs $(DESTDIR)$(includedir) \ $(DESTDIR)$(includedir)/readline $(DESTDIR)$(libdir) \ $(DESTDIR)$(infodir) $(DESTDIR)$(man3dir) -uninstall: uninstall-headers +uninstall: uninstall-headers uninstall-doc -test -n "$(DESTDIR)$(libdir)" && cd $(DESTDIR)$(libdir) && \ ${RM} libreadline.a libreadline.old libhistory.a libhistory.old $(SHARED_LIBS) - -( if test -d doc ; then \ - cd doc && \ - ${MAKE} ${MFLAGS} infodir=$(infodir) DESTDIR=${DESTDIR} $@; \ - fi ) -( cd shlib; ${MAKE} ${MFLAGS} DESTDIR=${DESTDIR} uninstall ) -install-shared: installdirs install-headers shared +install-shared: installdirs install-headers shared install-doc -( cd shlib ; ${MAKE} ${MFLAGS} DESTDIR=${DESTDIR} install ) - + uninstall-shared: maybe-uninstall-headers -( cd shlib; ${MAKE} ${MFLAGS} DESTDIR=${DESTDIR} uninstall ) +install-doc: installdirs + -( if test -d doc ; then \ + cd doc && \ + ${MAKE} ${MFLAGS} infodir=$(infodir) DESTDIR=${DESTDIR} install; \ + fi ) + +uninstall-doc: + -( if test -d doc ; then \ + cd doc && \ + ${MAKE} ${MFLAGS} infodir=$(infodir) DESTDIR=${DESTDIR} uninstall; \ + fi ) + TAGS: force $(ETAGS) $(CSOURCES) $(HSOURCES) diff --git a/readline/README b/readline/README index 7aa9394..8dd09cc 100644 --- a/readline/README +++ b/readline/README @@ -1,7 +1,7 @@ Introduction ============ -This is the Gnu Readline library, version 4.3. +This is the Gnu Readline library, version 5.1. The Readline library provides a set of functions for use by applications that allow users to edit command lines as they are typed in. Both @@ -102,6 +102,9 @@ SHLIB_XLDFLAGS Additional flags to pass to SHOBJ_LD for shared library SHLIB_LIBS Any additional libraries that shared libraries should be linked against when they are created. +SHLIB_LIBPREF The prefix to use when generating the filename of the shared + library. The default is `lib'; Cygwin uses `cyg'. + SHLIB_LIBSUFF The suffix to add to `libreadline' and `libhistory' when generating the filename of the shared library. Many systems use `so'; HP-UX uses `sl'. @@ -118,6 +121,17 @@ SHLIB_LIBVERSION The string to append to the filename to indicate the version numbers; use `$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' on those systems. Other Unix versions use different schemes. +SHLIB_DLLVERSION The version number for shared libraries that determines API + compatibility between readline versions and the underlying + system. Used only on Cygwin. Defaults to $SHLIB_MAJOR, but + can be overridden at configuration time by defining DLLVERSION + in the environment. + +SHLIB_DOT The character used to separate the name of the shared library + from the suffix and version information. The default is `.'; + systems like Cygwin which don't separate version information + from the library name should set this to the empty string. + SHLIB_STATUS Set this to `supported' when you have defined the other necessary variables. Make uses this to determine whether or not shared library creation should be attempted. diff --git a/readline/acconfig.h b/readline/acconfig.h deleted file mode 100644 index 577cf9c..0000000 --- a/readline/acconfig.h +++ /dev/null @@ -1,56 +0,0 @@ -/* acconfig.h - This file is in the public domain. - - Descriptive text for the C preprocessor macros that - the distributed Autoconf macros can define. - No software package will use all of them; autoheader copies the ones - your configure.in uses into your configuration header file templates. - - The entries are in sort -df order: alphabetical, case insensitive, - ignoring punctuation (such as underscores). Although this order - can split up related entries, it makes it easier to check whether - a given entry is in the file. - - Leave the following blank line there!! Autoheader needs it. */ - - -/* Definitions pulled in from aclocal.m4. */ -#undef VOID_SIGHANDLER - -#undef GWINSZ_IN_SYS_IOCTL - -#undef TIOCSTAT_IN_SYS_IOCTL - -#undef HAVE_GETPW_DECLS - -#undef FIONREAD_IN_SYS_IOCTL - -#undef HAVE_BSD_SIGNALS - -#undef HAVE_LSTAT - -#undef HAVE_POSIX_SIGNALS - -#undef HAVE_POSIX_SIGSETJMP - -#undef HAVE_USG_SIGHOLD - -#undef MUST_REINSTALL_SIGHANDLERS - -#undef SPEED_T_IN_SYS_TYPES - -#undef STRCOLL_BROKEN - -#undef STRUCT_DIRENT_HAS_D_FILENO - -#undef STRUCT_DIRENT_HAS_D_INO - -#undef STRUCT_WINSIZE_IN_SYS_IOCTL - -#undef STRUCT_WINSIZE_IN_TERMIOS - - -/* Leave that blank line there!! Autoheader needs it. - If you're adding to this file, keep in mind: - The entries are in sort -df order: alphabetical, case insensitive, - ignoring punctuation (such as underscores). */ diff --git a/readline/aclocal.m4 b/readline/aclocal.m4 index 35613c2..485ca49 100644 --- a/readline/aclocal.m4 +++ b/readline/aclocal.m4 @@ -685,65 +685,26 @@ fi ]) AC_DEFUN(BASH_FUNC_GETCWD, -[AC_MSG_CHECKING([if getcwd() calls popen()]) -AC_CACHE_VAL(bash_cv_getcwd_calls_popen, +[AC_MSG_CHECKING([if getcwd() will dynamically allocate memory]) +AC_CACHE_VAL(bash_cv_getcwd_malloc, [AC_TRY_RUN([ #include <stdio.h> #ifdef HAVE_UNISTD_H #include <unistd.h> #endif -#ifndef __STDC__ -#ifndef const -#define const -#endif -#endif - -int popen_called; - -FILE * -popen(command, type) - const char *command; - const char *type; -{ - popen_called = 1; - return (FILE *)NULL; -} - -FILE *_popen(command, type) - const char *command; - const char *type; -{ - return (popen (command, type)); -} - -int -pclose(stream) -FILE *stream; -{ - return 0; -} - -int -_pclose(stream) -FILE *stream; -{ - return 0; -} - main() { - char lbuf[32]; - popen_called = 0; - getcwd(lbuf, 32); - exit (popen_called); + char *xpwd; + xpwd = getcwd(0, 0); + exit (xpwd == 0); } -], bash_cv_getcwd_calls_popen=no, bash_cv_getcwd_calls_popen=yes, - [AC_MSG_WARN(cannot check whether getcwd calls popen if cross compiling -- defaulting to no) - bash_cv_getcwd_calls_popen=no] +], bash_cv_getcwd_malloc=yes, bash_cv_getcwd_malloc=no, + [AC_MSG_WARN(cannot check whether getcwd allocates memory when cross-compiling -- defaulting to no) + bash_cv_getcwd_malloc=no] )]) -AC_MSG_RESULT($bash_cv_getcwd_calls_popen) -if test $bash_cv_getcwd_calls_popen = yes; then +AC_MSG_RESULT($bash_cv_getcwd_malloc) +if test $bash_cv_getcwd_malloc = no; then AC_DEFINE(GETCWD_BROKEN) AC_LIBOBJ(getcwd) fi @@ -981,11 +942,12 @@ AC_MSG_CHECKING(which library has the termcap functions) _bash_needmsg= fi AC_CACHE_VAL(bash_cv_termcap_lib, -[AC_CHECK_LIB(termcap, tgetent, bash_cv_termcap_lib=libtermcap, +[AC_CHECK_FUNC(tgetent, bash_cv_termcap_lib=libc, + [AC_CHECK_LIB(termcap, tgetent, bash_cv_termcap_lib=libtermcap, [AC_CHECK_LIB(tinfo, tgetent, bash_cv_termcap_lib=libtinfo, [AC_CHECK_LIB(curses, tgetent, bash_cv_termcap_lib=libcurses, [AC_CHECK_LIB(ncurses, tgetent, bash_cv_termcap_lib=libncurses, - bash_cv_termcap_lib=gnutermcap)])])])]) + bash_cv_termcap_lib=gnutermcap)])])])])]) if test "X$_bash_needmsg" = "Xyes"; then AC_MSG_CHECKING(which library has the termcap functions) fi @@ -1003,6 +965,9 @@ TERMCAP_DEP= elif test $bash_cv_termcap_lib = libncurses; then TERMCAP_LIB=-lncurses TERMCAP_DEP= +elif test $bash_cv_termcap_lib = libc; then +TERMCAP_LIB= +TERMCAP_DEP= else TERMCAP_LIB=-lcurses TERMCAP_DEP= @@ -1061,7 +1026,7 @@ fi AC_DEFUN(BASH_STRUCT_DIRENT_D_INO, [AC_REQUIRE([AC_HEADER_DIRENT]) -AC_MSG_CHECKING(if struct dirent has a d_ino member) +AC_MSG_CHECKING(for struct dirent.d_ino) AC_CACHE_VAL(bash_cv_dirent_has_dino, [AC_TRY_COMPILE([ #include <stdio.h> @@ -1088,13 +1053,13 @@ struct dirent d; int z; z = d.d_ino; ], bash_cv_dirent_has_dino=yes, bash_cv_dirent_has_dino=no)]) AC_MSG_RESULT($bash_cv_dirent_has_dino) if test $bash_cv_dirent_has_dino = yes; then -AC_DEFINE(STRUCT_DIRENT_HAS_D_INO) +AC_DEFINE(HAVE_STRUCT_DIRENT_D_INO) fi ]) AC_DEFUN(BASH_STRUCT_DIRENT_D_FILENO, [AC_REQUIRE([AC_HEADER_DIRENT]) -AC_MSG_CHECKING(if struct dirent has a d_fileno member) +AC_MSG_CHECKING(for struct dirent.d_fileno) AC_CACHE_VAL(bash_cv_dirent_has_d_fileno, [AC_TRY_COMPILE([ #include <stdio.h> @@ -1121,7 +1086,40 @@ struct dirent d; int z; z = d.d_fileno; ], bash_cv_dirent_has_d_fileno=yes, bash_cv_dirent_has_d_fileno=no)]) AC_MSG_RESULT($bash_cv_dirent_has_d_fileno) if test $bash_cv_dirent_has_d_fileno = yes; then -AC_DEFINE(STRUCT_DIRENT_HAS_D_FILENO) +AC_DEFINE(HAVE_STRUCT_DIRENT_D_FILENO) +fi +]) + +AC_DEFUN(BASH_STRUCT_DIRENT_D_NAMLEN, +[AC_REQUIRE([AC_HEADER_DIRENT]) +AC_MSG_CHECKING(for struct dirent.d_namlen) +AC_CACHE_VAL(bash_cv_dirent_has_d_namlen, +[AC_TRY_COMPILE([ +#include <stdio.h> +#include <sys/types.h> +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#if defined(HAVE_DIRENT_H) +# include <dirent.h> +#else +# define dirent direct +# ifdef HAVE_SYS_NDIR_H +# include <sys/ndir.h> +# endif /* SYSNDIR */ +# ifdef HAVE_SYS_DIR_H +# include <sys/dir.h> +# endif /* SYSDIR */ +# ifdef HAVE_NDIR_H +# include <ndir.h> +# endif +#endif /* HAVE_DIRENT_H */ +],[ +struct dirent d; int z; z = d.d_namlen; +], bash_cv_dirent_has_d_namlen=yes, bash_cv_dirent_has_d_namlen=no)]) +AC_MSG_RESULT($bash_cv_dirent_has_d_namlen) +if test $bash_cv_dirent_has_d_namlen = yes; then +AC_DEFINE(HAVE_STRUCT_DIRENT_D_NAMLEN) fi ]) @@ -1141,6 +1139,22 @@ if test $bash_cv_struct_timeval = yes; then fi ]) +AC_DEFUN(BASH_STRUCT_TIMEZONE, +[AC_MSG_CHECKING(for struct timezone in sys/time.h and time.h) +AC_CACHE_VAL(bash_cv_struct_timezone, +[ +AC_EGREP_HEADER(struct timezone, sys/time.h, + bash_cv_struct_timezone=yes, + AC_EGREP_HEADER(struct timezone, time.h, + bash_cv_struct_timezone=yes, + bash_cv_struct_timezone=no)) +]) +AC_MSG_RESULT($bash_cv_struct_timezone) +if test $bash_cv_struct_timezone = yes; then + AC_DEFINE(HAVE_STRUCT_TIMEZONE) +fi +]) + AC_DEFUN(BASH_STRUCT_WINSIZE, [AC_MSG_CHECKING(for struct winsize in sys/ioctl.h and termios.h) AC_CACHE_VAL(bash_cv_struct_winsize_header, @@ -1526,9 +1540,16 @@ fi AC_DEFUN(BASH_CHECK_DEV_FD, [AC_MSG_CHECKING(whether /dev/fd is available) AC_CACHE_VAL(bash_cv_dev_fd, -[if test -d /dev/fd && test -r /dev/fd/0; then - bash_cv_dev_fd=standard - elif test -d /proc/self/fd && test -r /proc/self/fd/0; then +[if test -d /dev/fd && test -r /dev/fd/0 < /dev/null; then +# check for systems like FreeBSD 5 that only provide /dev/fd/[012] + exec 3<&0 + if test -r /dev/fd/3; then + bash_cv_dev_fd=standard + else + bash_cv_dev_fd=absent + fi + exec 3<&- + elif test -d /proc/self/fd && test -r /proc/self/fd/0 < /dev/null; then bash_cv_dev_fd=whacky else bash_cv_dev_fd=absent @@ -1547,9 +1568,9 @@ fi AC_DEFUN(BASH_CHECK_DEV_STDIN, [AC_MSG_CHECKING(whether /dev/stdin stdout stderr are available) AC_CACHE_VAL(bash_cv_dev_stdin, -[if test -d /dev/fd && test -r /dev/stdin; then +[if test -d /dev/fd && test -r /dev/stdin < /dev/null; then bash_cv_dev_stdin=present - elif test -d /proc/self/fd && test -r /dev/stdin; then + elif test -d /proc/self/fd && test -r /dev/stdin < /dev/null; then bash_cv_dev_stdin=present else bash_cv_dev_stdin=absent @@ -1652,9 +1673,13 @@ AC_CHECK_HEADERS(wctype.h) AC_CHECK_HEADERS(wchar.h) AC_CHECK_HEADERS(langinfo.h) -AC_CHECK_FUNC(mbrtowc, AC_DEFINE(HAVE_MBRTOWC)) AC_CHECK_FUNC(mbsrtowcs, AC_DEFINE(HAVE_MBSRTOWCS)) +AC_CHECK_FUNC(mbrtowc, AC_DEFINE(HAVE_MBRTOWC)) +AC_CHECK_FUNC(mbrlen, AC_DEFINE(HAVE_MBRLEN)) +AC_CHECK_FUNC(wctomb, AC_DEFINE(HAVE_WCTOMB)) AC_CHECK_FUNC(wcwidth, AC_DEFINE(HAVE_WCWIDTH)) +AC_CHECK_FUNC(wcsdup, AC_DEFINE(HAVE_WCSDUP)) + if test "$ac_cv_func_wcwidth" = no && test "$ac_cv_header_wchar_h" = yes; then WCWIDTH_OBJ=wcwidth.o else @@ -1663,14 +1688,12 @@ fi AC_SUBST(WCWIDTH_OBJ) AC_CACHE_CHECK([for mbstate_t], bash_cv_have_mbstate_t, -[AC_TRY_LINK( -[#include <wchar.h>], -[int -main () -{ +[AC_TRY_COMPILE([ +#include <wchar.h>], [ mbstate_t ps; - return 0; -}], bash_cv_have_mbstate_t=yes, bash_cv_have_mbstate_t=no)]) + mbstate_t *psp; + psp = (mbstate_t *)0; +], bash_cv_have_mbstate_t=yes, bash_cv_have_mbstate_t=no)]) if test $bash_cv_have_mbstate_t = yes; then AC_DEFINE(HAVE_MBSTATE_T) fi @@ -1719,23 +1742,30 @@ LIBS="$LIBS -lreadline ${TERMCAP_LIB}" CFLAGS="$CFLAGS -I${ac_cv_rl_includedir}" LDFLAGS="$LDFLAGS -L${ac_cv_rl_libdir}" -AC_TRY_RUN([ +AC_CACHE_VAL(ac_cv_rl_version, +[AC_TRY_RUN([ #include <stdio.h> #include <readline/readline.h> +extern int rl_gnu_readline_p; + main() { FILE *fp; fp = fopen("conftest.rlv", "w"); - if (fp == 0) exit(1); - fprintf(fp, "%s\n", rl_library_version ? rl_library_version : "0.0"); + if (fp == 0) + exit(1); + if (rl_gnu_readline_p != 1) + fprintf(fp, "0.0\n"); + else + fprintf(fp, "%s\n", rl_library_version ? rl_library_version : "0.0"); fclose(fp); exit(0); } ], ac_cv_rl_version=`cat conftest.rlv`, ac_cv_rl_version='0.0', -ac_cv_rl_version='4.2') +ac_cv_rl_version='4.2')]) CFLAGS="$_save_CFLAGS" LDFLAGS="$_save_LDFLAGS" @@ -1797,3 +1827,2140 @@ AC_MSG_RESULT($ac_cv_rl_version) fi ]) + +AC_DEFUN(BASH_FUNC_CTYPE_NONASCII, +[ +AC_MSG_CHECKING(whether the ctype macros accept non-ascii characters) +AC_CACHE_VAL(bash_cv_func_ctype_nonascii, +[AC_TRY_RUN([ +#ifdef HAVE_LOCALE_H +#include <locale.h> +#endif +#include <stdio.h> +#include <ctype.h> + +main(c, v) +int c; +char *v[]; +{ + char *deflocale; + unsigned char x; + int r1, r2; + +#ifdef HAVE_SETLOCALE + /* We take a shot here. If that locale is not known, try the + system default. We try this one because '\342' (226) is + known to be a printable character in that locale. */ + deflocale = setlocale(LC_ALL, "en_US.ISO8859-1"); + if (deflocale == 0) + deflocale = setlocale(LC_ALL, ""); +#endif + + x = '\342'; + r1 = isprint(x); + x -= 128; + r2 = isprint(x); + exit (r1 == 0 || r2 == 0); +} +], bash_cv_func_ctype_nonascii=yes, bash_cv_func_ctype_nonascii=no, + [AC_MSG_WARN(cannot check ctype macros if cross compiling -- defaulting to no) + bash_cv_func_ctype_nonascii=no] +)]) +AC_MSG_RESULT($bash_cv_func_ctype_nonascii) +if test $bash_cv_func_ctype_nonascii = yes; then +AC_DEFINE(CTYPE_NON_ASCII) +fi +]) + +AC_DEFUN(BASH_CHECK_WCONTINUED, +[ +AC_MSG_CHECKING(whether WCONTINUED flag to waitpid is unavailable or available but broken) +AC_CACHE_VAL(bash_cv_wcontinued_broken, +[AC_TRY_RUN([ +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +#include <errno.h> + +#ifndef errno +extern int errno; +#endif +main() +{ + int x; + + x = waitpid(-1, (int *)0, WNOHANG|WCONTINUED); + if (x == -1 && errno == EINVAL) + exit (1); + else + exit (0); +} +], bash_cv_wcontinued_broken=no,bash_cv_wcontinued_broken=yes, + [AC_MSG_WARN(cannot check WCONTINUED if cross compiling -- defaulting to no) + bash_cv_wcontinued_broken=no] +)]) +AC_MSG_RESULT($bash_cv_wcontinued_broken) +if test $bash_cv_wcontinued_broken = yes; then +AC_DEFINE(WCONTINUED_BROKEN) +fi +]) + +dnl +dnl tests added for bashdb +dnl + + +AC_DEFUN([AM_PATH_LISPDIR], + [AC_ARG_WITH(lispdir, AC_HELP_STRING([--with-lispdir], [override the default lisp directory]), + [ lispdir="$withval" + AC_MSG_CHECKING([where .elc files should go]) + AC_MSG_RESULT([$lispdir])], + [ + # If set to t, that means we are running in a shell under Emacs. + # If you have an Emacs named "t", then use the full path. + test x"$EMACS" = xt && EMACS= + AC_CHECK_PROGS(EMACS, emacs xemacs, no) + if test $EMACS != "no"; then + if test x${lispdir+set} != xset; then + AC_CACHE_CHECK([where .elc files should go], [am_cv_lispdir], [dnl + am_cv_lispdir=`$EMACS -batch -q -eval '(while load-path (princ (concat (car load-path) "\n")) (setq load-path (cdr load-path)))' | sed -n -e 's,/$,,' -e '/.*\/lib\/\(x\?emacs\/site-lisp\)$/{s,,${libdir}/\1,;p;q;}' -e '/.*\/share\/\(x\?emacs\/site-lisp\)$/{s,,${datadir}/\1,;p;q;}'` + if test -z "$am_cv_lispdir"; then + am_cv_lispdir='${datadir}/emacs/site-lisp' + fi + ]) + lispdir="$am_cv_lispdir" + fi + fi + ]) + AC_SUBST(lispdir) +]) + +dnl +dnl tests added for gettext +dnl +# codeset.m4 serial AM1 (gettext-0.10.40) +dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +AC_DEFUN([AM_LANGINFO_CODESET], +[ + AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset, + [AC_TRY_LINK([#include <langinfo.h>], + [char* cs = nl_langinfo(CODESET);], + am_cv_langinfo_codeset=yes, + am_cv_langinfo_codeset=no) + ]) + if test $am_cv_langinfo_codeset = yes; then + AC_DEFINE(HAVE_LANGINFO_CODESET, 1, + [Define if you have <langinfo.h> and nl_langinfo(CODESET).]) + fi +]) +# gettext.m4 serial 20 (gettext-0.12) +dnl Copyright (C) 1995-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000. +dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003. + +dnl Macro to add for using GNU gettext. + +dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). +dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The +dnl default (if it is not specified or empty) is 'no-libtool'. +dnl INTLSYMBOL should be 'external' for packages with no intl directory, +dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory. +dnl If INTLSYMBOL is 'use-libtool', then a libtool library +dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, +dnl depending on --{enable,disable}-{shared,static} and on the presence of +dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library +dnl $(top_builddir)/intl/libintl.a will be created. +dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext +dnl implementations (in libc or libintl) without the ngettext() function +dnl will be ignored. If NEEDSYMBOL is specified and is +dnl 'need-formatstring-macros', then GNU gettext implementations that don't +dnl support the ISO C 99 <inttypes.h> formatstring macros will be ignored. +dnl INTLDIR is used to find the intl libraries. If empty, +dnl the value `$(top_builddir)/intl/' is used. +dnl +dnl The result of the configuration is one of three cases: +dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled +dnl and used. +dnl Catalog format: GNU --> install in $(datadir) +dnl Catalog extension: .mo after installation, .gmo in source tree +dnl 2) GNU gettext has been found in the system's C library. +dnl Catalog format: GNU --> install in $(datadir) +dnl Catalog extension: .mo after installation, .gmo in source tree +dnl 3) No internationalization, always use English msgid. +dnl Catalog format: none +dnl Catalog extension: none +dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. +dnl The use of .gmo is historical (it was needed to avoid overwriting the +dnl GNU format catalogs when building on a platform with an X/Open gettext), +dnl but we keep it in order not to force irrelevant filename changes on the +dnl maintainers. +dnl +AC_DEFUN([AM_GNU_GETTEXT], +[ + dnl Argument checking. + ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], , + [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT +])])])])]) + ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , + [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT +])])])]) + define(gt_included_intl, ifelse([$1], [external], [no], [yes])) + define(gt_libtool_suffix_prefix, ifelse([$1], [use-libtool], [l], [])) + + AC_REQUIRE([AM_PO_SUBDIRS])dnl + ifelse(gt_included_intl, yes, [ + AC_REQUIRE([AM_INTL_SUBDIR])dnl + ]) + + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Sometimes libintl requires libiconv, so first search for libiconv. + dnl Ideally we would do this search only after the + dnl if test "$USE_NLS" = "yes"; then + dnl if test "$gt_cv_func_gnugettext_libc" != "yes"; then + dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT + dnl the configure script would need to contain the same shell code + dnl again, outside any 'if'. There are two solutions: + dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. + dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. + dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not + dnl documented, we avoid it. + ifelse(gt_included_intl, yes, , [ + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + ]) + + dnl Set USE_NLS. + AM_NLS + + ifelse(gt_included_intl, yes, [ + BUILD_INCLUDED_LIBINTL=no + USE_INCLUDED_LIBINTL=no + ]) + LIBINTL= + LTLIBINTL= + POSUB= + + dnl If we use NLS figure out what method + if test "$USE_NLS" = "yes"; then + gt_use_preinstalled_gnugettext=no + ifelse(gt_included_intl, yes, [ + AC_MSG_CHECKING([whether included gettext is requested]) + AC_ARG_WITH(included-gettext, + [ --with-included-gettext use the GNU gettext library included here], + nls_cv_force_use_gnu_gettext=$withval, + nls_cv_force_use_gnu_gettext=no) + AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) + + nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" + if test "$nls_cv_force_use_gnu_gettext" != "yes"; then + ]) + dnl User does not insist on using GNU NLS library. Figure out what + dnl to use. If GNU gettext is available we use this. Else we have + dnl to fall back to GNU NLS library. + + dnl Add a version number to the cache macros. + define([gt_api_version], ifelse([$2], [need-formatstring-macros], 3, ifelse([$2], [need-ngettext], 2, 1))) + define([gt_cv_func_gnugettext_libc], [gt_cv_func_gnugettext]gt_api_version[_libc]) + define([gt_cv_func_gnugettext_libintl], [gt_cv_func_gnugettext]gt_api_version[_libintl]) + + AC_CACHE_CHECK([for GNU gettext in libc], gt_cv_func_gnugettext_libc, + [AC_TRY_LINK([#include <libintl.h> +]ifelse([$2], [need-formatstring-macros], +[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +changequote(,)dnl +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +changequote([,])dnl +], [])[extern int _nl_msg_cat_cntr; +extern int *_nl_domain_bindings;], + [bindtextdomain ("", ""); +return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_domain_bindings], + gt_cv_func_gnugettext_libc=yes, + gt_cv_func_gnugettext_libc=no)]) + + if test "$gt_cv_func_gnugettext_libc" != "yes"; then + dnl Sometimes libintl requires libiconv, so first search for libiconv. + ifelse(gt_included_intl, yes, , [ + AM_ICONV_LINK + ]) + dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL + dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) + dnl because that would add "-liconv" to LIBINTL and LTLIBINTL + dnl even if libiconv doesn't exist. + AC_LIB_LINKFLAGS_BODY([intl]) + AC_CACHE_CHECK([for GNU gettext in libintl], + gt_cv_func_gnugettext_libintl, + [gt_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $INCINTL" + gt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBINTL" + dnl Now see whether libintl exists and does not depend on libiconv. + AC_TRY_LINK([#include <libintl.h> +]ifelse([$2], [need-formatstring-macros], +[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +changequote(,)dnl +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +changequote([,])dnl +], [])[extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias ();], + [bindtextdomain ("", ""); +return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], + gt_cv_func_gnugettext_libintl=yes, + gt_cv_func_gnugettext_libintl=no) + dnl Now see whether libintl exists and depends on libiconv. + if test "$gt_cv_func_gnugettext_libintl" != yes && test -n "$LIBICONV"; then + LIBS="$LIBS $LIBICONV" + AC_TRY_LINK([#include <libintl.h> +]ifelse([$2], [need-formatstring-macros], +[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +changequote(,)dnl +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +changequote([,])dnl +], [])[extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias ();], + [bindtextdomain ("", ""); +return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], + [LIBINTL="$LIBINTL $LIBICONV" + LTLIBINTL="$LTLIBINTL $LTLIBICONV" + gt_cv_func_gnugettext_libintl=yes + ]) + fi + CPPFLAGS="$gt_save_CPPFLAGS" + LIBS="$gt_save_LIBS"]) + fi + + dnl If an already present or preinstalled GNU gettext() is found, + dnl use it. But if this macro is used in GNU gettext, and GNU + dnl gettext is already preinstalled in libintl, we update this + dnl libintl. (Cf. the install rule in intl/Makefile.in.) + if test "$gt_cv_func_gnugettext_libc" = "yes" \ + || { test "$gt_cv_func_gnugettext_libintl" = "yes" \ + && test "$PACKAGE" != gettext-runtime \ + && test "$PACKAGE" != gettext-tools; }; then + gt_use_preinstalled_gnugettext=yes + else + dnl Reset the values set by searching for libintl. + LIBINTL= + LTLIBINTL= + INCINTL= + fi + + ifelse(gt_included_intl, yes, [ + if test "$gt_use_preinstalled_gnugettext" != "yes"; then + dnl GNU gettext is not found in the C library. + dnl Fall back on included GNU gettext library. + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions used to generate GNU NLS library. + BUILD_INCLUDED_LIBINTL=yes + USE_INCLUDED_LIBINTL=yes + LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV" + LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV" + LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` + fi + + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions to use GNU gettext tools. + CATOBJEXT=.gmo + fi + ]) + + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + AC_DEFINE(ENABLE_NLS, 1, + [Define to 1 if translation of program messages to the user's native language + is requested.]) + else + USE_NLS=no + fi + fi + + AC_MSG_CHECKING([whether to use NLS]) + AC_MSG_RESULT([$USE_NLS]) + if test "$USE_NLS" = "yes"; then + AC_MSG_CHECKING([where the gettext function comes from]) + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if test "$gt_cv_func_gnugettext_libintl" = "yes"; then + gt_source="external libintl" + else + gt_source="libc" + fi + else + gt_source="included intl directory" + fi + AC_MSG_RESULT([$gt_source]) + fi + + if test "$USE_NLS" = "yes"; then + + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if test "$gt_cv_func_gnugettext_libintl" = "yes"; then + AC_MSG_CHECKING([how to link with libintl]) + AC_MSG_RESULT([$LIBINTL]) + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) + fi + + dnl For backward compatibility. Some packages may be using this. + AC_DEFINE(HAVE_GETTEXT, 1, + [Define if the GNU gettext() function is already present or preinstalled.]) + AC_DEFINE(HAVE_DCGETTEXT, 1, + [Define if the GNU dcgettext() function is already present or preinstalled.]) + fi + + dnl We need to process the po/ directory. + POSUB=po + fi + + ifelse(gt_included_intl, yes, [ + dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL + dnl to 'yes' because some of the testsuite requires it. + if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then + BUILD_INCLUDED_LIBINTL=yes + fi + + dnl Make all variables we use known to autoconf. + AC_SUBST(BUILD_INCLUDED_LIBINTL) + AC_SUBST(USE_INCLUDED_LIBINTL) + AC_SUBST(CATOBJEXT) + + dnl For backward compatibility. Some configure.ins may be using this. + nls_cv_header_intl= + nls_cv_header_libgt= + + dnl For backward compatibility. Some Makefiles may be using this. + DATADIRNAME=share + AC_SUBST(DATADIRNAME) + + dnl For backward compatibility. Some Makefiles may be using this. + INSTOBJEXT=.mo + AC_SUBST(INSTOBJEXT) + + dnl For backward compatibility. Some Makefiles may be using this. + GENCAT=gencat + AC_SUBST(GENCAT) + + dnl For backward compatibility. Some Makefiles may be using this. + if test "$USE_INCLUDED_LIBINTL" = yes; then + INTLOBJS="\$(GETTOBJS)" + fi + AC_SUBST(INTLOBJS) + + dnl Enable libtool support if the surrounding package wishes it. + INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix + AC_SUBST(INTL_LIBTOOL_SUFFIX_PREFIX) + ]) + + dnl For backward compatibility. Some Makefiles may be using this. + INTLLIBS="$LIBINTL" + AC_SUBST(INTLLIBS) + + dnl Make all documented variables known to autoconf. + AC_SUBST(LIBINTL) + AC_SUBST(LTLIBINTL) + AC_SUBST(POSUB) +]) + + +dnl Checks for all prerequisites of the intl subdirectory, +dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS, +dnl USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL. +AC_DEFUN([AM_INTL_SUBDIR], +[ + AC_REQUIRE([AC_PROG_INSTALL])dnl + AC_REQUIRE([AM_MKINSTALLDIRS])dnl + AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_CANONICAL_HOST])dnl + AC_REQUIRE([AC_PROG_RANLIB])dnl + AC_REQUIRE([AC_ISC_POSIX])dnl + AC_REQUIRE([AC_HEADER_STDC])dnl + AC_REQUIRE([AC_C_CONST])dnl + AC_REQUIRE([AC_C_INLINE])dnl + AC_REQUIRE([AC_TYPE_OFF_T])dnl + AC_REQUIRE([AC_TYPE_SIZE_T])dnl + AC_REQUIRE([AC_FUNC_ALLOCA])dnl + AC_REQUIRE([AC_FUNC_MMAP])dnl + AC_REQUIRE([jm_GLIBC21])dnl + AC_REQUIRE([gt_INTDIV0])dnl + AC_REQUIRE([jm_AC_TYPE_UINTMAX_T])dnl + AC_REQUIRE([gt_HEADER_INTTYPES_H])dnl + AC_REQUIRE([gt_INTTYPES_PRI])dnl + + AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h stddef.h \ +stdlib.h string.h unistd.h sys/param.h]) + AC_CHECK_FUNCS([feof_unlocked fgets_unlocked getc_unlocked getcwd getegid \ +geteuid getgid getuid mempcpy munmap putenv setenv setlocale stpcpy \ +strcasecmp strdup strtoul tsearch __argz_count __argz_stringify __argz_next \ +__fsetlocking]) + + AM_ICONV + AM_LANGINFO_CODESET + if test $ac_cv_header_locale_h = yes; then + AM_LC_MESSAGES + fi + + dnl intl/plural.c is generated from intl/plural.y. It requires bison, + dnl because plural.y uses bison specific features. It requires at least + dnl bison-1.26 because earlier versions generate a plural.c that doesn't + dnl compile. + dnl bison is only needed for the maintainer (who touches plural.y). But in + dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put + dnl the rule in general Makefile. Now, some people carelessly touch the + dnl files or have a broken "make" program, hence the plural.c rule will + dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not + dnl present or too old. + AC_CHECK_PROGS([INTLBISON], [bison]) + if test -z "$INTLBISON"; then + ac_verc_fail=yes + else + dnl Found it, now check the version. + AC_MSG_CHECKING([version of bison]) +changequote(<<,>>)dnl + ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'` + case $ac_prog_version in + '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; + 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*) +changequote([,])dnl + ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; + *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; + esac + AC_MSG_RESULT([$ac_prog_version]) + fi + if test $ac_verc_fail = yes; then + INTLBISON=: + fi +]) + + +dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) +AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) +# glibc21.m4 serial 2 (fileutils-4.1.3, gettext-0.10.40) +dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +# Test for the GNU C Library, version 2.1 or newer. +# From Bruno Haible. + +AC_DEFUN([jm_GLIBC21], + [ + AC_CACHE_CHECK(whether we are using the GNU C Library 2.1 or newer, + ac_cv_gnu_library_2_1, + [AC_EGREP_CPP([Lucky GNU user], + [ +#include <features.h> +#ifdef __GNU_LIBRARY__ + #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) + Lucky GNU user + #endif +#endif + ], + ac_cv_gnu_library_2_1=yes, + ac_cv_gnu_library_2_1=no) + ] + ) + AC_SUBST(GLIBC21) + GLIBC21="$ac_cv_gnu_library_2_1" + ] +) +# iconv.m4 serial AM4 (gettext-0.11.3) +dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], +[ + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([iconv]) +]) + +AC_DEFUN([AM_ICONV_LINK], +[ + dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and + dnl those with the standalone portable GNU libiconv installed). + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + + dnl Add $INCICONV to CPPFLAGS before performing the following checks, + dnl because if the user has installed libiconv and not disabled its use + dnl via --without-libiconv-prefix, he wants to use it. The first + dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed. + am_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) + + AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [ + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + AC_TRY_LINK([#include <stdlib.h> +#include <iconv.h>], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + am_cv_func_iconv=yes) + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + AC_TRY_LINK([#include <stdlib.h> +#include <iconv.h>], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + am_cv_lib_iconv=yes + am_cv_func_iconv=yes) + LIBS="$am_save_LIBS" + fi + ]) + if test "$am_cv_func_iconv" = yes; then + AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.]) + fi + if test "$am_cv_lib_iconv" = yes; then + AC_MSG_CHECKING([how to link with libiconv]) + AC_MSG_RESULT([$LIBICONV]) + else + dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV + dnl either. + CPPFLAGS="$am_save_CPPFLAGS" + LIBICONV= + LTLIBICONV= + fi + AC_SUBST(LIBICONV) + AC_SUBST(LTLIBICONV) +]) + +AC_DEFUN([AM_ICONV], +[ + AM_ICONV_LINK + if test "$am_cv_func_iconv" = yes; then + AC_MSG_CHECKING([for iconv declaration]) + AC_CACHE_VAL(am_cv_proto_iconv, [ + AC_TRY_COMPILE([ +#include <stdlib.h> +#include <iconv.h> +extern +#ifdef __cplusplus +"C" +#endif +#if defined(__STDC__) || defined(__cplusplus) +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); +#else +size_t iconv(); +#endif +], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const") + am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) + am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` + AC_MSG_RESULT([$]{ac_t:- + }[$]am_cv_proto_iconv) + AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, + [Define as const if the declaration of iconv() needs const.]) + fi +]) +# intdiv0.m4 serial 1 (gettext-0.11.3) +dnl Copyright (C) 2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +AC_DEFUN([gt_INTDIV0], +[ + AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_CANONICAL_HOST])dnl + + AC_CACHE_CHECK([whether integer division by zero raises SIGFPE], + gt_cv_int_divbyzero_sigfpe, + [ + AC_TRY_RUN([ +#include <stdlib.h> +#include <signal.h> + +static void +#ifdef __cplusplus +sigfpe_handler (int sig) +#else +sigfpe_handler (sig) int sig; +#endif +{ + /* Exit with code 0 if SIGFPE, with code 1 if any other signal. */ + exit (sig != SIGFPE); +} + +int x = 1; +int y = 0; +int z; +int nan; + +int main () +{ + signal (SIGFPE, sigfpe_handler); +/* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP. */ +#if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP) + signal (SIGTRAP, sigfpe_handler); +#endif +/* Linux/SPARC yields signal SIGILL. */ +#if defined (__sparc__) && defined (__linux__) + signal (SIGILL, sigfpe_handler); +#endif + + z = x / y; + nan = y / y; + exit (1); +} +], gt_cv_int_divbyzero_sigfpe=yes, gt_cv_int_divbyzero_sigfpe=no, + [ + # Guess based on the CPU. + case "$host_cpu" in + alpha* | i[34567]86 | m68k | s390*) + gt_cv_int_divbyzero_sigfpe="guessing yes";; + *) + gt_cv_int_divbyzero_sigfpe="guessing no";; + esac + ]) + ]) + case "$gt_cv_int_divbyzero_sigfpe" in + *yes) value=1;; + *) value=0;; + esac + AC_DEFINE_UNQUOTED(INTDIV0_RAISES_SIGFPE, $value, + [Define if integer division by zero raises signal SIGFPE.]) +]) +# inttypes.m4 serial 1 (gettext-0.11.4) +dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Paul Eggert. + +# Define HAVE_INTTYPES_H if <inttypes.h> exists and doesn't clash with +# <sys/types.h>. + +AC_DEFUN([gt_HEADER_INTTYPES_H], +[ + AC_CACHE_CHECK([for inttypes.h], gt_cv_header_inttypes_h, + [ + AC_TRY_COMPILE( + [#include <sys/types.h> +#include <inttypes.h>], + [], gt_cv_header_inttypes_h=yes, gt_cv_header_inttypes_h=no) + ]) + if test $gt_cv_header_inttypes_h = yes; then + AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H, 1, + [Define if <inttypes.h> exists and doesn't clash with <sys/types.h>.]) + fi +]) +# inttypes_h.m4 serial 5 (gettext-0.12) +dnl Copyright (C) 1997-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Paul Eggert. + +# Define HAVE_INTTYPES_H_WITH_UINTMAX if <inttypes.h> exists, +# doesn't clash with <sys/types.h>, and declares uintmax_t. + +AC_DEFUN([jm_AC_HEADER_INTTYPES_H], +[ + AC_CACHE_CHECK([for inttypes.h], jm_ac_cv_header_inttypes_h, + [AC_TRY_COMPILE( + [#include <sys/types.h> +#include <inttypes.h>], + [uintmax_t i = (uintmax_t) -1;], + jm_ac_cv_header_inttypes_h=yes, + jm_ac_cv_header_inttypes_h=no)]) + if test $jm_ac_cv_header_inttypes_h = yes; then + AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H_WITH_UINTMAX, 1, + [Define if <inttypes.h> exists, doesn't clash with <sys/types.h>, + and declares uintmax_t. ]) + fi +]) +# inttypes-pri.m4 serial 1 (gettext-0.11.4) +dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +# Define PRI_MACROS_BROKEN if <inttypes.h> exists and defines the PRI* +# macros to non-string values. This is the case on AIX 4.3.3. + +AC_DEFUN([gt_INTTYPES_PRI], +[ + AC_REQUIRE([gt_HEADER_INTTYPES_H]) + if test $gt_cv_header_inttypes_h = yes; then + AC_CACHE_CHECK([whether the inttypes.h PRIxNN macros are broken], + gt_cv_inttypes_pri_broken, + [ + AC_TRY_COMPILE([#include <inttypes.h> +#ifdef PRId32 +char *p = PRId32; +#endif +], [], gt_cv_inttypes_pri_broken=no, gt_cv_inttypes_pri_broken=yes) + ]) + fi + if test "$gt_cv_inttypes_pri_broken" = yes; then + AC_DEFINE_UNQUOTED(PRI_MACROS_BROKEN, 1, + [Define if <inttypes.h> exists and defines unusable PRI* macros.]) + fi +]) +# isc-posix.m4 serial 2 (gettext-0.11.2) +dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +# This file is not needed with autoconf-2.53 and newer. Remove it in 2005. + +# This test replaces the one in autoconf. +# Currently this macro should have the same name as the autoconf macro +# because gettext's gettext.m4 (distributed in the automake package) +# still uses it. Otherwise, the use in gettext.m4 makes autoheader +# give these diagnostics: +# configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX +# configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX + +undefine([AC_ISC_POSIX]) + +AC_DEFUN([AC_ISC_POSIX], + [ + dnl This test replaces the obsolescent AC_ISC_POSIX kludge. + AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"]) + ] +) +# lcmessage.m4 serial 3 (gettext-0.11.3) +dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper <drepper@cygnus.com>, 1995. + +# Check whether LC_MESSAGES is available in <locale.h>. + +AC_DEFUN([AM_LC_MESSAGES], +[ + AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, + [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES], + am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) + if test $am_cv_val_LC_MESSAGES = yes; then + AC_DEFINE(HAVE_LC_MESSAGES, 1, + [Define if your <locale.h> file defines LC_MESSAGES.]) + fi +]) +# lib-ld.m4 serial 2 (gettext-0.12) +dnl Copyright (C) 1996-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl Subroutines of libtool.m4, +dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision +dnl with libtool.m4. + +dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. +AC_DEFUN([AC_LIB_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then + acl_cv_prog_gnu_ld=yes +else + acl_cv_prog_gnu_ld=no +fi]) +with_gnu_ld=$acl_cv_prog_gnu_ld +]) + +dnl From libtool-1.4. Sets the variable LD. +AC_DEFUN([AC_LIB_PROG_LD], +[AC_ARG_WITH(gnu-ld, +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]* | [A-Za-z]:[\\/]*)] + [re_direlt='/[^/][^/]*/\.\./'] + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(acl_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$acl_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + acl_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$acl_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_LIB_PROG_LD_GNU +]) +# lib-link.m4 serial 4 (gettext-0.12) +dnl Copyright (C) 2001-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and +dnl augments the CPPFLAGS variable. +AC_DEFUN([AC_LIB_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + define([Name],[translit([$1],[./-], [___])]) + define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + ac_cv_lib[]Name[]_libs="$LIB[]NAME" + ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" + ac_cv_lib[]Name[]_cppflags="$INC[]NAME" + ]) + LIB[]NAME="$ac_cv_lib[]Name[]_libs" + LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" + INC[]NAME="$ac_cv_lib[]Name[]_cppflags" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the + dnl results of this search when this library appears as a dependency. + HAVE_LIB[]NAME=yes + undefine([Name]) + undefine([NAME]) +]) + +dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode) +dnl searches for libname and the libraries corresponding to explicit and +dnl implicit dependencies, together with the specified include files and +dnl the ability to compile and link the specified testcode. If found, it +dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and +dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and +dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs +dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. +AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + define([Name],[translit([$1],[./-], [___])]) + define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + + dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + + dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, + dnl because if the user has installed lib[]Name and not disabled its use + dnl via --without-lib[]Name-prefix, he wants to use it. + ac_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + + AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ + ac_save_LIBS="$LIBS" + LIBS="$LIBS $LIB[]NAME" + AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no]) + LIBS="$ac_save_LIBS" + ]) + if test "$ac_cv_lib[]Name" = yes; then + HAVE_LIB[]NAME=yes + AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.]) + AC_MSG_CHECKING([how to link with lib[]$1]) + AC_MSG_RESULT([$LIB[]NAME]) + else + HAVE_LIB[]NAME=no + dnl If $LIB[]NAME didn't lead to a usable library, we don't need + dnl $INC[]NAME either. + CPPFLAGS="$ac_save_CPPFLAGS" + LIB[]NAME= + LTLIB[]NAME= + fi + AC_SUBST([HAVE_LIB]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + undefine([Name]) + undefine([NAME]) +]) + +dnl Determine the platform dependent parameters needed to use rpath: +dnl libext, shlibext, hardcode_libdir_flag_spec, hardcode_libdir_separator, +dnl hardcode_direct, hardcode_minus_L. +AC_DEFUN([AC_LIB_RPATH], +[ + AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS + AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld + AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host + AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir + AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [ + CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ + ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + ]) + wl="$acl_cv_wl" + libext="$acl_cv_libext" + shlibext="$acl_cv_shlibext" + hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + hardcode_direct="$acl_cv_hardcode_direct" + hardcode_minus_L="$acl_cv_hardcode_minus_L" + dnl Determine whether the user wants rpath handling at all. + AC_ARG_ENABLE(rpath, + [ --disable-rpath do not hardcode runtime library paths], + :, enable_rpath=yes) +]) + +dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. +AC_DEFUN([AC_LIB_LINKFLAGS_BODY], +[ + define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_LIB_ARG_WITH([lib$1-prefix], +[ --with-lib$1-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib + --without-lib$1-prefix don't search for lib$1 in includedir and libdir], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/lib" + fi + fi +]) + dnl Search the library and its dependencies in $additional_libdir and + dnl $LDFLAGS. Using breadth-first-seach. + LIB[]NAME= + LTLIB[]NAME= + INC[]NAME= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='$1 $2' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + dnl See if it was already located by an earlier AC_LIB_LINKFLAGS + dnl or AC_LIB_HAVE_LINKFLAGS call. + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" + else + dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined + dnl that this library doesn't exist. So just drop it. + : + fi + else + dnl Search the library lib$name in $additional_libdir and $LDFLAGS + dnl and the already constructed $LIBNAME/$LTLIBNAME. + found_dir= + found_la= + found_so= + found_a= + if test $use_additional = yes; then + if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then + found_dir="$additional_libdir" + found_so="$additional_libdir/lib$name.$shlibext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + else + if test -f "$additional_libdir/lib$name.$libext"; then + found_dir="$additional_libdir" + found_a="$additional_libdir/lib$name.$libext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then + found_dir="$dir" + found_so="$dir/lib$name.$shlibext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + else + if test -f "$dir/lib$name.$libext"; then + found_dir="$dir" + found_a="$dir/lib$name.$libext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + dnl Found the library. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + dnl Linking with a shared library. We attempt to hardcode its + dnl directory into the executable's runpath, unless it's the + dnl standard /usr/lib. + if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then + dnl No hardcoding is needed. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + dnl The hardcoding into $LIBNAME is system dependent. + if test "$hardcode_direct" = yes; then + dnl Using DIR/libNAME.so during linking hardcodes DIR into the + dnl resulting binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + dnl Rely on "-L$found_dir". + dnl But don't add it if it's already contained in the LDFLAGS + dnl or the already constructed $LIBNAME + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" + fi + if test "$hardcode_minus_L" != no; then + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl We cannot use $hardcode_runpath_var and LD_RUN_PATH + dnl here, because this doesn't fit in flags passed to the + dnl compiler. So give up. No hardcoding. This affects only + dnl very old systems. + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + dnl Linking with a static library. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" + else + dnl We shouldn't come here, but anyway it's good to have a + dnl fallback. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" + fi + fi + dnl Assume the include files are nearby. + additional_includedir= + case "$found_dir" in + */lib | */lib/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + dnl Potentially add $additional_includedir to $INCNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's /usr/local/include and we are using GCC on Linux, + dnl 3. if it's already present in $CPPFLAGS or the already + dnl constructed $INCNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INC[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $INCNAME. + INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + dnl Look for dependencies. + if test -n "$found_la"; then + dnl Read the .la file. It defines the variables + dnl dlname, library_names, old_library, dependency_libs, current, + dnl age, revision, installed, dlopen, dlpreopen, libdir. + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + dnl We use only dependency_libs. + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's /usr/local/lib and we are using GCC on Linux, + dnl 3. if it's already present in $LDFLAGS or the already + dnl constructed $LIBNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/lib"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/lib"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LIBNAME. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LTLIBNAME. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + dnl Handle this in the next round. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + dnl Handle this in the next round. Throw away the .la's + dnl directory; it is already contained in a preceding -L + dnl option. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + dnl Most likely an immediate library name. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" + ;; + esac + done + fi + else + dnl Didn't find the library; assume it is in the system directories + dnl known to the linker and runtime loader. (All the system + dnl directories known to the linker should also be known to the + dnl runtime loader, otherwise the system is severely misconfigured.) + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user must + dnl pass all path elements in one option. We can arrange that for a + dnl single library, but not when more than one $LIBNAMEs are used. + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" + done + dnl Note: hardcode_libdir_flag_spec uses $libdir and $wl. + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + else + dnl The -rpath options are cumulative. + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + dnl When using libtool, the option that works for both libraries and + dnl executables is -R. The -R options are cumulative. + for found_dir in $ltrpathdirs; do + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" + done + fi +]) + +dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, +dnl unless already present in VAR. +dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes +dnl contains two or three consecutive elements that belong together. +AC_DEFUN([AC_LIB_APPENDTOVAR], +[ + for element in [$2]; do + haveit= + for x in $[$1]; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + [$1]="${[$1]}${[$1]:+ }$element" + fi + done +]) +# lib-prefix.m4 serial 2 (gettext-0.12) +dnl Copyright (C) 2001-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and +dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't +dnl require excessive bracketing. +ifdef([AC_HELP_STRING], +[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], +[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) + +dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed +dnl to access previously installed libraries. The basic assumption is that +dnl a user will want packages to use other packages he previously installed +dnl with the same --prefix option. +dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate +dnl libraries, but is otherwise very convenient. +AC_DEFUN([AC_LIB_PREFIX], +[ + AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_LIB_ARG_WITH([lib-prefix], +[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib + --without-lib-prefix don't search for libraries in includedir and libdir], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/lib" + fi + fi +]) + if test $use_additional = yes; then + dnl Potentially add $additional_includedir to $CPPFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's already present in $CPPFLAGS, + dnl 3. if it's /usr/local/include and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + for x in $CPPFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $CPPFLAGS. + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" + fi + fi + fi + fi + dnl Potentially add $additional_libdir to $LDFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's already present in $LDFLAGS, + dnl 3. if it's /usr/local/lib and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/lib"; then + haveit= + for x in $LDFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_libdir" = "X/usr/local/lib"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LDFLAGS. + LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" + fi + fi + fi + fi + fi +]) + +dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, +dnl acl_final_exec_prefix, containing the values to which $prefix and +dnl $exec_prefix will expand at the end of the configure script. +AC_DEFUN([AC_LIB_PREPARE_PREFIX], +[ + dnl Unfortunately, prefix and exec_prefix get only finally determined + dnl at the end of configure. + if test "X$prefix" = "XNONE"; then + acl_final_prefix="$ac_default_prefix" + else + acl_final_prefix="$prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + acl_final_exec_prefix='${prefix}' + else + acl_final_exec_prefix="$exec_prefix" + fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the +dnl variables prefix and exec_prefix bound to the values they will have +dnl at the end of the configure script. +AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], +[ + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + $1 + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" +]) +# nls.m4 serial 1 (gettext-0.12) +dnl Copyright (C) 1995-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000. +dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003. + +AC_DEFUN([AM_NLS], +[ + AC_MSG_CHECKING([whether NLS is requested]) + dnl Default is enabled NLS + AC_ARG_ENABLE(nls, + [ --disable-nls do not use Native Language Support], + USE_NLS=$enableval, USE_NLS=yes) + AC_MSG_RESULT($USE_NLS) + AC_SUBST(USE_NLS) +]) + +AC_DEFUN([AM_MKINSTALLDIRS], +[ + dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly + dnl find the mkinstalldirs script in another subdir but $(top_srcdir). + dnl Try to locate it. + MKINSTALLDIRS= + if test -n "$ac_aux_dir"; then + case "$ac_aux_dir" in + /*) MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" ;; + *) MKINSTALLDIRS="\$(top_builddir)/$ac_aux_dir/mkinstalldirs" ;; + esac + fi + if test -z "$MKINSTALLDIRS"; then + MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" + fi + AC_SUBST(MKINSTALLDIRS) +]) +# po.m4 serial 1 (gettext-0.12) +dnl Copyright (C) 1995-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000. +dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003. + +dnl Checks for all prerequisites of the po subdirectory. +AC_DEFUN([AM_PO_SUBDIRS], +[ + AC_REQUIRE([AC_PROG_MAKE_SET])dnl + AC_REQUIRE([AC_PROG_INSTALL])dnl + AC_REQUIRE([AM_MKINSTALLDIRS])dnl + AC_REQUIRE([AM_NLS])dnl + + dnl Perform the following tests also if --disable-nls has been given, + dnl because they are needed for "make dist" to work. + + dnl Search for GNU msgfmt in the PATH. + dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. + dnl The second test excludes FreeBSD msgfmt. + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [$ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1 && + (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], + :) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + + dnl Search for GNU xgettext 0.12 or newer in the PATH. + dnl The first test excludes Solaris xgettext and early GNU xgettext versions. + dnl The second test excludes FreeBSD xgettext. + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 && + (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], + :) + dnl Remove leftover from FreeBSD xgettext call. + rm -f messages.po + + dnl Search for GNU msgmerge 0.11 or newer in the PATH. + AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, + [$ac_dir/$ac_word --update -q /dev/null /dev/null >/dev/null 2>&1], :) + + dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. + dnl Test whether we really found GNU msgfmt. + if test "$GMSGFMT" != ":"; then + dnl If it is no GNU msgfmt we define it as : so that the + dnl Makefiles still can work. + if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 && + (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then + : ; + else + GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'` + AC_MSG_RESULT( + [found $GMSGFMT program is not GNU msgfmt; ignore it]) + GMSGFMT=":" + fi + fi + + dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. + dnl Test whether we really found GNU xgettext. + if test "$XGETTEXT" != ":"; then + dnl If it is no GNU xgettext we define it as : so that the + dnl Makefiles still can work. + if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 && + (if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then + : ; + else + AC_MSG_RESULT( + [found xgettext program is not GNU xgettext; ignore it]) + XGETTEXT=":" + fi + dnl Remove leftover from FreeBSD xgettext call. + rm -f messages.po + fi + + AC_OUTPUT_COMMANDS([ + for ac_file in $CONFIG_FILES; do + # Support "outfile[:infile[:infile...]]" + case "$ac_file" in + *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + esac + # PO directories have a Makefile.in generated from Makefile.in.in. + case "$ac_file" in */Makefile.in) + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then + rm -f "$ac_dir/POTFILES" + test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" + cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" + POMAKEFILEDEPS="POTFILES.in" + # ALL_LINGUAS, POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES depend + # on $ac_dir but don't depend on user-specified configuration + # parameters. + if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then + # The LINGUAS file contains the set of available languages. + if test -n "$OBSOLETE_ALL_LINGUAS"; then + test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" + fi + ALL_LINGUAS_=`sed -e "/^#/d" "$ac_given_srcdir/$ac_dir/LINGUAS"` + # Hide the ALL_LINGUAS assigment from automake. + eval 'ALL_LINGUAS''=$ALL_LINGUAS_' + POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" + else + # The set of available languages was given in configure.in. + eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' + fi + case "$ac_given_srcdir" in + .) srcdirpre= ;; + *) srcdirpre='$(srcdir)/' ;; + esac + POFILES= + GMOFILES= + UPDATEPOFILES= + DUMMYPOFILES= + for lang in $ALL_LINGUAS; do + POFILES="$POFILES $srcdirpre$lang.po" + GMOFILES="$GMOFILES $srcdirpre$lang.gmo" + UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" + DUMMYPOFILES="$DUMMYPOFILES $lang.nop" + done + # CATALOGS depends on both $ac_dir and the user's LINGUAS + # environment variable. + INST_LINGUAS= + if test -n "$ALL_LINGUAS"; then + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "$LINGUAS"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + INST_LINGUAS="$INST_LINGUAS $presentlang" + fi + done + fi + CATALOGS= + if test -n "$INST_LINGUAS"; then + for lang in $INST_LINGUAS; do + CATALOGS="$CATALOGS $lang.gmo" + done + fi + test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" + sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" + for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do + if test -f "$f"; then + case "$f" in + *.orig | *.bak | *~) ;; + *) cat "$f" >> "$ac_dir/Makefile" ;; + esac + fi + done + fi + ;; + esac + done], + [# Capture the value of obsolete ALL_LINGUAS because we need it to compute + # POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES, CATALOGS. But hide it + # from automake. + eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' + # Capture the value of LINGUAS because we need it to compute CATALOGS. + LINGUAS="${LINGUAS-%UNSET%}" + ]) +]) +# progtest.m4 serial 3 (gettext-0.12) +dnl Copyright (C) 1996-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper <drepper@cygnus.com>, 1996. + +# Search path for a program which passes the given test. + +dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +AC_DEFUN([AM_PATH_PROG_WITH_TEST], +[ +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Find out how to test for executable files. Don't use a zero-byte file, +# as systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + ac_executable_p="test -x" +else + ac_executable_p="test -f" +fi +rm -f conf$$.file + +# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL(ac_cv_path_$1, +[case "[$]$1" in + [[\\/]]* | ?:[[\\/]]*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in ifelse([$5], , $PATH, [$5]); do + IFS="$ac_save_IFS" + test -z "$ac_dir" && ac_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext" + break 2 + fi + fi + done + done + IFS="$ac_save_IFS" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then + AC_MSG_RESULT([$]$1) +else + AC_MSG_RESULT(no) +fi +AC_SUBST($1)dnl +]) +# stdint_h.m4 serial 3 (gettext-0.12) +dnl Copyright (C) 1997-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Paul Eggert. + +# Define HAVE_STDINT_H_WITH_UINTMAX if <stdint.h> exists, +# doesn't clash with <sys/types.h>, and declares uintmax_t. + +AC_DEFUN([jm_AC_HEADER_STDINT_H], +[ + AC_CACHE_CHECK([for stdint.h], jm_ac_cv_header_stdint_h, + [AC_TRY_COMPILE( + [#include <sys/types.h> +#include <stdint.h>], + [uintmax_t i = (uintmax_t) -1;], + jm_ac_cv_header_stdint_h=yes, + jm_ac_cv_header_stdint_h=no)]) + if test $jm_ac_cv_header_stdint_h = yes; then + AC_DEFINE_UNQUOTED(HAVE_STDINT_H_WITH_UINTMAX, 1, + [Define if <stdint.h> exists, doesn't clash with <sys/types.h>, + and declares uintmax_t. ]) + fi +]) +# uintmax_t.m4 serial 7 (gettext-0.12) +dnl Copyright (C) 1997-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Paul Eggert. + +AC_PREREQ(2.13) + +# Define uintmax_t to 'unsigned long' or 'unsigned long long' +# if it is not already defined in <stdint.h> or <inttypes.h>. + +AC_DEFUN([jm_AC_TYPE_UINTMAX_T], +[ + AC_REQUIRE([jm_AC_HEADER_INTTYPES_H]) + AC_REQUIRE([jm_AC_HEADER_STDINT_H]) + if test $jm_ac_cv_header_inttypes_h = no && test $jm_ac_cv_header_stdint_h = no; then + AC_REQUIRE([jm_AC_TYPE_UNSIGNED_LONG_LONG]) + test $ac_cv_type_unsigned_long_long = yes \ + && ac_type='unsigned long long' \ + || ac_type='unsigned long' + AC_DEFINE_UNQUOTED(uintmax_t, $ac_type, + [Define to unsigned long or unsigned long long + if <stdint.h> and <inttypes.h> don't define.]) + else + AC_DEFINE(HAVE_UINTMAX_T, 1, + [Define if you have the 'uintmax_t' type in <stdint.h> or <inttypes.h>.]) + fi +]) +# ulonglong.m4 serial 2 (fileutils-4.0.32, gettext-0.10.40) +dnl Copyright (C) 1999-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Paul Eggert. + +AC_DEFUN([jm_AC_TYPE_UNSIGNED_LONG_LONG], +[ + AC_CACHE_CHECK([for unsigned long long], ac_cv_type_unsigned_long_long, + [AC_TRY_LINK([unsigned long long ull = 1; int i = 63;], + [unsigned long long ullmax = (unsigned long long) -1; + return ull << i | ull >> i | ullmax / ull | ullmax % ull;], + ac_cv_type_unsigned_long_long=yes, + ac_cv_type_unsigned_long_long=no)]) + if test $ac_cv_type_unsigned_long_long = yes; then + AC_DEFINE(HAVE_UNSIGNED_LONG_LONG, 1, + [Define if you have the unsigned long long type.]) + fi +]) diff --git a/readline/bind.c b/readline/bind.c index 7103888..7559d32 100644 --- a/readline/bind.c +++ b/readline/bind.c @@ -1,6 +1,6 @@ /* bind.c -- key binding and startup file support for the readline library. */ -/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc. +/* Copyright (C) 1987-2005 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -19,8 +19,13 @@ is generally kept in a file called COPYING or LICENSE. If you do not have a copy of the license, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + #define READLINE_LIBRARY +#if defined (__TANDEM) +# include <floss.h> +#endif + #if defined (HAVE_CONFIG_H) # include <config.h> #endif @@ -72,6 +77,9 @@ static char *_rl_read_file PARAMS((char *, size_t *)); static void _rl_init_file_error PARAMS((const char *)); static int _rl_read_init_file PARAMS((const char *, int)); static int glean_key_from_name PARAMS((char *)); +static int find_boolean_var PARAMS((const char *)); + +static char *_rl_get_string_variable_value PARAMS((const char *)); static int substring_member_of_array PARAMS((char *, const char **)); static int currently_reading_init_file; @@ -148,6 +156,34 @@ rl_bind_key_in_map (key, function, map) return (result); } +/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right + now, this is always used to attempt to bind the arrow keys, hence the + check for rl_vi_movement_mode. */ +int +rl_bind_key_if_unbound_in_map (key, default_func, kmap) + int key; + rl_command_func_t *default_func; + Keymap kmap; +{ + char keyseq[2]; + + keyseq[0] = (unsigned char)key; + keyseq[1] = '\0'; + return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap)); +} + +int +rl_bind_key_if_unbound (key, default_func) + int key; + rl_command_func_t *default_func; +{ + char keyseq[2]; + + keyseq[0] = (unsigned char)key; + keyseq[1] = '\0'; + return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap)); +} + /* Make KEY do nothing in the currently selected keymap. Returns non-zero in case of error. */ int @@ -200,9 +236,30 @@ rl_unbind_command_in_map (command, map) } /* Bind the key sequence represented by the string KEYSEQ to + FUNCTION, starting in the current keymap. This makes new + keymaps as necessary. */ +int +rl_bind_keyseq (keyseq, function) + const char *keyseq; + rl_command_func_t *function; +{ + return (rl_generic_bind (ISFUNC, keyseq, (char *)function, _rl_keymap)); +} + +/* Bind the key sequence represented by the string KEYSEQ to FUNCTION. This makes new keymaps as necessary. The initial place to do bindings is in MAP. */ int +rl_bind_keyseq_in_map (keyseq, function, map) + const char *keyseq; + rl_command_func_t *function; + Keymap map; +{ + return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map)); +} + +/* Backwards compatibility; equivalent to rl_bind_keyseq_in_map() */ +int rl_set_key (keyseq, function, map) const char *keyseq; rl_command_func_t *function; @@ -211,6 +268,40 @@ rl_set_key (keyseq, function, map) return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map)); } +/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right + now, this is always used to attempt to bind the arrow keys, hence the + check for rl_vi_movement_mode. */ +int +rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap) + const char *keyseq; + rl_command_func_t *default_func; + Keymap kmap; +{ + rl_command_func_t *func; + + if (keyseq) + { + func = rl_function_of_keyseq (keyseq, kmap, (int *)NULL); +#if defined (VI_MODE) + if (!func || func == rl_do_lowercase_version || func == rl_vi_movement_mode) +#else + if (!func || func == rl_do_lowercase_version) +#endif + return (rl_bind_keyseq_in_map (keyseq, default_func, kmap)); + else + return 1; + } + return 0; +} + +int +rl_bind_keyseq_if_unbound (keyseq, default_func) + const char *keyseq; + rl_command_func_t *default_func; +{ + return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap)); +} + /* Bind the key sequence represented by the string KEYSEQ to the string of characters MACRO. This makes new keymaps as necessary. The initial place to do bindings is in MAP. */ @@ -253,7 +344,7 @@ rl_generic_bind (type, keyseq, data, map) k.function = 0; /* If no keys to bind to, exit right away. */ - if (!keyseq || !*keyseq) + if (keyseq == 0 || *keyseq == 0) { if (type == ISMACR) free (data); @@ -281,7 +372,7 @@ rl_generic_bind (type, keyseq, data, map) if (ic < 0 || ic >= KEYMAP_SIZE) return -1; - if (_rl_convert_meta_chars_to_ascii && META_CHAR (ic)) + if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii) { ic = UNMETA (ic); if (map[ESC].type == ISKMAP) @@ -372,7 +463,14 @@ rl_translate_keyseq (seq, array, len) else if (c == 'M') { i++; - array[l++] = ESC; /* ESC is meta-prefix */ + /* XXX - should obey convert-meta setting? */ + if (_rl_convert_meta_chars_to_ascii && _rl_keymap[ESC].type == ISKMAP) + array[l++] = ESC; /* ESC is meta-prefix */ + else + { + i++; + array[l++] = META (seq[i]); + } } else if (c == 'C') { @@ -912,9 +1010,15 @@ parser_else (args) return 0; } +#if 0 /* Check the previous (n - 1) levels of the stack to make sure that we haven't previously turned off parsing. */ for (i = 0; i < if_stack_depth - 1; i++) +#else + /* Check the previous (n) levels of the stack to make sure that + we haven't previously turned off parsing. */ + for (i = 0; i < if_stack_depth; i++) +#endif if (if_stack[i] == 1) return 0; @@ -1091,9 +1195,9 @@ rl_parse_and_bind (string) /* If this is a command to set a variable, then do that. */ if (_rl_stricmp (string, "set") == 0) { - char *var = string + i; - char *value; + char *var, *value, *e; + var = string + i; /* Make VAR point to start of variable name. */ while (*var && whitespace (*var)) var++; @@ -1104,6 +1208,20 @@ rl_parse_and_bind (string) *value++ = '\0'; while (*value && whitespace (*value)) value++; + /* Strip trailing whitespace from values to boolean variables. Temp + fix until I get a real quoted-string parser here. */ + i = find_boolean_var (var); + if (i >= 0) + { + /* remove trailing whitespace */ + e = value + strlen (value) - 1; + while (e >= value && whitespace (*e)) + e--; + e++; /* skip back to whitespace or EOS */ + if (*e && e >= value) + *e = '\0'; + } + rl_variable_bind (var, value); return 0; } @@ -1124,8 +1242,9 @@ rl_parse_and_bind (string) the quoted string delimiter, like the shell. */ if (*funname == '\'' || *funname == '"') { - int delimiter = string[i++], passc; + int delimiter, passc; + delimiter = string[i++]; for (passc = 0; c = string[i]; i++) { if (passc) @@ -1161,7 +1280,7 @@ rl_parse_and_bind (string) } /* If this is a new-style key-binding, then do the binding with - rl_set_key (). Otherwise, let the older code deal with it. */ + rl_bind_keyseq (). Otherwise, let the older code deal with it. */ if (*string == '"') { char *seq; @@ -1200,7 +1319,7 @@ rl_parse_and_bind (string) rl_macro_bind (seq, &funname[1], _rl_keymap); } else - rl_set_key (seq, rl_named_function (funname), _rl_keymap); + rl_bind_keyseq (seq, rl_named_function (funname)); free (seq); return 0; @@ -1261,6 +1380,7 @@ static struct { int *value; int flags; } boolean_varlist [] = { + { "bind-tty-special-chars", &_rl_bind_stty_chars, 0 }, { "blink-matching-paren", &rl_blink_matching_paren, V_SPECIAL }, { "byte-oriented", &rl_byte_oriented, 0 }, { "completion-ignore-case", &_rl_completion_case_fold, 0 }, @@ -1281,6 +1401,7 @@ static struct { { "prefer-visible-bell", &_rl_prefer_visible_bell, V_SPECIAL }, { "print-completions-horizontally", &_rl_print_completions_horizontally, 0 }, { "show-all-if-ambiguous", &_rl_complete_show_all, 0 }, + { "show-all-if-unmodified", &_rl_complete_show_unmodified, 0 }, #if defined (VISIBLE_STATS) { "visible-stats", &rl_visible_stats, 0 }, #endif /* VISIBLE_STATS */ @@ -1373,13 +1494,34 @@ find_string_var (name) values result in 0 (false). */ static int bool_to_int (value) - char *value; + const char *value; { return (value == 0 || *value == '\0' || (_rl_stricmp (value, "on") == 0) || (value[0] == '1' && value[1] == '\0')); } +char * +rl_variable_value (name) + const char *name; +{ + register int i; + int v; + char *ret; + + /* Check for simple variables first. */ + i = find_boolean_var (name); + if (i >= 0) + return (*boolean_varlist[i].value ? "on" : "off"); + + i = find_string_var (name); + if (i >= 0) + return (_rl_get_string_variable_value (string_varlist[i].name)); + + /* Unknown variable names return NULL. */ + return 0; +} + int rl_variable_bind (name, value) const char *name, *value; @@ -1650,7 +1792,7 @@ rl_get_keymap_name_from_edit_mode () /* Each of the following functions produces information about the state of keybindings and functions known to Readline. The info is always printed to rl_outstream, and in such a way that it can - be read back in (i.e., passed to rl_parse_and_bind (). */ + be read back in (i.e., passed to rl_parse_and_bind ()). */ /* Print the names of functions known to Readline. */ void @@ -2022,12 +2164,68 @@ rl_dump_macros (count, key) return (0); } +static char * +_rl_get_string_variable_value (name) + const char *name; +{ + static char numbuf[32]; + char *ret; + int n; + + if (_rl_stricmp (name, "bell-style") == 0) + { + switch (_rl_bell_preference) + { + case NO_BELL: + return "none"; + case VISIBLE_BELL: + return "visible"; + case AUDIBLE_BELL: + default: + return "audible"; + } + } + else if (_rl_stricmp (name, "comment-begin") == 0) + return (_rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT); + else if (_rl_stricmp (name, "completion-query-items") == 0) + { + sprintf (numbuf, "%d", rl_completion_query_items); + return (numbuf); + } + else if (_rl_stricmp (name, "editing-mode") == 0) + return (rl_get_keymap_name_from_edit_mode ()); + else if (_rl_stricmp (name, "isearch-terminators") == 0) + { + if (_rl_isearch_terminators == 0) + return 0; + ret = _rl_untranslate_macro_value (_rl_isearch_terminators); + if (ret) + { + strncpy (numbuf, ret, sizeof (numbuf) - 1); + free (ret); + numbuf[sizeof(numbuf) - 1] = '\0'; + } + else + numbuf[0] = '\0'; + return numbuf; + } + else if (_rl_stricmp (name, "keymap") == 0) + { + ret = rl_get_keymap_name (_rl_keymap); + if (ret == 0) + ret = rl_get_keymap_name_from_edit_mode (); + return (ret ? ret : "none"); + } + else + return (0); +} + void rl_variable_dumper (print_readably) int print_readably; { int i; - const char *kname; + char *v; for (i = 0; boolean_varlist[i].name; i++) { @@ -2039,63 +2237,16 @@ rl_variable_dumper (print_readably) *boolean_varlist[i].value ? "on" : "off"); } - /* bell-style */ - switch (_rl_bell_preference) - { - case NO_BELL: - kname = "none"; break; - case VISIBLE_BELL: - kname = "visible"; break; - case AUDIBLE_BELL: - default: - kname = "audible"; break; - } - if (print_readably) - fprintf (rl_outstream, "set bell-style %s\n", kname); - else - fprintf (rl_outstream, "bell-style is set to `%s'\n", kname); - - /* comment-begin */ - if (print_readably) - fprintf (rl_outstream, "set comment-begin %s\n", _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT); - else - fprintf (rl_outstream, "comment-begin is set to `%s'\n", _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT); - - /* completion-query-items */ - if (print_readably) - fprintf (rl_outstream, "set completion-query-items %d\n", rl_completion_query_items); - else - fprintf (rl_outstream, "completion-query-items is set to `%d'\n", rl_completion_query_items); - - /* editing-mode */ - if (print_readably) - fprintf (rl_outstream, "set editing-mode %s\n", (rl_editing_mode == emacs_mode) ? "emacs" : "vi"); - else - fprintf (rl_outstream, "editing-mode is set to `%s'\n", (rl_editing_mode == emacs_mode) ? "emacs" : "vi"); - - /* isearch-terminators */ - if (_rl_isearch_terminators) + for (i = 0; string_varlist[i].name; i++) { - char *disp; - - disp = _rl_untranslate_macro_value (_rl_isearch_terminators); - + v = _rl_get_string_variable_value (string_varlist[i].name); + if (v == 0) /* _rl_isearch_terminators can be NULL */ + continue; if (print_readably) - fprintf (rl_outstream, "set isearch-terminators \"%s\"\n", disp); + fprintf (rl_outstream, "set %s %s\n", string_varlist[i].name, v); else - fprintf (rl_outstream, "isearch-terminators is set to \"%s\"\n", disp); - - free (disp); + fprintf (rl_outstream, "%s is set to `%s'\n", string_varlist[i].name, v); } - - /* keymap */ - kname = rl_get_keymap_name (_rl_keymap); - if (kname == 0) - kname = rl_get_keymap_name_from_edit_mode (); - if (print_readably) - fprintf (rl_outstream, "set keymap %s\n", kname ? kname : "none"); - else - fprintf (rl_outstream, "keymap is set to `%s'\n", kname ? kname : "none"); } /* Print all of the current variables and their values to @@ -2112,28 +2263,6 @@ rl_dump_variables (count, key) return (0); } -/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right - now, this is always used to attempt to bind the arrow keys, hence the - check for rl_vi_movement_mode. */ -void -_rl_bind_if_unbound (keyseq, default_func) - const char *keyseq; - rl_command_func_t *default_func; -{ - rl_command_func_t *func; - - if (keyseq) - { - func = rl_function_of_keyseq (keyseq, _rl_keymap, (int *)NULL); -#if defined (VI_MODE) - if (!func || func == rl_do_lowercase_version || func == rl_vi_movement_mode) -#else - if (!func || func == rl_do_lowercase_version) -#endif - rl_set_key (keyseq, default_func, _rl_keymap); - } -} - /* Return non-zero if any members of ARRAY are a substring in STRING. */ static int substring_member_of_array (string, array) diff --git a/readline/callback.c b/readline/callback.c index a8f4323..9120969 100644 --- a/readline/callback.c +++ b/readline/callback.c @@ -1,6 +1,6 @@ /* callback.c -- functions to use readline as an X `callback' mechanism. */ -/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc. +/* Copyright (C) 1987-2005 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -44,9 +44,14 @@ #include "readline.h" #include "rlprivate.h" +/* Private data for callback registration functions. See comments in + rl_callback_read_char for more details. */ +_rl_callback_func_t *_rl_callback_func = 0; +_rl_callback_generic_arg *_rl_callback_data = 0; + /* **************************************************************** */ /* */ -/* Callback Readline Functions */ +/* Callback Readline Functions */ /* */ /* **************************************************************** */ @@ -72,7 +77,8 @@ _rl_callback_newline () { in_handler = 1; - (*rl_prep_term_function) (_rl_meta_flag); + if (rl_prep_term_function) + (*rl_prep_term_function) (_rl_meta_flag); #if defined (HANDLE_SIGNALS) rl_set_signals (); @@ -89,6 +95,7 @@ rl_callback_handler_install (prompt, linefunc) rl_vcpfunc_t *linefunc; { rl_set_prompt (prompt); + RL_SETSTATE (RL_STATE_CALLBACK); rl_linefunc = linefunc; _rl_callback_newline (); } @@ -98,7 +105,8 @@ void rl_callback_read_char () { char *line; - int eof; + int eof, jcode; + static procenv_t olevel; if (rl_linefunc == NULL) { @@ -106,7 +114,79 @@ rl_callback_read_char () abort (); } - eof = readline_internal_char (); + memcpy ((void *)olevel, (void *)readline_top_level, sizeof (procenv_t)); + jcode = setjmp (readline_top_level); + if (jcode) + { + (*rl_redisplay_function) (); + _rl_want_redisplay = 0; + memcpy ((void *)readline_top_level, (void *)olevel, sizeof (procenv_t)); + return; + } + + if (RL_ISSTATE (RL_STATE_ISEARCH)) + { + eof = _rl_isearch_callback (_rl_iscxt); + if (eof == 0 && (RL_ISSTATE (RL_STATE_ISEARCH) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING)) + rl_callback_read_char (); + + return; + } + else if (RL_ISSTATE (RL_STATE_NSEARCH)) + { + eof = _rl_nsearch_callback (_rl_nscxt); + return; + } + else if (RL_ISSTATE (RL_STATE_NUMERICARG)) + { + eof = _rl_arg_callback (_rl_argcxt); + if (eof == 0 && (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING)) + rl_callback_read_char (); + /* XXX - this should handle _rl_last_command_was_kill better */ + else if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) + _rl_internal_char_cleanup (); + + return; + } + else if (RL_ISSTATE (RL_STATE_MULTIKEY)) + { + eof = _rl_dispatch_callback (_rl_kscxt); /* For now */ + while ((eof == -1 || eof == -2) && RL_ISSTATE (RL_STATE_MULTIKEY) && _rl_kscxt && (_rl_kscxt->flags & KSEQ_DISPATCHED)) + eof = _rl_dispatch_callback (_rl_kscxt); + if (RL_ISSTATE (RL_STATE_MULTIKEY) == 0) + { + _rl_internal_char_cleanup (); + _rl_want_redisplay = 1; + } + } + else if (_rl_callback_func) + { + /* This allows functions that simply need to read an additional character + (like quoted-insert) to register a function to be called when input is + available. _rl_callback_data is simply a pointer to a struct that has + the argument count originally passed to the registering function and + space for any additional parameters. */ + eof = (*_rl_callback_func) (_rl_callback_data); + /* If the function `deregisters' itself, make sure the data is cleaned + up. */ + if (_rl_callback_func == 0) + { + if (_rl_callback_data) + { + _rl_callback_data_dispose (_rl_callback_data); + _rl_callback_data = 0; + } + _rl_internal_char_cleanup (); + } + } + else + eof = readline_internal_char (); + + if (rl_done == 0 && _rl_want_redisplay) + { + (*rl_redisplay_function) (); + _rl_want_redisplay = 0; + } /* We loop in case some function has pushed input back with rl_execute_next. */ for (;;) @@ -115,7 +195,8 @@ rl_callback_read_char () { line = readline_internal_teardown (eof); - (*rl_deprep_term_function) (); + if (rl_deprep_term_function) + (*rl_deprep_term_function) (); #if defined (HANDLE_SIGNALS) rl_clear_signals (); #endif @@ -131,10 +212,10 @@ rl_callback_read_char () if (in_handler == 0 && rl_linefunc) _rl_callback_newline (); } - if (rl_pending_input) + if (rl_pending_input || _rl_pushed_input_available () || RL_ISSTATE (RL_STATE_MACROINPUT)) eof = readline_internal_char (); else - break; + break; } } @@ -143,14 +224,37 @@ void rl_callback_handler_remove () { rl_linefunc = NULL; + RL_UNSETSTATE (RL_STATE_CALLBACK); if (in_handler) { in_handler = 0; - (*rl_deprep_term_function) (); + if (rl_deprep_term_function) + (*rl_deprep_term_function) (); #if defined (HANDLE_SIGNALS) rl_clear_signals (); #endif } } +_rl_callback_generic_arg * +_rl_callback_data_alloc (count) + int count; +{ + _rl_callback_generic_arg *arg; + + arg = (_rl_callback_generic_arg *)xmalloc (sizeof (_rl_callback_generic_arg)); + arg->count = count; + + arg->i1 = arg->i2 = 0; + + return arg; +} + +void _rl_callback_data_dispose (arg) + _rl_callback_generic_arg *arg; +{ + if (arg) + free (arg); +} + #endif diff --git a/readline/chardefs.h b/readline/chardefs.h index a537be2..def3a11 100644 --- a/readline/chardefs.h +++ b/readline/chardefs.h @@ -77,11 +77,17 @@ # define isxdigit(c) (isdigit((c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) #endif -#define NON_NEGATIVE(c) ((unsigned char)(c) == (c)) +#if defined (CTYPE_NON_ASCII) +# define NON_NEGATIVE(c) 1 +#else +# define NON_NEGATIVE(c) ((unsigned char)(c) == (c)) +#endif /* Some systems define these; we want our definitions. */ #undef ISPRINT +/* Beware: these only work with single-byte ASCII characters. */ + #define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum (c)) #define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c)) #define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit (c)) diff --git a/readline/complete.c b/readline/complete.c index a4ff24e..d93c15a 100644 --- a/readline/complete.c +++ b/readline/complete.c @@ -1,6 +1,6 @@ /* complete.c -- filename completion for readline. */ -/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc. +/* Copyright (C) 1987-2005 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -28,7 +28,7 @@ #include <sys/types.h> #include <fcntl.h> #if defined (HAVE_SYS_FILE_H) -#include <sys/file.h> +# include <sys/file.h> #endif #if defined (HAVE_UNISTD_H) @@ -48,7 +48,7 @@ extern int errno; #endif /* !errno */ -#ifdef HAVE_PWD_H +#if defined (HAVE_PWD_H) #include <pwd.h> #endif @@ -81,10 +81,9 @@ typedef int QSFUNC (); /* Most systems don't declare getpwent in <pwd.h> if _POSIX_SOURCE is defined. */ -#if defined(HAVE_GETPWENT) && \ - (!defined (HAVE_GETPW_DECLS) || defined (_POSIX_SOURCE)) +#if defined (HAVE_GETPWENT) && (!defined (HAVE_GETPW_DECLS) || defined (_POSIX_SOURCE)) extern struct passwd *getpwent PARAMS((void)); -#endif /* defiend (HAVE_GETPWENT) && (!HAVE_GETPW_DECLS || _POSIX_SOURCE) */ +#endif /* HAVE_GETPWENT && (!HAVE_GETPW_DECLS || _POSIX_SOURCE) */ /* If non-zero, then this is the address of a function to call when completing a word would normally display the list of possible matches. @@ -102,12 +101,16 @@ rl_compdisp_func_t *rl_completion_display_matches_hook = (rl_compdisp_func_t *)N static int stat_char PARAMS((char *)); #endif +static int path_isdir PARAMS((const char *)); + static char *rl_quote_filename PARAMS((char *, int, char *)); static void set_completion_defaults PARAMS((int)); static int get_y_or_n PARAMS((int)); static int _rl_internal_pager PARAMS((int)); static char *printable_part PARAMS((char *)); +static int fnwidth PARAMS((const char *)); +static int fnprint PARAMS((const char *)); static int print_filename PARAMS((char *, char *)); static char **gen_completion_matches PARAMS((char *, int, int, rl_compentry_func_t *, int, int)); @@ -133,6 +136,10 @@ static char *make_quoted_replacement PARAMS((char *, int, char *)); /* If non-zero, non-unique completions always show the list of matches. */ int _rl_complete_show_all = 0; +/* If non-zero, non-unique completions show the list of matches, unless it + is not possible to do partial completion and modify the line. */ +int _rl_complete_show_unmodified = 0; + /* If non-zero, completed directory names have a slash appended. */ int _rl_complete_mark_directories = 1; @@ -201,7 +208,8 @@ int rl_completion_type = 0; /* Up to this many items will be displayed in response to a possible-completions call. After that, we ask the user if - she is sure she wants to see them all. */ + she is sure she wants to see them all. A negative value means + don't ask. */ int rl_completion_query_items = 100; int _rl_page_completions = 1; @@ -217,7 +225,12 @@ const char *rl_basic_quote_characters = "\"'"; /* The list of characters that signal a break between words for rl_complete_internal. The default list is the contents of rl_basic_word_break_characters. */ -const char *rl_completer_word_break_characters = (const char *)NULL; +/*const*/ char *rl_completer_word_break_characters = (/*const*/ char *)NULL; + +/* Hook function to allow an application to set the completion word + break characters before readline breaks up the line. Allows + position-dependent word break characters. */ +rl_cpvfunc_t *rl_completion_word_break_hook = (rl_cpvfunc_t *)NULL; /* List of characters which can be used to quote a substring of the line. Completion occurs on the entire substring, and within the substring @@ -285,6 +298,19 @@ int rl_completion_suppress_append = 0; default is a space. */ int rl_completion_append_character = ' '; +/* If non-zero, the completion functions don't append any closing quote. + This is set to 0 by rl_complete_internal and may be changed by an + application-specific completion function. */ +int rl_completion_suppress_quote = 0; + +/* Set to any quote character readline thinks it finds before any application + completion function is called. */ +int rl_completion_quote_character; + +/* Set to a non-zero value if readline found quoting anywhere in the word to + be completed; set before any application completion function is called. */ +int rl_completion_found_quote; + /* If non-zero, a slash will be appended to completed filenames that are symbolic links to directory names, subject to the value of the mark-directories variable (which is user-settable). This exists so @@ -323,6 +349,8 @@ rl_complete (ignore, invoking_key) return (rl_complete_internal ('?')); else if (_rl_complete_show_all) return (rl_complete_internal ('!')); + else if (_rl_complete_show_unmodified) + return (rl_complete_internal ('@')); else return (rl_complete_internal (TAB)); } @@ -355,6 +383,8 @@ rl_completion_mode (cfunc) return '?'; else if (_rl_complete_show_all) return '!'; + else if (_rl_complete_show_unmodified) + return '@'; else return TAB; } @@ -375,7 +405,7 @@ set_completion_defaults (what_to_do) rl_filename_completion_desired = 0; rl_filename_quoting_desired = 1; rl_completion_type = what_to_do; - rl_completion_suppress_append = 0; + rl_completion_suppress_append = rl_completion_suppress_quote = 0; /* The completion entry function may optionally change this. */ rl_completion_mark_symlink_dirs = _rl_complete_mark_symlink_dirs; @@ -426,6 +456,15 @@ _rl_internal_pager (lines) return 0; } +static int +path_isdir (filename) + const char *filename; +{ + struct stat finfo; + + return (stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode)); +} + #if defined (VISIBLE_STATS) /* Return the character which best describes FILENAME. `@' for symbolic links @@ -523,53 +562,149 @@ printable_part (pathname) return ++temp; } +/* Compute width of STRING when displayed on screen by print_filename */ +static int +fnwidth (string) + const char *string; +{ + int width, pos; +#if defined (HANDLE_MULTIBYTE) + mbstate_t ps; + int left, w; + size_t clen; + wchar_t wc; + + left = strlen (string) + 1; + memset (&ps, 0, sizeof (mbstate_t)); +#endif + + width = pos = 0; + while (string[pos]) + { + if (CTRL_CHAR (*string) || *string == RUBOUT) + { + width += 2; + pos++; + } + else + { +#if defined (HANDLE_MULTIBYTE) + clen = mbrtowc (&wc, string + pos, left - pos, &ps); + if (MB_INVALIDCH (clen)) + { + width++; + pos++; + memset (&ps, 0, sizeof (mbstate_t)); + } + else if (MB_NULLWCH (clen)) + break; + else + { + pos += clen; + w = wcwidth (wc); + width += (w >= 0) ? w : 1; + } +#else + width++; + pos++; +#endif + } + } + + return width; +} + +static int +fnprint (to_print) + const char *to_print; +{ + int printed_len; + const char *s; +#if defined (HANDLE_MULTIBYTE) + mbstate_t ps; + const char *end; + size_t tlen; + int width, w; + wchar_t wc; + + end = to_print + strlen (to_print) + 1; + memset (&ps, 0, sizeof (mbstate_t)); +#endif + + printed_len = 0; + s = to_print; + while (*s) + { + if (CTRL_CHAR (*s)) + { + putc ('^', rl_outstream); + putc (UNCTRL (*s), rl_outstream); + printed_len += 2; + s++; +#if defined (HANDLE_MULTIBYTE) + memset (&ps, 0, sizeof (mbstate_t)); +#endif + } + else if (*s == RUBOUT) + { + putc ('^', rl_outstream); + putc ('?', rl_outstream); + printed_len += 2; + s++; +#if defined (HANDLE_MULTIBYTE) + memset (&ps, 0, sizeof (mbstate_t)); +#endif + } + else + { +#if defined (HANDLE_MULTIBYTE) + tlen = mbrtowc (&wc, s, end - s, &ps); + if (MB_INVALIDCH (tlen)) + { + tlen = 1; + width = 1; + memset (&ps, 0, sizeof (mbstate_t)); + } + else if (MB_NULLWCH (tlen)) + break; + else + { + w = wcwidth (wc); + width = (w >= 0) ? w : 1; + } + fwrite (s, 1, tlen, rl_outstream); + s += tlen; + printed_len += width; +#else + putc (*s, rl_outstream); + s++; + printed_len++; +#endif + } + } + + return printed_len; +} + /* Output TO_PRINT to rl_outstream. If VISIBLE_STATS is defined and we are using it, check for and output a single character for `special' filenames. Return the number of characters we output. */ -#define PUTX(c) \ - do { \ - if (CTRL_CHAR (c)) \ - { \ - putc ('^', rl_outstream); \ - putc (UNCTRL (c), rl_outstream); \ - printed_len += 2; \ - } \ - else if (c == RUBOUT) \ - { \ - putc ('^', rl_outstream); \ - putc ('?', rl_outstream); \ - printed_len += 2; \ - } \ - else \ - { \ - putc (c, rl_outstream); \ - printed_len++; \ - } \ - } while (0) - static int print_filename (to_print, full_pathname) char *to_print, *full_pathname; { - int printed_len = 0; -#if !defined (VISIBLE_STATS) - char *s; + int printed_len, extension_char, slen, tlen; + char *s, c, *new_full_pathname, *dn; - for (s = to_print; *s; s++) - { - PUTX (*s); - } -#else - char *s, c, *new_full_pathname; - int extension_char, slen, tlen; + extension_char = 0; + printed_len = fnprint (to_print); - for (s = to_print; *s; s++) - { - PUTX (*s); - } - - if (rl_filename_completion_desired && rl_visible_stats) +#if defined (VISIBLE_STATS) + if (rl_filename_completion_desired && (rl_visible_stats || _rl_complete_mark_directories)) +#else + if (rl_filename_completion_desired && _rl_complete_mark_directories) +#endif { /* If to_print != full_pathname, to_print is the basename of the path passed. In this case, we try to expand the directory @@ -585,7 +720,17 @@ print_filename (to_print, full_pathname) files in the root directory. If we pass a null string to the bash directory completion hook, for example, it will expand it to the current directory. We just want the `/'. */ - s = tilde_expand (full_pathname && *full_pathname ? full_pathname : "/"); + if (full_pathname == 0 || *full_pathname == 0) + dn = "/"; + else if (full_pathname[0] != '/') + dn = full_pathname; + else if (full_pathname[1] == 0) + dn = "//"; /* restore trailing slash to `//' */ + else if (full_pathname[1] == '/' && full_pathname[2] == 0) + dn = "/"; /* don't turn /// into // */ + else + dn = full_pathname; + s = tilde_expand (dn); if (rl_directory_completion_hook) (*rl_directory_completion_hook) (&s); @@ -593,10 +738,20 @@ print_filename (to_print, full_pathname) tlen = strlen (to_print); new_full_pathname = (char *)xmalloc (slen + tlen + 2); strcpy (new_full_pathname, s); + if (s[slen - 1] == '/') + slen--; + else + new_full_pathname[slen] = '/'; new_full_pathname[slen] = '/'; strcpy (new_full_pathname + slen + 1, to_print); - extension_char = stat_char (new_full_pathname); +#if defined (VISIBLE_STATS) + if (rl_visible_stats) + extension_char = stat_char (new_full_pathname); + else +#endif + if (path_isdir (new_full_pathname)) + extension_char = '/'; free (new_full_pathname); to_print[-1] = c; @@ -604,7 +759,13 @@ print_filename (to_print, full_pathname) else { s = tilde_expand (full_pathname); - extension_char = stat_char (s); +#if defined (VISIBLE_STATS) + if (rl_visible_stats) + extension_char = stat_char (s); + else +#endif + if (path_isdir (s)) + extension_char = '/'; } free (s); @@ -614,7 +775,7 @@ print_filename (to_print, full_pathname) printed_len++; } } -#endif /* VISIBLE_STATS */ + return printed_len; } @@ -654,19 +815,25 @@ _rl_find_completion_word (fp, dp) int *fp, *dp; { int scan, end, found_quote, delimiter, pass_next, isbrk; - char quote_char; + char quote_char, *brkchars; end = rl_point; found_quote = delimiter = 0; quote_char = '\0'; + brkchars = 0; + if (rl_completion_word_break_hook) + brkchars = (*rl_completion_word_break_hook) (); + if (brkchars == 0) + brkchars = rl_completer_word_break_characters; + if (rl_completer_quote_characters) { /* We have a list of characters which can be used in pairs to quote substrings for the completer. Try to find the start of an unclosed quoted substring. */ /* FOUND_QUOTE is set so we know what kind of quotes we found. */ - for (scan = pass_next = 0; scan < end; scan++) + for (scan = pass_next = 0; scan < end; scan = MB_NEXTCHAR (rl_line_buffer, scan, 1, MB_FIND_ANY)) { if (pass_next) { @@ -716,15 +883,11 @@ _rl_find_completion_word (fp, dp) /* We didn't find an unclosed quoted substring upon which to do completion, so use the word break characters to find the substring on which to complete. */ -#if defined (HANDLE_MULTIBYTE) - while (rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_ANY)) -#else - while (--rl_point) -#endif + while (rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_ANY)) { scan = rl_line_buffer[rl_point]; - if (strchr (rl_completer_word_break_characters, scan) == 0) + if (strchr (brkchars, scan) == 0) continue; /* Call the application-specific function to tell us whether @@ -752,9 +915,9 @@ _rl_find_completion_word (fp, dp) if (rl_char_is_quoted_p) isbrk = (found_quote == 0 || (*rl_char_is_quoted_p) (rl_line_buffer, rl_point) == 0) && - strchr (rl_completer_word_break_characters, scan) != 0; + strchr (brkchars, scan) != 0; else - isbrk = strchr (rl_completer_word_break_characters, scan) != 0; + isbrk = strchr (brkchars, scan) != 0; if (isbrk) { @@ -789,6 +952,9 @@ gen_completion_matches (text, start, end, our_func, found_quote, quote_char) { char **matches, *temp; + rl_completion_found_quote = found_quote; + rl_completion_quote_character = quote_char; + /* If the user wants to TRY to complete, but then wants to give up and use the default completion function, they set the variable rl_attempted_completion_function. */ @@ -892,6 +1058,7 @@ compute_lcd_of_matches (match_list, matches, text) { register int i, c1, c2, si; int low; /* Count of max-matched characters. */ + char *dtext; /* dequoted TEXT, if needed */ #if defined (HANDLE_MULTIBYTE) int v; mbstate_t ps1, ps2; @@ -983,6 +1150,26 @@ compute_lcd_of_matches (match_list, matches, text) the user typed in the face of multiple matches differing in case. */ if (_rl_completion_case_fold) { + /* We're making an assumption here: + IF we're completing filenames AND + the application has defined a filename dequoting function AND + we found a quote character AND + the application has requested filename quoting + THEN + we assume that TEXT was dequoted before checking against + the file system and needs to be dequoted here before we + check against the list of matches + FI */ + dtext = (char *)NULL; + if (rl_filename_completion_desired && + rl_filename_dequoting_function && + rl_completion_found_quote && + rl_filename_quoting_desired) + { + dtext = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character); + text = dtext; + } + /* sort the list to get consistent answers. */ qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare); @@ -1002,6 +1189,8 @@ compute_lcd_of_matches (match_list, matches, text) else /* otherwise, just use the text the user typed. */ strncpy (match_list[0], text, low); + + FREE (dtext); } else strncpy (match_list[0], match_list[1], low); @@ -1206,7 +1395,7 @@ display_matches (matches) for (max = 0, i = 1; matches[i]; i++) { temp = printable_part (matches[i]); - len = strlen (temp); + len = fnwidth (temp); if (len > max) max = len; @@ -1223,7 +1412,7 @@ display_matches (matches) /* If there are many items, then ask the user if she really wants to see them all. */ - if (len >= rl_completion_query_items) + if (rl_completion_query_items > 0 && len >= rl_completion_query_items) { rl_crlf (); fprintf (rl_outstream, "Display all %d possibilities? (y or n)", len); @@ -1341,7 +1530,8 @@ append_to_match (text, delimiter, quote_char, nontrivial_match) struct stat finfo; temp_string_index = 0; - if (quote_char && rl_point && rl_line_buffer[rl_point - 1] != quote_char) + if (quote_char && rl_point && rl_completion_suppress_quote == 0 && + rl_line_buffer[rl_point - 1] != quote_char) temp_string[temp_string_index++] = quote_char; if (delimiter) @@ -1359,7 +1549,7 @@ append_to_match (text, delimiter, quote_char, nontrivial_match) : stat (filename, &finfo); if (s == 0 && S_ISDIR (finfo.st_mode)) { - if (_rl_complete_mark_directories) + if (_rl_complete_mark_directories /* && rl_completion_suppress_append == 0 */) { /* This is clumsy. Avoid putting in a double slash if point is at the end of the line and the previous character is a @@ -1452,7 +1642,9 @@ _rl_free_match_list (matches) TAB means do standard completion. `*' means insert all of the possible completions. `!' means to do standard completion, and list all possible completions if - there is more than one. */ + there is more than one. + `@' means to do standard completion, and list all possible completions if + there is more than one and partial completion is not possible. */ int rl_complete_internal (what_to_do) int what_to_do; @@ -1471,7 +1663,6 @@ rl_complete_internal (what_to_do) our_func = rl_completion_entry_function ? rl_completion_entry_function : rl_filename_completion_function; - /* We now look backwards for the start of a filename/variable word. */ end = rl_point; found_quote = delimiter = 0; @@ -1519,6 +1710,7 @@ rl_complete_internal (what_to_do) { case TAB: case '!': + case '@': /* Insert the first match with proper quoting. */ if (*matches[0]) insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, "e_char); @@ -1538,6 +1730,12 @@ rl_complete_internal (what_to_do) display_matches (matches); break; } + else if (what_to_do == '@') + { + if (nontrivial_lcd == 0) + display_matches (matches); + break; + } else if (rl_editing_mode != vi_mode) rl_ding (); /* There are other matches remaining. */ } @@ -1665,7 +1863,7 @@ rl_username_completion_function (text, state) setpwent (); } -#ifdef HAVE_GETPWENT +#if defined (HAVE_GETPWENT) while (entry = getpwent ()) { /* Null usernames should result in all users as possible completions. */ @@ -1676,7 +1874,7 @@ rl_username_completion_function (text, state) if (entry == 0) { -#ifdef HAVE_GETPWENT +#if defined (HAVE_GETPWENT) endpwent (); #endif return ((char *)NULL); @@ -1990,9 +2188,11 @@ rl_menu_complete (count, ignore) return (0); } - match_list_index = (match_list_index + count) % match_list_size; + match_list_index += count; if (match_list_index < 0) match_list_index += match_list_size; + else + match_list_index %= match_list_size; if (match_list_index == 0 && match_list_size > 1) { diff --git a/readline/config.h.bot b/readline/config.h.bot deleted file mode 100644 index d7a6dc4..0000000 --- a/readline/config.h.bot +++ /dev/null @@ -1,22 +0,0 @@ -/* config.h.bot */ -/* modify settings or make new ones based on what autoconf tells us. */ - -/* Ultrix botches type-ahead when switching from canonical to - non-canonical mode, at least through version 4.3 */ -#if !defined (HAVE_TERMIOS_H) || !defined (HAVE_TCGETATTR) || defined (ultrix) -# define TERMIOS_MISSING -#endif - -#if defined (STRCOLL_BROKEN) -# undef HAVE_STRCOLL -#endif - -#if defined (__STDC__) && defined (HAVE_STDARG_H) -# define PREFER_STDARG -# define USE_VARARGS -#else -# if defined (HAVE_VARARGS_H) -# define PREFER_VARARGS -# define USE_VARARGS -# endif -#endif diff --git a/readline/config.h.in b/readline/config.h.in index 8d1f0bc..b4aae98 100644 --- a/readline/config.h.in +++ b/readline/config.h.in @@ -1,11 +1,17 @@ /* config.h.in. Maintained by hand. */ +/* Define NO_MULTIBYTE_SUPPORT to not compile in support for multibyte + characters, even if the OS supports them. */ +#undef NO_MULTIBYTE_SUPPORT + /* Define if on MINIX. */ #undef _MINIX /* Define as the return type of signal handlers (int or void). */ #undef RETSIGTYPE +#undef VOID_SIGHANDLER + /* Characteristics of the compiler. */ #undef const @@ -20,11 +26,18 @@ /* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */ #undef STAT_MACROS_BROKEN -#undef VOID_SIGHANDLER - /* Define if you have the fcntl function. */ -#undef HAVE_FCNTL - +#undef HAVE_FCNTL + +/* Define if you have the getpwent function. */ +#undef HAVE_GETPWENT + +/* Define if you have the getpwnam function. */ +#undef HAVE_GETPWNAM + +/* Define if you have the getpwuid function. */ +#undef HAVE_GETPWUID + /* Define if you have the isascii function. */ #undef HAVE_ISASCII @@ -37,6 +50,9 @@ /* Define if you have the lstat function. */ #undef HAVE_LSTAT +/* Define if you have the mbrlen function. */ +#undef HAVE_MBRLEN + /* Define if you have the mbrtowc function. */ #undef HAVE_MBRTOWC @@ -49,15 +65,6 @@ /* Define if you have the putenv function. */ #undef HAVE_PUTENV -/* Define if you have the getpwent function. */ -#undef HAVE_GETPWENT - -/* Define if you have the getpwnam function. */ -#undef HAVE_GETPWNAM - -/* Define if you have the getpwnam function. */ -#undef HAVE_GETPWUID - /* Define if you have the select function. */ #undef HAVE_SELECT @@ -84,12 +91,20 @@ /* Define if you have the vsnprintf function. */ #undef HAVE_VSNPRINTF +/* Define if you have the wctomb function. */ +#undef HAVE_WCTOMB + /* Define if you have the wcwidth function. */ #undef HAVE_WCWIDTH +#undef STDC_HEADERS + /* Define if you have the <dirent.h> header file. */ #undef HAVE_DIRENT_H +/* Define if you have the <fcntl.h> header file. */ +#undef HAVE_FCNTL_H + /* Define if you have the <langinfo.h> header file. */ #undef HAVE_LANGINFO_H @@ -198,6 +213,8 @@ #undef HAVE_POSIX_SIGSETJMP +#undef CTYPE_NON_ASCII + /* modify settings or make new ones based on what autoconf tells us. */ /* Ultrix botches type-ahead when switching from canonical to diff --git a/readline/configure b/readline/configure index 720d789..17b6f52 100755 --- a/readline/configure +++ b/readline/configure @@ -1,7 +1,7 @@ #! /bin/sh -# From configure.in for Readline 4.3, version 2.45, from autoconf version AC_ACVERSION. +# From configure.in for Readline 5.1, version 2.59. # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.59 for readline 4.3. +# Generated by GNU Autoconf 2.59 for readline 5.1-release. # # Report bugs to <bug-readline@gnu.org>. # @@ -270,8 +270,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='readline' PACKAGE_TARNAME='readline' -PACKAGE_VERSION='4.3' -PACKAGE_STRING='readline 4.3' +PACKAGE_VERSION='5.1-release' +PACKAGE_STRING='readline 5.1-release' PACKAGE_BUGREPORT='bug-readline@gnu.org' ac_unique_file="readline.h" @@ -312,7 +312,7 @@ ac_includes_default="\ # include <unistd.h> #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os SET_MAKE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP CROSS_COMPILING_FLAG CC_FOR_BUILD INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AR RANLIB ac_ct_RANLIB MAKE_SHELL WCWIDTH_OBJ SHOBJ_CC SHOBJ_CFLAGS SHOBJ_LD SHOBJ_LDFLAGS SHOBJ_XLDFLAGS SHOBJ_LIBS SHOBJ_STATUS SHLIB_STATUS SHLIB_XLDFLAGS SHLIB_LIBSUFF SHLIB_LIBVERSION SHLIB_LIBS SHLIB_MAJOR SHLIB_MINOR STATIC_TARGET SHARED_TARGET STATIC_INSTALL_TARGET SHARED_INSTALL_TARGET BUILD_DIR LOCAL_CFLAGS LOCAL_LDFLAGS LOCAL_DEFS ARFLAGS LIBVERSION TERMCAP_LIB LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os CROSS_COMPILE SET_MAKE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP CC_FOR_BUILD INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AR RANLIB ac_ct_RANLIB MAKE_SHELL WCWIDTH_OBJ SHOBJ_CC SHOBJ_CFLAGS SHOBJ_LD SHOBJ_LDFLAGS SHOBJ_XLDFLAGS SHOBJ_LIBS SHOBJ_STATUS SHLIB_STATUS SHLIB_XLDFLAGS SHLIB_DOT SHLIB_LIBPREF SHLIB_LIBSUFF SHLIB_LIBVERSION SHLIB_DLLVERSION SHLIB_LIBS SHLIB_MAJOR SHLIB_MINOR STATIC_TARGET SHARED_TARGET STATIC_INSTALL_TARGET SHARED_INSTALL_TARGET PURIFY BUILD_DIR LOCAL_CFLAGS LOCAL_LDFLAGS LOCAL_DEFS ARFLAGS LIBVERSION TERMCAP_LIB LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -781,7 +781,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures readline 4.3 to adapt to many kinds of systems. +\`configure' configures readline 5.1-release to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -842,17 +842,14 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of readline 4.3:";; + short | recursive ) echo "Configuration of readline 5.1-release:";; esac cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] -<<<<<<< configure - --enable-shared build shared libraries [default=NO] -======= ->>>>>>> 1.6 + --enable-multibyte enable multibyte characters if OS supports them --enable-static build static libraries [default=YES] Optional Packages: @@ -860,6 +857,7 @@ Optional Packages: --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-curses use the curses library instead of the termcap library + --with-purify configure to postprocess with purify Some influential environment variables: CC C compiler command @@ -962,14 +960,14 @@ esac else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi - cd $ac_popdir + cd "$ac_popdir" done fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF -readline configure 4.3 +readline configure 5.1-release generated by GNU Autoconf 2.59 Copyright (C) 2003 Free Software Foundation, Inc. @@ -983,7 +981,7 @@ cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by readline $as_me 4.3, which was +It was created by readline $as_me 5.1-release, which was generated by GNU Autoconf 2.59. Invocation command line was $ $0 $@ @@ -1323,13 +1321,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu - ac_config_headers="$ac_config_headers config.h" - - -LIBVERSION=4.3 - ac_aux_dir= -for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do +for ac_dir in `cd $srcdir;pwd`/.. $srcdir/`cd $srcdir;pwd`/..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" @@ -1345,14 +1338,19 @@ for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do fi done if test -z "$ac_aux_dir"; then - { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 -echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \`cd $srcdir;pwd\`/.. $srcdir/\`cd $srcdir;pwd\`/.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in \`cd $srcdir;pwd\`/.. $srcdir/\`cd $srcdir;pwd\`/.." >&2;} { (exit 1); exit 1; }; } fi ac_config_guess="$SHELL $ac_aux_dir/config.guess" ac_config_sub="$SHELL $ac_aux_dir/config.sub" ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + ac_config_headers="$ac_config_headers config.h" + + +LIBVERSION=5.1 + # Make sure we can run config.sub. $ac_config_sub sun4 >/dev/null 2>&1 || { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 @@ -1409,6 +1407,7 @@ host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` opt_curses=no +opt_purify=no # Check whether --with-curses or --without-curses was given. @@ -1417,19 +1416,69 @@ if test "${with_curses+set}" = set; then opt_curses=$withval fi; +# Check whether --with-purify or --without-purify was given. +if test "${with_purify+set}" = set; then + withval="$with_purify" + opt_purify=$withval +fi; + if test "$opt_curses" = "yes"; then prefer_curses=yes fi +if test "$opt_purify" = yes; then + PURIFY="purify" +else + PURIFY= +fi + +opt_multibyte=yes opt_static_libs=yes opt_shared_libs=no +# Check whether --enable-multibyte or --disable-multibyte was given. +if test "${enable_multibyte+set}" = set; then + enableval="$enable_multibyte" + opt_multibyte=$enableval +fi; # Check whether --enable-static or --disable-static was given. if test "${enable_static+set}" = set; then enableval="$enable_static" opt_static_libs=$enableval fi; +if test $opt_multibyte = no; then +cat >>confdefs.h <<\_ACEOF +#define NO_MULTIBYTE_SUPPORT 1 +_ACEOF + +fi + + + +if test "x$cross_compiling" = "xyes"; then + case "${host}" in + *-cygwin*) + cross_cache=${srcdir}/cross-build/cygwin.cache + ;; + *-mingw*) + cross_cache=${srcdir}/cross-build/mingw.cache + ;; + i[3456]86-*-beos*) + cross_cache=${srcdir}/cross-build/x86-beos.cache + ;; + *) echo "configure: cross-compiling for $host is not supported" >&2 + ;; + esac + if test -n "${cross_cache}" && test -r "${cross_cache}"; then + echo "loading cross-build cache file ${cross_cache}" + . ${cross_cache} + fi + unset cross_cache + CROSS_COMPILE='-DCROSS_COMPILING' + +fi + echo "" echo "Beginning configuration for readline-$LIBVERSION for ${host_cpu}-${host_vendor}-${host_os}" echo "" @@ -2034,8 +2083,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2093,8 +2141,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2210,8 +2257,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2265,8 +2311,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2311,8 +2356,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2356,8 +2400,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2680,8 +2723,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2851,8 +2893,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2915,8 +2956,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3071,13 +3111,6 @@ if test "x$cross_compiling" = "xyes"; then fi fi -if test "x$cross_compiling" = "xyes"; then - CROSS_COMPILING_FLAG=-DCROSS_COMPILING -else - CROSS_COMPILING_FLAG= -fi - - if test -z "$CC_FOR_BUILD"; then if test "x$cross_compiling" = "xno"; then CC_FOR_BUILD='$(CC)' @@ -3416,8 +3449,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3500,8 +3532,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3571,8 +3602,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3634,8 +3664,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3700,8 +3729,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3735,6 +3763,172 @@ _ACEOF fi +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ctype.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + + echo "$as_me:$LINENO: checking whether stat file-mode macros are broken" >&5 echo $ECHO_N "checking whether stat file-mode macros are broken... $ECHO_C" >&6 if test "${ac_cv_header_stat_broken+set}" = set; then @@ -3833,8 +4027,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3906,8 +4099,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3961,8 +4153,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4033,8 +4224,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4088,8 +4278,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4127,23 +4316,322 @@ fi +for ac_func in fcntl kill lstat +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + + + + + + + + +for ac_func in memmove putenv select setenv setlocale \ + strcasecmp strpbrk tcgetattr vsnprintf +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $ac_func innocuous_$ac_func +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif +#undef $ac_func +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + +for ac_func in isascii isxdigit +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif +#undef $ac_func +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF +fi +done -for ac_func in fcntl kill lstat memmove putenv select setenv setlocale \ - strcasecmp strpbrk tcgetattr vsnprintf isascii isxdigit \ - getpwnam getpwent getpwuid +for ac_func in getpwent getpwnam getpwuid do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 @@ -4211,8 +4699,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4318,14 +4805,160 @@ fi +for ac_header in fcntl.h unistd.h stdlib.h varargs.h stdarg.h string.h strings.h \ + limits.h locale.h pwd.h memory.h termcap.h termios.h termio.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ----------------------------------- ## +## Report this to bug-readline@gnu.org ## +## ----------------------------------- ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done -for ac_header in unistd.h stdlib.h varargs.h stdarg.h string.h strings.h \ - limits.h sys/ptem.h sys/pte.h sys/stream.h sys/select.h \ - termcap.h termios.h termio.h sys/file.h locale.h memory.h \ - pwd.h + + + +for ac_header in sys/pte.h sys/stream.h sys/select.h sys/file.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then @@ -4358,8 +4991,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4476,6 +5108,71 @@ done +for ac_header in sys/ptem.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#if HAVE_SYS_STREAM_H +# include <sys/stream.h> +#endif + + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + echo "$as_me:$LINENO: checking for type of signal functions" >&5 echo $ECHO_N "checking for type of signal functions... $ECHO_C" >&6 if test "${bash_cv_signal_vintage+set}" = set; then @@ -4512,8 +5209,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4558,8 +5254,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4607,8 +5302,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4880,8 +5574,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5001,6 +5694,89 @@ _ACEOF fi +echo "$as_me:$LINENO: checking whether the ctype macros accept non-ascii characters" >&5 +echo $ECHO_N "checking whether the ctype macros accept non-ascii characters... $ECHO_C" >&6 +if test "${bash_cv_func_ctype_nonascii+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + { echo "$as_me:$LINENO: WARNING: cannot check ctype macros if cross compiling -- defaulting to no" >&5 +echo "$as_me: WARNING: cannot check ctype macros if cross compiling -- defaulting to no" >&2;} + bash_cv_func_ctype_nonascii=no + +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#ifdef HAVE_LOCALE_H +#include <locale.h> +#endif +#include <stdio.h> +#include <ctype.h> + +main(c, v) +int c; +char *v[]; +{ + char *deflocale; + unsigned char x; + int r1, r2; + +#ifdef HAVE_SETLOCALE + /* We take a shot here. If that locale is not known, try the + system default. We try this one because '\342' (226) is + known to be a printable character in that locale. */ + deflocale = setlocale(LC_ALL, "en_US.ISO8859-1"); + if (deflocale == 0) + deflocale = setlocale(LC_ALL, ""); +#endif + + x = '\342'; + r1 = isprint(x); + x -= 128; + r2 = isprint(x); + exit (r1 == 0 || r2 == 0); +} + +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + bash_cv_func_ctype_nonascii=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +bash_cv_func_ctype_nonascii=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi + +echo "$as_me:$LINENO: result: $bash_cv_func_ctype_nonascii" >&5 +echo "${ECHO_T}$bash_cv_func_ctype_nonascii" >&6 +if test $bash_cv_func_ctype_nonascii = yes; then +cat >>confdefs.h <<\_ACEOF +#define CTYPE_NON_ASCII 1 +_ACEOF + +fi + + echo "$as_me:$LINENO: checking whether getpw functions are declared in pwd.h" >&5 echo $ECHO_N "checking whether getpw functions are declared in pwd.h... $ECHO_C" >&6 if test "${bash_cv_getpw_declared+set}" = set; then @@ -5148,8 +5924,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5209,8 +5984,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5271,8 +6045,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5332,8 +6105,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5394,8 +6166,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5437,8 +6208,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5483,8 +6253,8 @@ echo "${ECHO_T}not found" >&6 fi -echo "$as_me:$LINENO: checking if struct dirent has a d_ino member" >&5 -echo $ECHO_N "checking if struct dirent has a d_ino member... $ECHO_C" >&6 +echo "$as_me:$LINENO: checking for struct dirent.d_ino" >&5 +echo $ECHO_N "checking for struct dirent.d_ino... $ECHO_C" >&6 if test "${bash_cv_dirent_has_dino+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -5534,8 +6304,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5561,14 +6330,14 @@ echo "$as_me:$LINENO: result: $bash_cv_dirent_has_dino" >&5 echo "${ECHO_T}$bash_cv_dirent_has_dino" >&6 if test $bash_cv_dirent_has_dino = yes; then cat >>confdefs.h <<\_ACEOF -#define STRUCT_DIRENT_HAS_D_INO 1 +#define HAVE_STRUCT_DIRENT_D_INO 1 _ACEOF fi -echo "$as_me:$LINENO: checking if struct dirent has a d_fileno member" >&5 -echo $ECHO_N "checking if struct dirent has a d_fileno member... $ECHO_C" >&6 +echo "$as_me:$LINENO: checking for struct dirent.d_fileno" >&5 +echo $ECHO_N "checking for struct dirent.d_fileno... $ECHO_C" >&6 if test "${bash_cv_dirent_has_d_fileno+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -5618,8 +6387,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5645,7 +6413,7 @@ echo "$as_me:$LINENO: result: $bash_cv_dirent_has_d_fileno" >&5 echo "${ECHO_T}$bash_cv_dirent_has_d_fileno" >&6 if test $bash_cv_dirent_has_d_fileno = yes; then cat >>confdefs.h <<\_ACEOF -#define STRUCT_DIRENT_HAS_D_FILENO 1 +#define HAVE_STRUCT_DIRENT_D_FILENO 1 _ACEOF fi @@ -5665,6 +6433,98 @@ fi if test "${bash_cv_termcap_lib+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else + echo "$as_me:$LINENO: checking for tgetent" >&5 +echo $ECHO_N "checking for tgetent... $ECHO_C" >&6 +if test "${ac_cv_func_tgetent+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define tgetent to an innocuous variant, in case <limits.h> declares tgetent. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define tgetent innocuous_tgetent + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char tgetent (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef tgetent + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char tgetent (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_tgetent) || defined (__stub___tgetent) +choke me +#else +char (*f) () = tgetent; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != tgetent; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_tgetent=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_tgetent=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_tgetent" >&5 +echo "${ECHO_T}$ac_cv_func_tgetent" >&6 +if test $ac_cv_func_tgetent = yes; then + bash_cv_termcap_lib=libc +else echo "$as_me:$LINENO: checking for tgetent in -ltermcap" >&5 echo $ECHO_N "checking for tgetent in -ltermcap... $ECHO_C" >&6 if test "${ac_cv_lib_termcap_tgetent+set}" = set; then @@ -5703,8 +6563,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5770,8 +6629,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5837,8 +6695,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5904,8 +6761,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5944,6 +6800,8 @@ fi fi +fi + if test "X$_bash_needmsg" = "Xyes"; then echo "$as_me:$LINENO: checking which library has the termcap functions" >&5 echo $ECHO_N "checking which library has the termcap functions... $ECHO_C" >&6 @@ -5963,6 +6821,9 @@ TERMCAP_DEP= elif test $bash_cv_termcap_lib = libncurses; then TERMCAP_LIB=-lncurses TERMCAP_DEP= +elif test $bash_cv_termcap_lib = libc; then +TERMCAP_LIB= +TERMCAP_DEP= else TERMCAP_LIB=-lcurses TERMCAP_DEP= @@ -6011,8 +6872,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -6161,8 +7021,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -6311,8 +7170,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -6428,6 +7286,102 @@ fi done +echo "$as_me:$LINENO: checking for mbsrtowcs" >&5 +echo $ECHO_N "checking for mbsrtowcs... $ECHO_C" >&6 +if test "${ac_cv_func_mbsrtowcs+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define mbsrtowcs to an innocuous variant, in case <limits.h> declares mbsrtowcs. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define mbsrtowcs innocuous_mbsrtowcs + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char mbsrtowcs (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef mbsrtowcs + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char mbsrtowcs (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_mbsrtowcs) || defined (__stub___mbsrtowcs) +choke me +#else +char (*f) () = mbsrtowcs; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != mbsrtowcs; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_mbsrtowcs=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_mbsrtowcs=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_mbsrtowcs" >&5 +echo "${ECHO_T}$ac_cv_func_mbsrtowcs" >&6 +if test $ac_cv_func_mbsrtowcs = yes; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_MBSRTOWCS 1 +_ACEOF + +fi + echo "$as_me:$LINENO: checking for mbrtowc" >&5 echo $ECHO_N "checking for mbrtowc... $ECHO_C" >&6 if test "${ac_cv_func_mbrtowc+set}" = set; then @@ -6493,8 +7447,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -6525,9 +7478,9 @@ _ACEOF fi -echo "$as_me:$LINENO: checking for mbsrtowcs" >&5 -echo $ECHO_N "checking for mbsrtowcs... $ECHO_C" >&6 -if test "${ac_cv_func_mbsrtowcs+set}" = set; then +echo "$as_me:$LINENO: checking for mbrlen" >&5 +echo $ECHO_N "checking for mbrlen... $ECHO_C" >&6 +if test "${ac_cv_func_mbrlen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF @@ -6536,12 +7489,12 @@ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -/* Define mbsrtowcs to an innocuous variant, in case <limits.h> declares mbsrtowcs. +/* Define mbrlen to an innocuous variant, in case <limits.h> declares mbrlen. For example, HP-UX 11i <limits.h> declares gettimeofday. */ -#define mbsrtowcs innocuous_mbsrtowcs +#define mbrlen innocuous_mbrlen /* System header to define __stub macros and hopefully few prototypes, - which can conflict with char mbsrtowcs (); below. + which can conflict with char mbrlen (); below. Prefer <limits.h> to <assert.h> if __STDC__ is defined, since <limits.h> exists even on freestanding compilers. */ @@ -6551,7 +7504,7 @@ cat >>conftest.$ac_ext <<_ACEOF # include <assert.h> #endif -#undef mbsrtowcs +#undef mbrlen /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus @@ -6560,14 +7513,14 @@ extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ -char mbsrtowcs (); +char mbrlen (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ -#if defined (__stub_mbsrtowcs) || defined (__stub___mbsrtowcs) +#if defined (__stub_mbrlen) || defined (__stub___mbrlen) choke me #else -char (*f) () = mbsrtowcs; +char (*f) () = mbrlen; #endif #ifdef __cplusplus } @@ -6576,7 +7529,7 @@ char (*f) () = mbsrtowcs; int main () { -return f != mbsrtowcs; +return f != mbrlen; ; return 0; } @@ -6590,8 +7543,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -6603,21 +7555,117 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then - ac_cv_func_mbsrtowcs=yes + ac_cv_func_mbrlen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_func_mbsrtowcs=no +ac_cv_func_mbrlen=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_func_mbsrtowcs" >&5 -echo "${ECHO_T}$ac_cv_func_mbsrtowcs" >&6 -if test $ac_cv_func_mbsrtowcs = yes; then +echo "$as_me:$LINENO: result: $ac_cv_func_mbrlen" >&5 +echo "${ECHO_T}$ac_cv_func_mbrlen" >&6 +if test $ac_cv_func_mbrlen = yes; then cat >>confdefs.h <<\_ACEOF -#define HAVE_MBSRTOWCS 1 +#define HAVE_MBRLEN 1 +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for wctomb" >&5 +echo $ECHO_N "checking for wctomb... $ECHO_C" >&6 +if test "${ac_cv_func_wctomb+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define wctomb to an innocuous variant, in case <limits.h> declares wctomb. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define wctomb innocuous_wctomb + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char wctomb (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef wctomb + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char wctomb (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_wctomb) || defined (__stub___wctomb) +choke me +#else +char (*f) () = wctomb; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != wctomb; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_wctomb=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_wctomb=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_wctomb" >&5 +echo "${ECHO_T}$ac_cv_func_wctomb" >&6 +if test $ac_cv_func_wctomb = yes; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_WCTOMB 1 _ACEOF fi @@ -6687,8 +7735,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -6719,6 +7766,103 @@ _ACEOF fi +echo "$as_me:$LINENO: checking for wcsdup" >&5 +echo $ECHO_N "checking for wcsdup... $ECHO_C" >&6 +if test "${ac_cv_func_wcsdup+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define wcsdup to an innocuous variant, in case <limits.h> declares wcsdup. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define wcsdup innocuous_wcsdup + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char wcsdup (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef wcsdup + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char wcsdup (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_wcsdup) || defined (__stub___wcsdup) +choke me +#else +char (*f) () = wcsdup; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != wcsdup; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_wcsdup=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_wcsdup=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_wcsdup" >&5 +echo "${ECHO_T}$ac_cv_func_wcsdup" >&6 +if test $ac_cv_func_wcsdup = yes; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_WCSDUP 1 +_ACEOF + +fi + + if test "$ac_cv_func_wcwidth" = no && test "$ac_cv_header_wchar_h" = yes; then WCWIDTH_OBJ=wcwidth.o else @@ -6737,37 +7881,36 @@ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ + #include <wchar.h> int main () { -int -main () -{ + mbstate_t ps; - return 0; -} + mbstate_t *psp; + psp = (mbstate_t *)0; + ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -6780,8 +7923,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 bash_cv_have_mbstate_t=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $bash_cv_have_mbstate_t" >&5 echo "${ECHO_T}$bash_cv_have_mbstate_t" >&6 @@ -6821,8 +7963,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -6872,7 +8013,16 @@ esac if test -f ${srcdir}/support/shobj-conf; then echo "$as_me:$LINENO: checking configuration for building shared libraries" >&5 echo $ECHO_N "checking configuration for building shared libraries... $ECHO_C" >&6 - eval `${CONFIG_SHELL-/bin/sh} ${srcdir}/support/shobj-conf -C "${CC}" -c ${host_cpu} -o ${host_os} -v ${host_vendor}` + eval `TERMCAP_LIB=$TERMCAP_LIB ${CONFIG_SHELL-/bin/sh} ${srcdir}/support/shobj-conf -C "${CC}" -c ${host_cpu} -o ${host_os} -v ${host_vendor}` + +# case "$SHLIB_LIBS" in +# *curses*|*termcap*|*termlib*) ;; +# *) SHLIB_LIBS="$SHLIB_LIBS $TERMCAP_LIB" ;; +# esac + + + + @@ -6921,6 +8071,12 @@ msdosdjgpp*) BUILD_DIR=`pwd.exe` ;; # to prevent //d/path/file *) BUILD_DIR=`pwd` ;; esac +case "$BUILD_DIR" in +*\ *) BUILD_DIR=`echo "$BUILD_DIR" | sed 's: :\\\\ :g'` ;; +*) ;; +esac + + @@ -7302,7 +8458,7 @@ _ASBOX } >&5 cat >&5 <<_CSEOF -This file was extended by readline $as_me 4.3, which was +This file was extended by readline $as_me 5.1-release, which was generated by GNU Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -7365,7 +8521,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -readline config.status 4.3 +readline config.status 5.1-release configured by $0, generated by GNU Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" @@ -7567,6 +8723,7 @@ s,@host@,$host,;t t s,@host_cpu@,$host_cpu,;t t s,@host_vendor@,$host_vendor,;t t s,@host_os@,$host_os,;t t +s,@CROSS_COMPILE@,$CROSS_COMPILE,;t t s,@SET_MAKE@,$SET_MAKE,;t t s,@CC@,$CC,;t t s,@CFLAGS@,$CFLAGS,;t t @@ -7577,7 +8734,6 @@ s,@EXEEXT@,$EXEEXT,;t t s,@OBJEXT@,$OBJEXT,;t t s,@CPP@,$CPP,;t t s,@EGREP@,$EGREP,;t t -s,@CROSS_COMPILING_FLAG@,$CROSS_COMPILING_FLAG,;t t s,@CC_FOR_BUILD@,$CC_FOR_BUILD,;t t s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t @@ -7596,8 +8752,11 @@ s,@SHOBJ_LIBS@,$SHOBJ_LIBS,;t t s,@SHOBJ_STATUS@,$SHOBJ_STATUS,;t t s,@SHLIB_STATUS@,$SHLIB_STATUS,;t t s,@SHLIB_XLDFLAGS@,$SHLIB_XLDFLAGS,;t t +s,@SHLIB_DOT@,$SHLIB_DOT,;t t +s,@SHLIB_LIBPREF@,$SHLIB_LIBPREF,;t t s,@SHLIB_LIBSUFF@,$SHLIB_LIBSUFF,;t t s,@SHLIB_LIBVERSION@,$SHLIB_LIBVERSION,;t t +s,@SHLIB_DLLVERSION@,$SHLIB_DLLVERSION,;t t s,@SHLIB_LIBS@,$SHLIB_LIBS,;t t s,@SHLIB_MAJOR@,$SHLIB_MAJOR,;t t s,@SHLIB_MINOR@,$SHLIB_MINOR,;t t @@ -7605,6 +8764,7 @@ s,@STATIC_TARGET@,$STATIC_TARGET,;t t s,@SHARED_TARGET@,$SHARED_TARGET,;t t s,@STATIC_INSTALL_TARGET@,$STATIC_INSTALL_TARGET,;t t s,@SHARED_INSTALL_TARGET@,$SHARED_INSTALL_TARGET,;t t +s,@PURIFY@,$PURIFY,;t t s,@BUILD_DIR@,$BUILD_DIR,;t t s,@LOCAL_CFLAGS@,$LOCAL_CFLAGS,;t t s,@LOCAL_LDFLAGS@,$LOCAL_LDFLAGS,;t t @@ -7780,11 +8940,6 @@ esac *) ac_INSTALL=$ac_top_builddir$INSTALL ;; esac - if test x"$ac_file" != x-; then - { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - rm -f "$ac_file" - fi # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ @@ -7823,6 +8978,12 @@ echo "$as_me: error: cannot find input file: $f" >&2;} fi;; esac done` || { (exit 1); exit 1; } + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub diff --git a/readline/configure.in b/readline/configure.in index c436cca..6c7b818 100644 --- a/readline/configure.in +++ b/readline/configure.in @@ -4,38 +4,102 @@ dnl dnl report bugs to chet@po.cwru.edu dnl dnl Process this file with autoconf to produce a configure script. -AC_REVISION([for Readline 4.3, version 2.45, from autoconf version] AC_ACVERSION) -AC_INIT(readline, 4.3, bug-readline@gnu.org) +# Copyright (C) 1987-2005 Free Software Foundation, Inc. + +# 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, 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. + +AC_REVISION([for Readline 5.1, version 2.59]) + +AC_INIT(readline, 5.1-release, bug-readline@gnu.org) dnl make sure we are using a recent autoconf version AC_PREREQ(2.50) AC_CONFIG_SRCDIR(readline.h) +dnl GDB LOCAL dnl AC_CONFIG_AUX_DIR(./support) +AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/..) AC_CONFIG_HEADERS(config.h) dnl update the value of RL_READLINE_VERSION in readline.h when this changes -LIBVERSION=4.3 +LIBVERSION=5.1 AC_CANONICAL_HOST dnl configure defaults opt_curses=no +opt_purify=no dnl arguments to configure AC_ARG_WITH(curses, AC_HELP_STRING([--with-curses], [use the curses library instead of the termcap library]), opt_curses=$withval) +AC_ARG_WITH(purify, AC_HELP_STRING([--with-purify], [configure to postprocess with purify]), opt_purify=$withval) if test "$opt_curses" = "yes"; then prefer_curses=yes fi +if test "$opt_purify" = yes; then + PURIFY="purify" +else + PURIFY= +fi + dnl option parsing for optional features +opt_multibyte=yes opt_static_libs=yes opt_shared_libs=no +AC_ARG_ENABLE(multibyte, AC_HELP_STRING([--enable-multibyte], [enable multibyte characters if OS supports them]), opt_multibyte=$enableval) +dnl AC_ARG_ENABLE(shared, AC_HELP_STRING([--enable-shared], [build shared libraries [[default=YES]]]), opt_shared_libs=$enableval) AC_ARG_ENABLE(static, AC_HELP_STRING([--enable-static], [build static libraries [[default=YES]]]), opt_static_libs=$enableval) +if test $opt_multibyte = no; then +AC_DEFINE(NO_MULTIBYTE_SUPPORT) +fi + +dnl load up the cross-building cache file -- add more cases and cache +dnl files as necessary + +dnl Note that host and target machine are the same, and different than the +dnl build machine. + +if test "x$cross_compiling" = "xyes"; then + case "${host}" in + *-cygwin*) + cross_cache=${srcdir}/cross-build/cygwin.cache + ;; + *-mingw*) + cross_cache=${srcdir}/cross-build/mingw.cache + ;; + i[[3456]]86-*-beos*) + cross_cache=${srcdir}/cross-build/x86-beos.cache + ;; + *) echo "configure: cross-compiling for $host is not supported" >&2 + ;; + esac + if test -n "${cross_cache}" && test -r "${cross_cache}"; then + echo "loading cross-build cache file ${cross_cache}" + . ${cross_cache} + fi + unset cross_cache + CROSS_COMPILE='-DCROSS_COMPILING' + AC_SUBST(CROSS_COMPILE) +fi + echo "" echo "Beginning configuration for readline-$LIBVERSION for ${host_cpu}-${host_vendor}-${host_os}" echo "" @@ -49,7 +113,8 @@ dnl AC_AIX AC_MINIX dnl BEGIN changes for CYGNUS cross-building for Cygwin - +dnl NOTE: Some of these changes may no longer be necessary. + dnl load up the cross-building cache file -- add more cases and cache dnl files as necessary if test "x$cross_compiling" = "xyes"; then @@ -73,14 +138,7 @@ if test "x$cross_compiling" = "xyes"; then unset cross_cache fi fi - -if test "x$cross_compiling" = "xyes"; then - CROSS_COMPILING_FLAG=-DCROSS_COMPILING -else - CROSS_COMPILING_FLAG= -fi -AC_SUBST(CROSS_COMPILING_FLAG) - + if test -z "$CC_FOR_BUILD"; then if test "x$cross_compiling" = "xno"; then CC_FOR_BUILD='$(CC)' @@ -115,19 +173,29 @@ AC_TYPE_SIGNAL AC_TYPE_SIZE_T AC_CHECK_TYPE(ssize_t, int) +AC_HEADER_STDC + AC_HEADER_STAT AC_HEADER_DIRENT -AC_CHECK_FUNCS(fcntl kill lstat memmove putenv select setenv setlocale \ - strcasecmp strpbrk tcgetattr vsnprintf isascii isxdigit \ - getpwnam getpwent getpwuid) +AC_CHECK_FUNCS(fcntl kill lstat) +AC_CHECK_FUNCS(memmove putenv select setenv setlocale \ + strcasecmp strpbrk tcgetattr vsnprintf) +AC_CHECK_FUNCS(isascii isxdigit) +AC_CHECK_FUNCS(getpwent getpwnam getpwuid) AC_FUNC_STRCOLL -AC_CHECK_HEADERS(unistd.h stdlib.h varargs.h stdarg.h string.h strings.h \ - limits.h sys/ptem.h sys/pte.h sys/stream.h sys/select.h \ - termcap.h termios.h termio.h sys/file.h locale.h memory.h \ - pwd.h) +AC_CHECK_HEADERS(fcntl.h unistd.h stdlib.h varargs.h stdarg.h string.h strings.h \ + limits.h locale.h pwd.h memory.h termcap.h termios.h termio.h) +AC_CHECK_HEADERS(sys/pte.h sys/stream.h sys/select.h sys/file.h) + +AC_CHECK_HEADERS(sys/ptem.h,,, +[[ +#if HAVE_SYS_STREAM_H +# include <sys/stream.h> +#endif +]]) BASH_SYS_SIGNAL_VINTAGE BASH_SYS_REINSTALL_SIGHANDLERS @@ -135,6 +203,7 @@ BASH_SYS_REINSTALL_SIGHANDLERS BASH_FUNC_POSIX_SETJMP BASH_FUNC_LSTAT BASH_FUNC_STRCOLL +BASH_FUNC_CTYPE_NONASCII BASH_CHECK_GETPW_FUNCS @@ -179,7 +248,13 @@ esac # if test -f ${srcdir}/support/shobj-conf; then AC_MSG_CHECKING(configuration for building shared libraries) - eval `${CONFIG_SHELL-/bin/sh} ${srcdir}/support/shobj-conf -C "${CC}" -c ${host_cpu} -o ${host_os} -v ${host_vendor}` + eval `TERMCAP_LIB=$TERMCAP_LIB ${CONFIG_SHELL-/bin/sh} ${srcdir}/support/shobj-conf -C "${CC}" -c ${host_cpu} -o ${host_os} -v ${host_vendor}` + +# case "$SHLIB_LIBS" in +# *curses*|*termcap*|*termlib*) ;; +# *) SHLIB_LIBS="$SHLIB_LIBS $TERMCAP_LIB" ;; +# esac + AC_SUBST(SHOBJ_CC) AC_SUBST(SHOBJ_CFLAGS) AC_SUBST(SHOBJ_LD) @@ -189,8 +264,11 @@ if test -f ${srcdir}/support/shobj-conf; then AC_SUBST(SHOBJ_STATUS) AC_SUBST(SHLIB_STATUS) AC_SUBST(SHLIB_XLDFLAGS) + AC_SUBST(SHLIB_DOT) + AC_SUBST(SHLIB_LIBPREF) AC_SUBST(SHLIB_LIBSUFF) AC_SUBST(SHLIB_LIBVERSION) + AC_SUBST(SHLIB_DLLVERSION) AC_SUBST(SHLIB_LIBS) AC_MSG_RESULT($SHLIB_STATUS) @@ -227,6 +305,12 @@ msdosdjgpp*) BUILD_DIR=`pwd.exe` ;; # to prevent //d/path/file *) BUILD_DIR=`pwd` ;; esac +case "$BUILD_DIR" in +*\ *) BUILD_DIR=`echo "$BUILD_DIR" | sed 's: :\\\\ :g'` ;; +*) ;; +esac + +AC_SUBST(PURIFY) AC_SUBST(BUILD_DIR) AC_SUBST(CFLAGS) diff --git a/readline/display.c b/readline/display.c index b9bb2d3..0858098 100644 --- a/readline/display.c +++ b/readline/display.c @@ -1,6 +1,6 @@ /* display.c -- readline redisplay facility. */ -/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc. +/* Copyright (C) 1987-2005 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -122,16 +122,24 @@ rl_voidfunc_t *rl_redisplay_function = rl_redisplay; int rl_display_fixed = 0; int _rl_suppress_redisplay = 0; +int _rl_want_redisplay = 0; /* The stuff that gets printed out before the actual text of the line. This is usually pointing to rl_prompt. */ char *rl_display_prompt = (char *)NULL; /* Pseudo-global variables declared here. */ + /* The visible cursor position. If you print some text, adjust this. */ +/* NOTE: _rl_last_c_pos is used as a buffer index when not in a locale + supporting multibyte characters, and an absolute cursor position when + in such a locale. This is an artifact of the donated multibyte support. + Care must be taken when modifying its value. */ int _rl_last_c_pos = 0; int _rl_last_v_pos = 0; +static int cpos_adjusted; + /* Number of lines currently on screen minus 1. */ int _rl_vis_botlin = 0; @@ -182,12 +190,27 @@ static int prompt_invis_chars_first_line; static int prompt_last_screen_line; +static int prompt_physical_chars; + +/* Variables to save and restore prompt and display information. */ + +/* These are getting numerous enough that it's time to create a struct. */ + +static char *saved_local_prompt; +static char *saved_local_prefix; +static int saved_last_invisible; +static int saved_visible_length; +static int saved_prefix_length; +static int saved_invis_chars_first_line; +static int saved_physical_chars; + /* Expand the prompt string S and return the number of visible characters in *LP, if LP is not null. This is currently more-or-less a placeholder for expansion. LIP, if non-null is a place to store the index of the last invisible character in the returned string. NIFLP, if non-zero, is a place to store the number of invisible characters in - the first prompt line. */ + the first prompt line. The previous are used as byte counts -- indexes + into a character buffer. */ /* Current implementation: \001 (^A) start non-visible characters @@ -197,19 +220,25 @@ static int prompt_last_screen_line; \002 are assumed to be `visible'. */ static char * -expand_prompt (pmt, lp, lip, niflp) +expand_prompt (pmt, lp, lip, niflp, vlp) char *pmt; - int *lp, *lip, *niflp; + int *lp, *lip, *niflp, *vlp; { char *r, *ret, *p; - int l, rl, last, ignoring, ninvis, invfl; + int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars; /* Short-circuit if we can. */ - if (strchr (pmt, RL_PROMPT_START_IGNORE) == 0) + if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (pmt, RL_PROMPT_START_IGNORE) == 0) { r = savestring (pmt); if (lp) *lp = strlen (r); + if (lip) + *lip = 0; + if (niflp) + *niflp = 0; + if (vlp) + *vlp = lp ? *lp : strlen (r); return r; } @@ -217,8 +246,9 @@ expand_prompt (pmt, lp, lip, niflp) r = ret = (char *)xmalloc (l + 1); invfl = 0; /* invisible chars in first line of prompt */ + invflset = 0; /* we only want to set invfl once */ - for (rl = ignoring = last = ninvis = 0, p = pmt; p && *p; p++) + for (rl = ignoring = last = ninvis = physchars = 0, p = pmt; p && *p; p++) { /* This code strips the invisible character string markers RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */ @@ -230,18 +260,47 @@ expand_prompt (pmt, lp, lip, niflp) else if (ignoring && *p == RL_PROMPT_END_IGNORE) { ignoring = 0; - last = r - ret - 1; + if (p[-1] != RL_PROMPT_START_IGNORE) + last = r - ret - 1; continue; } else { - *r++ = *p; - if (!ignoring) - rl++; +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + pind = p - pmt; + ind = _rl_find_next_mbchar (pmt, pind, 1, MB_FIND_NONZERO); + l = ind - pind; + while (l--) + *r++ = *p++; + if (!ignoring) + { + rl += ind - pind; + physchars += _rl_col_width (pmt, pind, ind); + } + else + ninvis += ind - pind; + p--; /* compensate for later increment */ + } else - ninvis++; - if (rl == _rl_screenwidth) - invfl = ninvis; +#endif + { + *r++ = *p; + if (!ignoring) + { + rl++; /* visible length byte counter */ + physchars++; + } + else + ninvis++; /* invisible chars byte counter */ + } + + if (invflset == 0 && rl >= _rl_screenwidth) + { + invfl = ninvis; + invflset = 1; + } } } @@ -255,6 +314,8 @@ expand_prompt (pmt, lp, lip, niflp) *lip = last; if (niflp) *niflp = invfl; + if (vlp) + *vlp = physchars; return ret; } @@ -266,7 +327,7 @@ _rl_strip_prompt (pmt) { char *ret; - ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL); + ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL, (int *)NULL); return ret; } @@ -299,7 +360,8 @@ rl_expand_prompt (prompt) FREE (local_prompt_prefix); local_prompt = local_prompt_prefix = (char *)0; - prompt_last_invisible = prompt_visible_length = 0; + prompt_last_invisible = prompt_invis_chars_first_line = 0; + prompt_visible_length = prompt_physical_chars = 0; if (prompt == 0 || *prompt == 0) return (0); @@ -310,7 +372,8 @@ rl_expand_prompt (prompt) /* The prompt is only one logical line, though it might wrap. */ local_prompt = expand_prompt (prompt, &prompt_visible_length, &prompt_last_invisible, - &prompt_invis_chars_first_line); + &prompt_invis_chars_first_line, + &prompt_physical_chars); local_prompt_prefix = (char *)0; return (prompt_visible_length); } @@ -320,13 +383,15 @@ rl_expand_prompt (prompt) t = ++p; local_prompt = expand_prompt (p, &prompt_visible_length, &prompt_last_invisible, - &prompt_invis_chars_first_line); + (int *)NULL, + &prompt_physical_chars); c = *t; *t = '\0'; /* The portion of the prompt string up to and including the final newline is now null-terminated. */ local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length, (int *)NULL, - &prompt_invis_chars_first_line); + &prompt_invis_chars_first_line, + (int *)NULL); *t = c; return (prompt_prefix_length); } @@ -384,8 +449,8 @@ rl_redisplay () { register int in, out, c, linenum, cursor_linenum; register char *line; - int c_pos, inv_botlin, lb_botlin, lb_linenum; - int newlines, lpos, temp; + int c_pos, inv_botlin, lb_botlin, lb_linenum, o_cpos; + int newlines, lpos, temp, modmark, n0, num; char *prompt_this_line; #if defined (HANDLE_MULTIBYTE) wchar_t wc; @@ -401,7 +466,7 @@ rl_redisplay () if (!rl_display_prompt) rl_display_prompt = ""; - if (invisible_line == 0) + if (invisible_line == 0 || vis_lbreaks == 0) { init_line_structures (0); rl_on_new_line (); @@ -415,10 +480,12 @@ rl_redisplay () /* Mark the line as modified or not. We only do this for history lines. */ + modmark = 0; if (_rl_mark_modified_lines && current_history () && rl_undo_list) { line[out++] = '*'; line[out] = '\0'; + modmark = 1; } /* If someone thought that the redisplay was handled, but the currently @@ -472,7 +539,7 @@ rl_redisplay () } } - pmtlen = strlen (prompt_this_line); + prompt_physical_chars = pmtlen = strlen (prompt_this_line); temp = pmtlen + out + 2; if (temp >= line_size) { @@ -531,9 +598,15 @@ rl_redisplay () /* inv_lbreaks[i] is where line i starts in the buffer. */ inv_lbreaks[newlines = 0] = 0; +#if 0 lpos = out - wrap_offset; +#else + lpos = prompt_physical_chars + modmark; +#endif + #if defined (HANDLE_MULTIBYTE) memset (_rl_wrapped_line, 0, vis_lbsize); + num = 0; #endif /* prompt_invis_chars_first_line is the number of invisible characters in @@ -550,17 +623,34 @@ rl_redisplay () prompt_invis_chars_first_line variable could be made into an array saying how many invisible characters there are per line, but that's probably too much work for the benefit gained. How many people have - prompts that exceed two physical lines? */ - temp = ((newlines + 1) * _rl_screenwidth) + -#if 0 - ((newlines == 0) ? prompt_invis_chars_first_line : 0) + + prompts that exceed two physical lines? + Additional logic fix from Edward Catmur <ed@catmur.co.uk> */ +#if defined (HANDLE_MULTIBYTE) + n0 = num; + temp = local_prompt ? strlen (local_prompt) : 0; + while (num < temp) + { + if (_rl_col_width (local_prompt, n0, num) > _rl_screenwidth) + { + num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY); + break; + } + num++; + } + temp = num + #else - ((newlines == 0 && local_prompt_prefix == 0) ? prompt_invis_chars_first_line : 0) + -#endif - ((newlines == 1) ? wrap_offset : 0); - + temp = ((newlines + 1) * _rl_screenwidth) + +#endif /* !HANDLE_MULTIBYTE */ + ((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line + : ((newlines == 1) ? wrap_offset : 0)) + : ((newlines == 0) ? wrap_offset :0)); + inv_lbreaks[++newlines] = temp; +#if defined (HANDLE_MULTIBYTE) + lpos -= _rl_col_width (local_prompt, n0, num); +#else lpos -= _rl_screenwidth; +#endif } prompt_last_screen_line = newlines; @@ -590,7 +680,7 @@ rl_redisplay () #if defined (HANDLE_MULTIBYTE) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) { - if (wc_bytes == (size_t)-1 || wc_bytes == (size_t)-2) + if (MB_INVALIDCH (wc_bytes)) { /* Byte sequence is invalid or shortened. Assume that the first byte represents a character. */ @@ -599,12 +689,12 @@ rl_redisplay () wc_width = 1; memset (&ps, 0, sizeof (mbstate_t)); } - else if (wc_bytes == (size_t)0) + else if (MB_NULLWCH (wc_bytes)) break; /* Found '\0' */ else { temp = wcwidth (wc); - wc_width = (temp < 0) ? 1 : temp; + wc_width = (temp >= 0) ? temp : 1; } } #endif @@ -769,7 +859,7 @@ rl_redisplay () if (_rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up) { - int nleft, pos, changed_screen_line; + int nleft, pos, changed_screen_line, tx; if (!rl_display_fixed || forced_display) { @@ -800,9 +890,26 @@ rl_redisplay () /* For each line in the buffer, do the updating display. */ for (linenum = 0; linenum <= inv_botlin; linenum++) { + o_cpos = _rl_last_c_pos; + cpos_adjusted = 0; update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum, VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin); + /* update_line potentially changes _rl_last_c_pos, but doesn't + take invisible characters into account, since _rl_last_c_pos + is an absolute cursor position in a multibyte locale. See + if compensating here is the right thing, or if we have to + change update_line itself. There is one case in which + update_line adjusts _rl_last_c_pos itself (so it can pass + _rl_move_cursor_relative accurate values); it communicates + this back by setting cpos_adjusted */ + if (linenum == 0 && (MB_CUR_MAX > 1 && rl_byte_oriented == 0) && + cpos_adjusted == 0 && + _rl_last_c_pos != o_cpos && + _rl_last_c_pos > wrap_offset && + o_cpos < prompt_last_invisible) + _rl_last_c_pos -= wrap_offset; + /* If this is the line with the prompt, we might need to compensate for invisible characters in the new line. Do this only if there is not more than one new line (which @@ -814,7 +921,10 @@ rl_redisplay () (wrap_offset > visible_wrap_offset) && (_rl_last_c_pos < visible_first_line_len)) { - nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos; + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + nleft = _rl_screenwidth - _rl_last_c_pos; + else + nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos; if (nleft) _rl_clear_to_eol (nleft); } @@ -850,7 +960,7 @@ rl_redisplay () the physical cursor position on the screen stays the same, but the buffer position needs to be adjusted to account for invisible characters. */ - if (cursor_linenum == 0 && wrap_offset) + if ((MB_CUR_MAX == 1 || rl_byte_oriented) && cursor_linenum == 0 && wrap_offset) _rl_last_c_pos += wrap_offset; } @@ -871,7 +981,7 @@ rl_redisplay () #endif _rl_output_some_chars (local_prompt, nleft); if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - _rl_last_c_pos = _rl_col_width(local_prompt, 0, nleft); + _rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft) - wrap_offset; else _rl_last_c_pos = nleft; } @@ -883,18 +993,31 @@ rl_redisplay () start of the line and the cursor position. */ nleft = c_pos - pos; + /* NLEFT is now a number of characters in a buffer. When in a + multibyte locale, however, _rl_last_c_pos is an absolute cursor + position that doesn't take invisible characters in the prompt + into account. We use a fudge factor to compensate. */ + /* Since _rl_backspace() doesn't know about invisible characters in the prompt, and there's no good way to tell it, we compensate for those characters here and call _rl_backspace() directly. */ if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos) { - _rl_backspace (_rl_last_c_pos - nleft); if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - _rl_last_c_pos = _rl_col_width (&visible_line[pos], 0, nleft); + tx = _rl_col_width (&visible_line[pos], 0, nleft) - visible_wrap_offset; else - _rl_last_c_pos = nleft; + tx = nleft; + if (_rl_last_c_pos > tx) + { + _rl_backspace (_rl_last_c_pos - tx); /* XXX */ + _rl_last_c_pos = tx; + } } + /* We need to note that in a multibyte locale we are dealing with + _rl_last_c_pos as an absolute cursor position, but moving to a + point specified by a buffer position (NLEFT) that doesn't take + invisible characters into account. */ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) _rl_move_cursor_relative (nleft, &invisible_line[pos]); else if (nleft != _rl_last_c_pos) @@ -1053,7 +1176,10 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) the exact cursor position and cut-and-paste with certain terminal emulators. In this calculation, TEMP is the physical screen position of the cursor. */ - temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset); + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + temp = _rl_last_c_pos; + else + temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset); if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode && _rl_last_v_pos == current_line - 1) { @@ -1073,12 +1199,12 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) memset (&ps, 0, sizeof (mbstate_t)); ret = mbrtowc (&wc, new, MB_CUR_MAX, &ps); - if (ret == (size_t)-1 || ret == (size_t)-2) + if (MB_INVALIDCH (ret)) { tempwidth = 1; ret = 1; } - else if (ret == 0) + else if (MB_NULLWCH (ret)) tempwidth = 0; else tempwidth = wcwidth (wc); @@ -1095,7 +1221,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) ret = mbrtowc (&wc, old, MB_CUR_MAX, &ps); if (ret != 0 && bytes != 0) { - if (ret == (size_t)-1 || ret == (size_t)-2) + if (MB_INVALIDCH (ret)) memmove (old+bytes, old+1, strlen (old+1)); else memmove (old+bytes, old+ret, strlen (old+ret)); @@ -1118,7 +1244,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) putc (new[0], rl_outstream); else putc (' ', rl_outstream); - _rl_last_c_pos = 1; /* XXX */ + _rl_last_c_pos = 1; _rl_last_v_pos++; if (old[0] && new[0]) old[0] = new[0]; @@ -1130,18 +1256,37 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) #if defined (HANDLE_MULTIBYTE) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) { - memset (&ps_new, 0, sizeof(mbstate_t)); - memset (&ps_old, 0, sizeof(mbstate_t)); - - new_offset = old_offset = 0; - for (ofd = old, nfd = new; - (ofd - old < omax) && *ofd && - _rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); ) + /* See if the old line is a subset of the new line, so that the + only change is adding characters. */ + temp = (omax < nmax) ? omax : nmax; + if (memcmp (old, new, temp) == 0) { - old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY); - new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY); - ofd = old + old_offset; - nfd = new + new_offset; + ofd = old + temp; + nfd = new + temp; + } + else + { + memset (&ps_new, 0, sizeof(mbstate_t)); + memset (&ps_old, 0, sizeof(mbstate_t)); + + if (omax == nmax && STREQN (new, old, omax)) + { + ofd = old + omax; + nfd = new + nmax; + } + else + { + new_offset = old_offset = 0; + for (ofd = old, nfd = new; + (ofd - old < omax) && *ofd && + _rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); ) + { + old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY); + new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY); + ofd = old + old_offset; + nfd = new + new_offset; + } + } } } else @@ -1173,8 +1318,11 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) memset (&ps_old, 0, sizeof (mbstate_t)); memset (&ps_new, 0, sizeof (mbstate_t)); +#if 0 + /* On advice from jir@yamato.ibm.com */ _rl_adjust_point (old, ols - old, &ps_old); _rl_adjust_point (new, nls - new, &ps_new); +#endif if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0) break; @@ -1237,7 +1385,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) if (_rl_last_v_pos != current_line) { _rl_move_vert (current_line); - if (current_line == 0 && visible_wrap_offset) + if ((MB_CUR_MAX == 1 || rl_byte_oriented) && current_line == 0 && visible_wrap_offset) _rl_last_c_pos += visible_wrap_offset; } @@ -1266,7 +1414,12 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) #endif _rl_output_some_chars (local_prompt, lendiff); if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff); + { + /* We take wrap_offset into account here so we can pass correct + information to _rl_move_cursor_relative. */ + _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff) - wrap_offset; + cpos_adjusted = 1; + } else _rl_last_c_pos = lendiff; } @@ -1328,7 +1481,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) insert_some_chars (nfd, lendiff, col_lendiff); _rl_last_c_pos += col_lendiff; } - else if (*ols == 0) + else if ((MB_CUR_MAX == 1 || rl_byte_oriented != 0) && *ols == 0 && lendiff > 0) { /* At the end of a line the characters do not have to be "inserted". They can just be placed on the screen. */ @@ -1351,7 +1504,11 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) if ((temp - lendiff) > 0) { _rl_output_some_chars (nfd + lendiff, temp - lendiff); -#if 0 +#if 1 + /* XXX -- this bears closer inspection. Fixes a redisplay bug + reported against bash-3.0-alpha by Andreas Schwab involving + multibyte characters and prompt strings with invisible + characters, but was previously disabled. */ _rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-col_lendiff); #else _rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-lendiff); @@ -1363,6 +1520,10 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) /* cannot insert chars, write to EOL */ _rl_output_some_chars (nfd, temp); _rl_last_c_pos += col_temp; + /* If we're in a multibyte locale and were before the last invisible + char in the current line (which implies we just output some invisible + characters) we need to adjust _rl_last_c_pos, since it represents + a physical character position. */ } } else /* Delete characters from line. */ @@ -1394,7 +1555,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) if (temp > 0) { _rl_output_some_chars (nfd, temp); - _rl_last_c_pos += col_temp; + _rl_last_c_pos += col_temp; /* XXX */ } lendiff = (oe - old) - (ne - new); if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) @@ -1430,12 +1591,13 @@ rl_on_new_line () /* Tell the update routines that we have moved onto a new line with the prompt already displayed. Code originally from the version of readline - distributed with CLISP. */ + distributed with CLISP. rl_expand_prompt must have already been called + (explicitly or implicitly). This still doesn't work exactly right. */ int rl_on_new_line_with_prompt () { int prompt_size, i, l, real_screenwidth, newlines; - char *prompt_last_line; + char *prompt_last_line, *lprompt; /* Initialize visible_line and invisible_line to ensure that they can hold the already-displayed prompt. */ @@ -1444,8 +1606,9 @@ rl_on_new_line_with_prompt () /* Make sure the line structures hold the already-displayed prompt for redisplay. */ - strcpy (visible_line, rl_prompt); - strcpy (invisible_line, rl_prompt); + lprompt = local_prompt ? local_prompt : rl_prompt; + strcpy (visible_line, lprompt); + strcpy (invisible_line, lprompt); /* If the prompt contains newlines, take the last tail. */ prompt_last_line = strrchr (rl_prompt, '\n'); @@ -1454,7 +1617,7 @@ rl_on_new_line_with_prompt () l = strlen (prompt_last_line); if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l); + _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l); /* XXX */ else _rl_last_c_pos = l; @@ -1480,6 +1643,8 @@ rl_on_new_line_with_prompt () vis_lbreaks[newlines] = l; visible_wrap_offset = 0; + rl_display_prompt = rl_prompt; /* XXX - make sure it's set */ + return 0; } @@ -1501,6 +1666,8 @@ rl_forced_update_display () } /* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices. + (Well, when we don't have multibyte characters, _rl_last_c_pos is a + buffer index.) DATA is the contents of the screen line of interest; i.e., where the movement is being done. */ void @@ -1509,28 +1676,40 @@ _rl_move_cursor_relative (new, data) const char *data; { register int i; + int woff; /* number of invisible chars on current line */ + int cpos, dpos; /* current and desired cursor positions */ - /* If we don't have to do anything, then return. */ + woff = W_OFFSET (_rl_last_v_pos, wrap_offset); + cpos = _rl_last_c_pos; #if defined (HANDLE_MULTIBYTE) /* If we have multibyte characters, NEW is indexed by the buffer point in a multibyte string, but _rl_last_c_pos is the display position. In this case, NEW's display position is not obvious and must be - calculated. */ - if (MB_CUR_MAX == 1 || rl_byte_oriented) + calculated. We need to account for invisible characters in this line, + as long as we are past them and they are counted by _rl_col_width. */ + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) { - if (_rl_last_c_pos == new) - return; + dpos = _rl_col_width (data, 0, new); + if (dpos > woff) + dpos -= woff; } - else if (_rl_last_c_pos == _rl_col_width (data, 0, new)) - return; -#else - if (_rl_last_c_pos == new) return; + else #endif + dpos = new; + + /* If we don't have to do anything, then return. */ + if (cpos == dpos) + return; /* It may be faster to output a CR, and then move forwards instead of moving backwards. */ /* i == current physical cursor position. */ - i = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset); +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + i = _rl_last_c_pos; + else +#endif + i = _rl_last_c_pos - woff; if (new == 0 || CR_FASTER (new, _rl_last_c_pos) || (_rl_term_autowrap && i == _rl_screenwidth)) { @@ -1539,10 +1718,10 @@ _rl_move_cursor_relative (new, data) #else tputs (_rl_term_cr, 1, _rl_output_character_function); #endif /* !__MSDOS__ */ - _rl_last_c_pos = 0; + cpos = _rl_last_c_pos = 0; } - if (_rl_last_c_pos < new) + if (cpos < dpos) { /* Move the cursor forward. We do it by printing the command to move the cursor forward if there is one, else print that @@ -1556,31 +1735,11 @@ _rl_move_cursor_relative (new, data) #if defined (HACK_TERMCAP_MOTION) if (_rl_term_forward_char) { - if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - { - int width; - width = _rl_col_width (data, _rl_last_c_pos, new); - for (i = 0; i < width; i++) - tputs (_rl_term_forward_char, 1, _rl_output_character_function); - } - else - { - for (i = _rl_last_c_pos; i < new; i++) - tputs (_rl_term_forward_char, 1, _rl_output_character_function); - } - } - else if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - { - tputs (_rl_term_cr, 1, _rl_output_character_function); - for (i = 0; i < new; i++) - putc (data[i], rl_outstream); + for (i = cpos; i < dpos; i++) + tputs (_rl_term_forward_char, 1, _rl_output_character_function); } else - for (i = _rl_last_c_pos; i < new; i++) - putc (data[i], rl_outstream); - -#else /* !HACK_TERMCAP_MOTION */ - +#endif /* HACK_TERMCAP_MOTION */ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) { tputs (_rl_term_cr, 1, _rl_output_character_function); @@ -1588,32 +1747,20 @@ _rl_move_cursor_relative (new, data) putc (data[i], rl_outstream); } else - for (i = _rl_last_c_pos; i < new; i++) + for (i = cpos; i < new; i++) putc (data[i], rl_outstream); - -#endif /* !HACK_TERMCAP_MOTION */ - } + #if defined (HANDLE_MULTIBYTE) /* NEW points to the buffer point, but _rl_last_c_pos is the display point. The byte length of the string is probably bigger than the column width of the string, which means that if NEW == _rl_last_c_pos, then NEW's display point is less than _rl_last_c_pos. */ - else if (_rl_last_c_pos >= new) -#else - else if (_rl_last_c_pos > new) #endif - { - if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - _rl_backspace (_rl_last_c_pos - _rl_col_width (data, 0, new)); - else - _rl_backspace (_rl_last_c_pos - new); - } + else if (cpos > dpos) + _rl_backspace (cpos - dpos); - if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - _rl_last_c_pos = _rl_col_width (data, 0, new); - else - _rl_last_c_pos = new; + _rl_last_c_pos = dpos; } /* PWP: move the cursor up or down. */ @@ -1711,9 +1858,9 @@ rl_character_len (c, pos) return ((ISPRINT (uc)) ? 1 : 2); } - /* How to print things in the "echo-area". The prompt is treated as a mini-modeline. */ +static int msg_saved_prompt = 0; #if defined (USE_VARARGS) int @@ -1744,8 +1891,19 @@ rl_message (va_alist) #endif va_end (args); + if (saved_local_prompt == 0) + { + rl_save_prompt (); + msg_saved_prompt = 1; + } rl_display_prompt = msg_buf; + local_prompt = expand_prompt (msg_buf, &prompt_visible_length, + &prompt_last_invisible, + &prompt_invis_chars_first_line, + &prompt_physical_chars); + local_prompt_prefix = (char *)NULL; (*rl_redisplay_function) (); + return 0; } #else /* !USE_VARARGS */ @@ -1755,8 +1913,20 @@ rl_message (format, arg1, arg2) { sprintf (msg_buf, format, arg1, arg2); msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */ + rl_display_prompt = msg_buf; + if (saved_local_prompt == 0) + { + rl_save_prompt (); + msg_saved_prompt = 1; + } + local_prompt = expand_prompt (msg_buf, &prompt_visible_length, + &prompt_last_invisible, + &prompt_invis_chars_first_line, + &prompt_physical_chars); + local_prompt_prefix = (char *)NULL; (*rl_redisplay_function) (); + return 0; } #endif /* !USE_VARARGS */ @@ -1766,6 +1936,11 @@ int rl_clear_message () { rl_display_prompt = rl_prompt; + if (msg_saved_prompt) + { + rl_restore_prompt (); + msg_saved_prompt = 0; + } (*rl_redisplay_function) (); return 0; } @@ -1780,21 +1955,20 @@ rl_reset_line_state () return 0; } -static char *saved_local_prompt; -static char *saved_local_prefix; -static int saved_last_invisible; -static int saved_visible_length; - void rl_save_prompt () { saved_local_prompt = local_prompt; saved_local_prefix = local_prompt_prefix; + saved_prefix_length = prompt_prefix_length; saved_last_invisible = prompt_last_invisible; saved_visible_length = prompt_visible_length; + saved_invis_chars_first_line = prompt_invis_chars_first_line; + saved_physical_chars = prompt_physical_chars; local_prompt = local_prompt_prefix = (char *)0; - prompt_last_invisible = prompt_visible_length = 0; + prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0; + prompt_invis_chars_first_line = prompt_physical_chars = 0; } void @@ -1805,8 +1979,16 @@ rl_restore_prompt () local_prompt = saved_local_prompt; local_prompt_prefix = saved_local_prefix; + prompt_prefix_length = saved_prefix_length; prompt_last_invisible = saved_last_invisible; prompt_visible_length = saved_visible_length; + prompt_invis_chars_first_line = saved_invis_chars_first_line; + prompt_physical_chars = saved_physical_chars; + + /* can test saved_local_prompt to see if prompt info has been saved. */ + saved_local_prompt = saved_local_prefix = (char *)0; + saved_last_invisible = saved_visible_length = saved_prefix_length = 0; + saved_invis_chars_first_line = saved_physical_chars = 0; } char * @@ -1814,11 +1996,15 @@ _rl_make_prompt_for_search (pchar) int pchar; { int len; - char *pmt; + char *pmt, *p; rl_save_prompt (); - if (saved_local_prompt == 0) + /* We've saved the prompt, and can do anything with the various prompt + strings we need before they're restored. We want the unexpanded + portion of the prompt string after any final newline. */ + p = rl_prompt ? strrchr (rl_prompt, '\n') : 0; + if (p == 0) { len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0; pmt = (char *)xmalloc (len + 2); @@ -1829,16 +2015,17 @@ _rl_make_prompt_for_search (pchar) } else { - len = *saved_local_prompt ? strlen (saved_local_prompt) : 0; + p++; + len = strlen (p); pmt = (char *)xmalloc (len + 2); if (len) - strcpy (pmt, saved_local_prompt); + strcpy (pmt, p); pmt[len] = pchar; pmt[len+1] = '\0'; - local_prompt = savestring (pmt); - prompt_last_invisible = saved_last_invisible; - prompt_visible_length = saved_visible_length + 1; - } + } + + /* will be overwritten by expand_prompt, called from rl_message */ + prompt_physical_chars = saved_physical_chars + 1; return pmt; } @@ -1907,9 +2094,9 @@ insert_some_chars (string, count, col) char *string; int count, col; { -#if defined(__MSDOS__) || defined(__MINGW32__) +#if defined (__MSDOS__) || defined (__MINGW32__) _rl_output_some_chars (string, count); -#else /* !__MSDOS__ && !__MINGW32__ */ +#else /* DEBUGGING */ if (MB_CUR_MAX == 1 || rl_byte_oriented) if (count != col) @@ -1948,7 +2135,7 @@ insert_some_chars (string, count, col) if (_rl_term_ei && *_rl_term_ei) tputs (_rl_term_ei, 1, _rl_output_character_function); } -#endif /* !__MSDOS__ */ +#endif /* __MSDOS__ || __MINGW32__ */ } /* Delete COUNT characters from the display line. */ @@ -1959,7 +2146,7 @@ delete_chars (count) if (count > _rl_screenwidth) /* XXX */ return; -#if !defined(__MSDOS__) && !defined(__MINGW32__) +#if !defined (__MSDOS__) && !defined (__MINGW32__) if (_rl_term_DC && *_rl_term_DC) { char *buffer; @@ -2028,32 +2215,22 @@ static void redraw_prompt (t) char *t; { - char *oldp, *oldl, *oldlprefix; - int oldlen, oldlast, oldplen, oldninvis; + char *oldp; - /* Geez, I should make this a struct. */ oldp = rl_display_prompt; - oldl = local_prompt; - oldlprefix = local_prompt_prefix; - oldlen = prompt_visible_length; - oldplen = prompt_prefix_length; - oldlast = prompt_last_invisible; - oldninvis = prompt_invis_chars_first_line; + rl_save_prompt (); rl_display_prompt = t; local_prompt = expand_prompt (t, &prompt_visible_length, &prompt_last_invisible, - &prompt_invis_chars_first_line); + &prompt_invis_chars_first_line, + &prompt_physical_chars); local_prompt_prefix = (char *)NULL; + rl_forced_update_display (); rl_display_prompt = oldp; - local_prompt = oldl; - local_prompt_prefix = oldlprefix; - prompt_visible_length = oldlen; - prompt_prefix_length = oldplen; - prompt_last_invisible = oldlast; - prompt_invis_chars_first_line = oldninvis; + rl_restore_prompt(); } /* Redisplay the current line after a SIGWINCH is received. */ @@ -2163,7 +2340,7 @@ _rl_col_width (str, start, end) while (point < start) { tmp = mbrlen (str + point, max, &ps); - if ((size_t)tmp == (size_t)-1 || (size_t)tmp == (size_t)-2) + if (MB_INVALIDCH ((size_t)tmp)) { /* In this case, the bytes are invalid or too short to compose a multibyte character, so we assume that the first byte represents @@ -2175,8 +2352,8 @@ _rl_col_width (str, start, end) effect of mbstate is undefined. */ memset (&ps, 0, sizeof (mbstate_t)); } - else if (tmp == 0) - break; /* Found '\0' */ + else if (MB_NULLWCH (tmp)) + break; /* Found '\0' */ else { point += tmp; @@ -2192,7 +2369,7 @@ _rl_col_width (str, start, end) while (point < end) { tmp = mbrtowc (&wc, str + point, max, &ps); - if ((size_t)tmp == (size_t)-1 || (size_t)tmp == (size_t)-2) + if (MB_INVALIDCH ((size_t)tmp)) { /* In this case, the bytes are invalid or too short to compose a multibyte character, so we assume that the first byte represents @@ -2207,8 +2384,8 @@ _rl_col_width (str, start, end) effect of mbstate is undefined. */ memset (&ps, 0, sizeof (mbstate_t)); } - else if (tmp == 0) - break; /* Found '\0' */ + else if (MB_NULLWCH (tmp)) + break; /* Found '\0' */ else { point += tmp; diff --git a/readline/doc/ChangeLog.gdb b/readline/doc/ChangeLog.gdb index 1253d9c..14d32f6 100644 --- a/readline/doc/ChangeLog.gdb +++ b/readline/doc/ChangeLog.gdb @@ -1,3 +1,7 @@ +2006-04-24 Daniel Jacobowitz <dan@codesourcery.com> + + Imported readline 5.1, and upstream patches 001-004. + 2003-09-14 Andrew Cagney <cagney@redhat.com> * history.0: Delete generated file. diff --git a/readline/doc/Makefile.in b/readline/doc/Makefile.in index 8a85ae1..692a4e8 100644 --- a/readline/doc/Makefile.in +++ b/readline/doc/Makefile.in @@ -1,7 +1,7 @@ # This makefile for Readline library documentation is in -*- text -*- mode. # Emacs likes it that way. -# Copyright (C) 1996 Free Software Foundation, Inc. +# Copyright (C) 1996-2004 Free Software Foundation, Inc. # 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 @@ -52,14 +52,18 @@ TEXI2DVI = $(srcdir)/texi2dvi TEXI2HTML = $(srcdir)/texi2html QUIETPS = #set this to -q to shut up dvips PAPERSIZE = letter -PSDPI = 300 # I don't have any 600-dpi printers +PSDPI = 600 DVIPS = dvips -D ${PSDPI} $(QUIETPS) -t ${PAPERSIZE} -o $@ # tricky -RLSRC = $(srcdir)/rlman.texinfo $(srcdir)/rluser.texinfo \ - $(srcdir)/rltech.texinfo $(srcdir)/manvers.texinfo \ - $(srcdir)/rluserman.texinfo -HISTSRC = $(srcdir)/hist.texinfo $(srcdir)/hsuser.texinfo \ - $(srcdir)/hstech.texinfo $(srcdir)/manvers.texinfo +# These tools might not be available; they're not required +DVIPDF = dvipdfm -o $@ -p ${PAPERSIZE} +PSPDF = gs -sPAPERSIZE=${PAPERSIZE} -sDEVICE=pdfwrite -dNOPAUSE -dBATCH -sOutputFile=$@ + +RLSRC = $(srcdir)/rlman.texi $(srcdir)/rluser.texi \ + $(srcdir)/rltech.texi $(srcdir)/version.texi \ + $(srcdir)/rluserman.texi +HISTSRC = $(srcdir)/history.texi $(srcdir)/hsuser.texi \ + $(srcdir)/hstech.texi $(srcdir)/version.texi # This should be a program that converts troff to an ascii-readable format NROFF = groff -Tascii @@ -72,39 +76,54 @@ INFOOBJ = readline.info history.info rluserman.info PSOBJ = readline.ps history.ps rluserman.ps readline_3.ps history_3.ps HTMLOBJ = readline.html history.html rluserman.html TEXTOBJ = readline.0 history.0 +PDFOBJ = readline.pdf history.pdf rluserman.pdf -INTERMEDIATE_OBJ = rlman.dvi hist.dvi rluserman.dvi +INTERMEDIATE_OBJ = rlman.dvi DIST_DOCS = $(DVIOBJ) $(PSOBJ) $(HTMLOBJ) $(INFOOBJ) $(TEXTOBJ) -.SUFFIXES: .0 .3 .ps .txt .dvi +.SUFFIXES: .0 .3 .ps .txt .dvi .html .pdf .3.0: $(RM) $@ -${NROFF} -man $< > $@ +.ps.pdf: + $(RM) $@ + -${PSPDF} $< + +.dvi.pdf: + $(RM) $@ + -${DVIPDF} $< + all: info dvi html ps text nodvi: info html text +info: $(INFOOBJ) +dvi: $(DVIOBJ) +ps: $(PSOBJ) +html: $(HTMLOBJ) +text: $(TEXTOBJ) +pdf: $(PDFOBJ) + readline.dvi: $(RLSRC) - TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/rlman.texinfo + TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/rlman.texi mv rlman.dvi readline.dvi readline.info: $(RLSRC) - $(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/rlman.texinfo + $(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/rlman.texi rluserman.dvi: $(RLSRC) - TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/rluserman.texinfo + TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/rluserman.texi rluserman.info: $(RLSRC) - $(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/rluserman.texinfo + $(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/rluserman.texi history.dvi: ${HISTSRC} - TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/hist.texinfo - mv hist.dvi history.dvi + TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/history.texi history.info: ${HISTSRC} - $(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/hist.texinfo + $(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/history.texi readline.ps: readline.dvi $(RM) $@ @@ -122,22 +141,15 @@ history.ps: history.dvi # This leaves readline.html and rlman.html -- rlman.html is for www.gnu.org # readline.html: ${RLSRC} - $(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/rlman.texinfo + $(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/rlman.texi sed -e 's:rlman.html:readline.html:g' rlman.html > readline.html + $(RM) rlman.html rluserman.html: ${RLSRC} - $(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/rluserman.texinfo + $(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/rluserman.texi history.html: ${HISTSRC} - $(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/hist.texinfo - sed -e 's:hist.html:history.html:g' hist.html > history.html - $(RM) hist.html - -info: $(INFOOBJ) -dvi: $(DVIOBJ) -ps: $(PSOBJ) -html: $(HTMLOBJ) -text: $(TEXTOBJ) + $(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/history.texi readline.0: readline.3 @@ -151,9 +163,14 @@ history_3.ps: history.3 ${RM} $@ ${GROFF} -man < $(srcdir)/history.3 > $@ +readline.pdf: readline.dvi +history.pdf: history.dvi +rluserman.pdf: rluserman.dvi + clean: - $(RM) *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps *.pgs \ - *.fns *.kys *.tps *.vrs *.bt *.bts *.o core *.core + $(RM) *.aux *.bak *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps \ + *.pgs *.bt *.bts *.rw *.rws *.fns *.kys *.tps *.vrs *.o \ + core *.core mostlyclean: clean @@ -169,6 +186,7 @@ maybe-clean: maintainer-clean: clean $(RM) $(DIST_DOCS) $(RM) $(INTERMEDIATE_OBJ) + $(RM) $(PDFOBJ) $(RM) Makefile installdirs: $(topdir)/support/mkdirs diff --git a/readline/doc/hist.texinfo b/readline/doc/hist.texinfo deleted file mode 100644 index 63ceb16..0000000 --- a/readline/doc/hist.texinfo +++ /dev/null @@ -1,110 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@c %**start of header (This is for running Texinfo on a region.) -@setfilename history.info -@settitle GNU History Library -@c %**end of header (This is for running Texinfo on a region.) - -@setchapternewpage odd - -@include manvers.texinfo - -@ifinfo -@dircategory Libraries -@direntry -* History: (history). The GNU history library API -@end direntry - -This document describes the GNU History library, a programming tool that -provides a consistent user interface for recalling lines of previously -typed input. - -Copyright (C) 1988-2002 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -pare preserved on all copies. - -@ignore -Permission is granted to process this file through TeX and print the -results, provided the printed document carries copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). -@end ignore - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the entire -resulting derived work is distributed under the terms of a permission -notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that this permission notice may be stated in a translation approved -by the Free Software Foundation. -@end ifinfo - -@titlepage -@title GNU History Library -@subtitle Edition @value{EDITION}, for @code{History Library} Version @value{VERSION}. -@subtitle @value{UPDATE-MONTH} -@author Brian Fox, Free Software Foundation -@author Chet Ramey, Case Western Reserve University - -@page -This document describes the GNU History library, a programming tool that -provides a consistent user interface for recalling lines of previously -typed input. - -Published by the Free Software Foundation @* -59 Temple Place, Suite 330, @* -Boston, MA 02111 USA - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the entire -resulting derived work is distributed under the terms of a permission -notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that this permission notice may be stated in a translation approved -by the Free Software Foundation. - -@vskip 0pt plus 1filll -Copyright @copyright{} 1988-2002 Free Software Foundation, Inc. -@end titlepage - -@ifinfo -@node Top -@top GNU History Library - -This document describes the GNU History library, a programming tool that -provides a consistent user interface for recalling lines of previously -typed input. - -@menu -* Using History Interactively:: GNU History User's Manual. -* Programming with GNU History:: GNU History Programmer's Manual. -* Concept Index:: Index of concepts described in this manual. -* Function and Variable Index:: Index of externally visible functions - and variables. -@end menu -@end ifinfo - -@syncodeindex fn vr - -@include hsuser.texinfo -@include hstech.texinfo - -@node Concept Index -@appendix Concept Index -@printindex cp - -@node Function and Variable Index -@appendix Function and Variable Index -@printindex vr - -@contents -@bye diff --git a/readline/doc/history.3 b/readline/doc/history.3 index ed0cb9f..3ade839 100644 --- a/readline/doc/history.3 +++ b/readline/doc/history.3 @@ -6,9 +6,9 @@ .\" Case Western Reserve University .\" chet@ins.CWRU.Edu .\" -.\" Last Change: Thu Jan 31 16:08:07 EST 2002 +.\" Last Change: Thu Jul 31 08:46:08 EDT 2003 .\" -.TH HISTORY 3 "2002 January 31" "GNU History 4.3" +.TH HISTORY 3 "2003 July 31" "GNU History 5.0" .\" .\" File Name macro. This used to be `.PN', for Path Name, .\" but Sun doesn't seem to like that very much. @@ -249,6 +249,10 @@ or `\fB:&\fP'. If used with `\fB:s\fP', any delimiter can be used in place of /, and the final delimiter is optional if it is the last character of the event line. +An \fBa\fP may be used as a synonym for \fBg\fP. +.TP +.B G +Apply the following `\fBs\fP' modifier once to each word in the event line. .PD .SH "PROGRAMMING WITH HISTORY FUNCTIONS" This section describes how to use the History library in other programs. @@ -292,6 +296,7 @@ declared as follows: .nf typedef struct _hist_entry { char *line; + char *timestamp; histdata_t data; } HIST_ENTRY; .fi @@ -345,14 +350,24 @@ parameters managing the list itself. Place \fIstring\fP at the end of the history list. The associated data field (if any) is set to \fBNULL\fP. +.Fn1 void add_history_time "const char *string" +Change the time stamp associated with the most recent history entry to +\fIstring\fP. + .Fn1 "HIST_ENTRY *" remove_history "int which" Remove history entry at offset \fIwhich\fP from the history. The removed element is returned so you can free the line, data, and containing structure. +.Fn1 "histdata_t" free_history_entry "HIST_ENTRY *histent" +Free the history entry \fIhistent\fP and any history library private +data associated with it. Returns the application-specific data +so the caller can dispose of it. + .Fn3 "HIST_ENTRY *" replace_history_entry "int which" "const char *line" "histdata_t data" Make the history entry at offset \fIwhich\fP have \fIline\fP and \fIdata\fP. -This returns the old entry so you can dispose of the data. In the case +This returns the old entry so the caller can dispose of any +application-specific data. In the case of an invalid \fIwhich\fP, a \fBNULL\fP pointer is returned. .Fn1 void clear_history "void" @@ -394,6 +409,9 @@ Return the history entry at position \fIoffset\fP, starting from If there is no entry there, or if \fIoffset\fP is greater than the history length, return a \fBNULL\fP pointer. +.Fn1 "time_t" history_get_time "HIST_ENTRY *" +Return the time stamp associated with the history entry passed as the argument. + .Fn1 int history_total_bytes "void" Return the number of bytes that the primary history entries are using. This function returns the sum of the lengths of all the lines in the @@ -551,6 +569,11 @@ The number of entries currently stored in the history list. The maximum number of history entries. This must be changed using \fBstifle_history()\fP. +.Vb int history_write_timestamps +If non-zero, timestamps are written to the history file, so they can be +preserved between sessions. The default value is 0, meaning that +timestamps are not saved. + .Vb char history_expansion_char The character that introduces a history event. The default is \fB!\fP. Setting this to 0 inhibits history expansion. diff --git a/readline/doc/history.pdf b/readline/doc/history.pdf Binary files differdeleted file mode 100644 index 2ed10c4..0000000 --- a/readline/doc/history.pdf +++ /dev/null diff --git a/readline/doc/hstech.texinfo b/readline/doc/hstech.texinfo deleted file mode 100644 index 9494446..0000000 --- a/readline/doc/hstech.texinfo +++ /dev/null @@ -1,550 +0,0 @@ -@ignore -This file documents the user interface to the GNU History library. - -Copyright (C) 1988-2002 Free Software Foundation, Inc. -Authored by Brian Fox and Chet Ramey. - -Permission is granted to make and distribute verbatim copies of this manual -provided the copyright notice and this permission notice are preserved on -all copies. - -Permission is granted to process this file through Tex and print the -results, provided the printed document carries copying permission notice -identical to this one except for the removal of this paragraph (this -paragraph not being relevant to the printed manual). - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that the -GNU Copyright statement is available to the distributee, and provided that -the entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. -@end ignore - -@node Programming with GNU History -@chapter Programming with GNU History - -This chapter describes how to interface programs that you write -with the @sc{gnu} History Library. -It should be considered a technical guide. -For information on the interactive use of @sc{gnu} History, @pxref{Using -History Interactively}. - -@menu -* Introduction to History:: What is the GNU History library for? -* History Storage:: How information is stored. -* History Functions:: Functions that you can use. -* History Variables:: Variables that control behaviour. -* History Programming Example:: Example of using the GNU History Library. -@end menu - -@node Introduction to History -@section Introduction to History - -Many programs read input from the user a line at a time. The @sc{gnu} -History library is able to keep track of those lines, associate arbitrary -data with each line, and utilize information from previous lines in -composing new ones. - -The programmer using the History library has available functions -for remembering lines on a history list, associating arbitrary data -with a line, removing lines from the list, searching through the list -for a line containing an arbitrary text string, and referencing any line -in the list directly. In addition, a history @dfn{expansion} function -is available which provides for a consistent user interface across -different programs. - -The user using programs written with the History library has the -benefit of a consistent user interface with a set of well-known -commands for manipulating the text of previous lines and using that text -in new commands. The basic history manipulation commands are similar to -the history substitution provided by @code{csh}. - -If the programmer desires, he can use the Readline library, which -includes some history manipulation by default, and has the added -advantage of command line editing. - -Before declaring any functions using any functionality the History -library provides in other code, an application writer should include -the file @code{<readline/history.h>} in any file that uses the -History library's features. It supplies extern declarations for all -of the library's public functions and variables, and declares all of -the public data structures. - -@node History Storage -@section History Storage - -The history list is an array of history entries. A history entry is -declared as follows: - -@example -typedef void *histdata_t; - -typedef struct _hist_entry @{ - char *line; - histdata_t data; -@} HIST_ENTRY; -@end example - -The history list itself might therefore be declared as - -@example -HIST_ENTRY **the_history_list; -@end example - -The state of the History library is encapsulated into a single structure: - -@example -/* - * A structure used to pass around the current state of the history. - */ -typedef struct _hist_state @{ - HIST_ENTRY **entries; /* Pointer to the entries themselves. */ - int offset; /* The location pointer within this array. */ - int length; /* Number of elements within this array. */ - int size; /* Number of slots allocated to this array. */ - int flags; -@} HISTORY_STATE; -@end example - -If the flags member includes @code{HS_STIFLED}, the history has been -stifled. - -@node History Functions -@section History Functions - -This section describes the calling sequence for the various functions -exported by the @sc{gnu} History library. - -@menu -* Initializing History and State Management:: Functions to call when you - want to use history in a - program. -* History List Management:: Functions used to manage the list - of history entries. -* Information About the History List:: Functions returning information about - the history list. -* Moving Around the History List:: Functions used to change the position - in the history list. -* Searching the History List:: Functions to search the history list - for entries containing a string. -* Managing the History File:: Functions that read and write a file - containing the history list. -* History Expansion:: Functions to perform csh-like history - expansion. -@end menu - -@node Initializing History and State Management -@subsection Initializing History and State Management - -This section describes functions used to initialize and manage -the state of the History library when you want to use the history -functions in your program. - -@deftypefun void using_history (void) -Begin a session in which the history functions might be used. This -initializes the interactive variables. -@end deftypefun - -@deftypefun {HISTORY_STATE *} history_get_history_state (void) -Return a structure describing the current state of the input history. -@end deftypefun - -@deftypefun void history_set_history_state (HISTORY_STATE *state) -Set the state of the history list according to @var{state}. -@end deftypefun - -@node History List Management -@subsection History List Management - -These functions manage individual entries on the history list, or set -parameters managing the list itself. - -@deftypefun void add_history (const char *string) -Place @var{string} at the end of the history list. The associated data -field (if any) is set to @code{NULL}. -@end deftypefun - -@deftypefun {HIST_ENTRY *} remove_history (int which) -Remove history entry at offset @var{which} from the history. The -removed element is returned so you can free the line, data, -and containing structure. -@end deftypefun - -@deftypefun {HIST_ENTRY *} replace_history_entry (int which, const char *line, histdata_t data) -Make the history entry at offset @var{which} have @var{line} and @var{data}. -This returns the old entry so you can dispose of the data. In the case -of an invalid @var{which}, a @code{NULL} pointer is returned. -@end deftypefun - -@deftypefun void clear_history (void) -Clear the history list by deleting all the entries. -@end deftypefun - -@deftypefun void stifle_history (int max) -Stifle the history list, remembering only the last @var{max} entries. -@end deftypefun - -@deftypefun int unstifle_history (void) -Stop stifling the history. This returns the previously-set -maximum number of history entries (as set by @code{stifle_history()}). -The value is positive if the history was -stifled, negative if it wasn't. -@end deftypefun - -@deftypefun int history_is_stifled (void) -Returns non-zero if the history is stifled, zero if it is not. -@end deftypefun - -@node Information About the History List -@subsection Information About the History List - -These functions return information about the entire history list or -individual list entries. - -@deftypefun {HIST_ENTRY **} history_list (void) -Return a @code{NULL} terminated array of @code{HIST_ENTRY *} which is the -current input history. Element 0 of this list is the beginning of time. -If there is no history, return @code{NULL}. -@end deftypefun - -@deftypefun int where_history (void) -Returns the offset of the current history element. -@end deftypefun - -@deftypefun {HIST_ENTRY *} current_history (void) -Return the history entry at the current position, as determined by -@code{where_history()}. If there is no entry there, return a @code{NULL} -pointer. -@end deftypefun - -@deftypefun {HIST_ENTRY *} history_get (int offset) -Return the history entry at position @var{offset}, starting from -@code{history_base} (@pxref{History Variables}). -If there is no entry there, or if @var{offset} -is greater than the history length, return a @code{NULL} pointer. -@end deftypefun - -@deftypefun int history_total_bytes (void) -Return the number of bytes that the primary history entries are using. -This function returns the sum of the lengths of all the lines in the -history. -@end deftypefun - -@node Moving Around the History List -@subsection Moving Around the History List - -These functions allow the current index into the history list to be -set or changed. - -@deftypefun int history_set_pos (int pos) -Set the current history offset to @var{pos}, an absolute index -into the list. -Returns 1 on success, 0 if @var{pos} is less than zero or greater -than the number of history entries. -@end deftypefun - -@deftypefun {HIST_ENTRY *} previous_history (void) -Back up the current history offset to the previous history entry, and -return a pointer to that entry. If there is no previous entry, return -a @code{NULL} pointer. -@end deftypefun - -@deftypefun {HIST_ENTRY *} next_history (void) -Move the current history offset forward to the next history entry, and -return the a pointer to that entry. If there is no next entry, return -a @code{NULL} pointer. -@end deftypefun - -@node Searching the History List -@subsection Searching the History List -@cindex History Searching - -These functions allow searching of the history list for entries containing -a specific string. Searching may be performed both forward and backward -from the current history position. The search may be @dfn{anchored}, -meaning that the string must match at the beginning of the history entry. -@cindex anchored search - -@deftypefun int history_search (const char *string, int direction) -Search the history for @var{string}, starting at the current history offset. -If @var{direction} is less than 0, then the search is through -previous entries, otherwise through subsequent entries. -If @var{string} is found, then -the current history index is set to that history entry, and the value -returned is the offset in the line of the entry where -@var{string} was found. Otherwise, nothing is changed, and a -1 is -returned. -@end deftypefun - -@deftypefun int history_search_prefix (const char *string, int direction) -Search the history for @var{string}, starting at the current history -offset. The search is anchored: matching lines must begin with -@var{string}. If @var{direction} is less than 0, then the search is -through previous entries, otherwise through subsequent entries. -If @var{string} is found, then the -current history index is set to that entry, and the return value is 0. -Otherwise, nothing is changed, and a -1 is returned. -@end deftypefun - -@deftypefun int history_search_pos (const char *string, int direction, int pos) -Search for @var{string} in the history list, starting at @var{pos}, an -absolute index into the list. If @var{direction} is negative, the search -proceeds backward from @var{pos}, otherwise forward. Returns the absolute -index of the history element where @var{string} was found, or -1 otherwise. -@end deftypefun - -@node Managing the History File -@subsection Managing the History File - -The History library can read the history from and write it to a file. -This section documents the functions for managing a history file. - -@deftypefun int read_history (const char *filename) -Add the contents of @var{filename} to the history list, a line at a time. -If @var{filename} is @code{NULL}, then read from @file{~/.history}. -Returns 0 if successful, or @code{errno} if not. -@end deftypefun - -@deftypefun int read_history_range (const char *filename, int from, int to) -Read a range of lines from @var{filename}, adding them to the history list. -Start reading at line @var{from} and end at @var{to}. -If @var{from} is zero, start at the beginning. If @var{to} is less than -@var{from}, then read until the end of the file. If @var{filename} is -@code{NULL}, then read from @file{~/.history}. Returns 0 if successful, -or @code{errno} if not. -@end deftypefun - -@deftypefun int write_history (const char *filename) -Write the current history to @var{filename}, overwriting @var{filename} -if necessary. -If @var{filename} is @code{NULL}, then write the history list to -@file{~/.history}. -Returns 0 on success, or @code{errno} on a read or write error. -@end deftypefun - -@deftypefun int append_history (int nelements, const char *filename) -Append the last @var{nelements} of the history list to @var{filename}. -If @var{filename} is @code{NULL}, then append to @file{~/.history}. -Returns 0 on success, or @code{errno} on a read or write error. -@end deftypefun - -@deftypefun int history_truncate_file (const char *filename, int nlines) -Truncate the history file @var{filename}, leaving only the last -@var{nlines} lines. -If @var{filename} is @code{NULL}, then @file{~/.history} is truncated. -Returns 0 on success, or @code{errno} on failure. -@end deftypefun - -@node History Expansion -@subsection History Expansion - -These functions implement history expansion. - -@deftypefun int history_expand (char *string, char **output) -Expand @var{string}, placing the result into @var{output}, a pointer -to a string (@pxref{History Interaction}). Returns: -@table @code -@item 0 -If no expansions took place (or, if the only change in -the text was the removal of escape characters preceding the history expansion -character); -@item 1 -if expansions did take place; -@item -1 -if there was an error in expansion; -@item 2 -if the returned line should be displayed, but not executed, -as with the @code{:p} modifier (@pxref{Modifiers}). -@end table - -If an error ocurred in expansion, then @var{output} contains a descriptive -error message. -@end deftypefun - -@deftypefun {char *} get_history_event (const char *string, int *cindex, int qchar) -Returns the text of the history event beginning at @var{string} + -@var{*cindex}. @var{*cindex} is modified to point to after the event -specifier. At function entry, @var{cindex} points to the index into -@var{string} where the history event specification begins. @var{qchar} -is a character that is allowed to end the event specification in addition -to the ``normal'' terminating characters. -@end deftypefun - -@deftypefun {char **} history_tokenize (const char *string) -Return an array of tokens parsed out of @var{string}, much as the -shell might. The tokens are split on the characters in the -@var{history_word_delimiters} variable, -and shell quoting conventions are obeyed. -@end deftypefun - -@deftypefun {char *} history_arg_extract (int first, int last, const char *string) -Extract a string segment consisting of the @var{first} through @var{last} -arguments present in @var{string}. Arguments are split using -@code{history_tokenize}. -@end deftypefun - -@node History Variables -@section History Variables - -This section describes the externally-visible variables exported by -the @sc{gnu} History Library. - -@deftypevar int history_base -The logical offset of the first entry in the history list. -@end deftypevar - -@deftypevar int history_length -The number of entries currently stored in the history list. -@end deftypevar - -@deftypevar int history_max_entries -The maximum number of history entries. This must be changed using -@code{stifle_history()}. -@end deftypevar - -@deftypevar char history_expansion_char -The character that introduces a history event. The default is @samp{!}. -Setting this to 0 inhibits history expansion. -@end deftypevar - -@deftypevar char history_subst_char -The character that invokes word substitution if found at the start of -a line. The default is @samp{^}. -@end deftypevar - -@deftypevar char history_comment_char -During tokenization, if this character is seen as the first character -of a word, then it and all subsequent characters up to a newline are -ignored, suppressing history expansion for the remainder of the line. -This is disabled by default. -@end deftypevar - -@deftypevar {char *} history_word_delimiters -The characters that separate tokens for @code{history_tokenize()}. -The default value is @code{" \t\n()<>;&|"}. -@end deftypevar - -@deftypevar {char *} history_no_expand_chars -The list of characters which inhibit history expansion if found immediately -following @var{history_expansion_char}. The default is space, tab, newline, -carriage return, and @samp{=}. -@end deftypevar - -@deftypevar {char *} history_search_delimiter_chars -The list of additional characters which can delimit a history search -string, in addition to space, TAB, @samp{:} and @samp{?} in the case of -a substring search. The default is empty. -@end deftypevar - -@deftypevar int history_quotes_inhibit_expansion -If non-zero, single-quoted words are not scanned for the history expansion -character. The default value is 0. -@end deftypevar - -@deftypevar {rl_linebuf_func_t *} history_inhibit_expansion_function -This should be set to the address of a function that takes two arguments: -a @code{char *} (@var{string}) -and an @code{int} index into that string (@var{i}). -It should return a non-zero value if the history expansion starting at -@var{string[i]} should not be performed; zero if the expansion should -be done. -It is intended for use by applications like Bash that use the history -expansion character for additional purposes. -By default, this variable is set to @code{NULL}. -@end deftypevar - -@node History Programming Example -@section History Programming Example - -The following program demonstrates simple use of the @sc{gnu} History Library. - -@smallexample -#include <stdio.h> -#include <readline/history.h> - -main (argc, argv) - int argc; - char **argv; -@{ - char line[1024], *t; - int len, done = 0; - - line[0] = 0; - - using_history (); - while (!done) - @{ - printf ("history$ "); - fflush (stdout); - t = fgets (line, sizeof (line) - 1, stdin); - if (t && *t) - @{ - len = strlen (t); - if (t[len - 1] == '\n') - t[len - 1] = '\0'; - @} - - if (!t) - strcpy (line, "quit"); - - if (line[0]) - @{ - char *expansion; - int result; - - result = history_expand (line, &expansion); - if (result) - fprintf (stderr, "%s\n", expansion); - - if (result < 0 || result == 2) - @{ - free (expansion); - continue; - @} - - add_history (expansion); - strncpy (line, expansion, sizeof (line) - 1); - free (expansion); - @} - - if (strcmp (line, "quit") == 0) - done = 1; - else if (strcmp (line, "save") == 0) - write_history ("history_file"); - else if (strcmp (line, "read") == 0) - read_history ("history_file"); - else if (strcmp (line, "list") == 0) - @{ - register HIST_ENTRY **the_list; - register int i; - - the_list = history_list (); - if (the_list) - for (i = 0; the_list[i]; i++) - printf ("%d: %s\n", i + history_base, the_list[i]->line); - @} - else if (strncmp (line, "delete", 6) == 0) - @{ - int which; - if ((sscanf (line + 6, "%d", &which)) == 1) - @{ - HIST_ENTRY *entry = remove_history (which); - if (!entry) - fprintf (stderr, "No such entry %d\n", which); - else - @{ - free (entry->line); - free (entry); - @} - @} - else - @{ - fprintf (stderr, "non-numeric arg given to `delete'\n"); - @} - @} - @} -@} -@end smallexample diff --git a/readline/doc/hsuser.texinfo b/readline/doc/hsuser.texinfo deleted file mode 100644 index 418bfa8..0000000 --- a/readline/doc/hsuser.texinfo +++ /dev/null @@ -1,437 +0,0 @@ -@ignore -This file documents the user interface to the GNU History library. - -Copyright (C) 1988-2002 Free Software Foundation, Inc. -Authored by Brian Fox and Chet Ramey. - -Permission is granted to make and distribute verbatim copies of this manual -provided the copyright notice and this permission notice are preserved on -all copies. - -Permission is granted to process this file through Tex and print the -results, provided the printed document carries copying permission notice -identical to this one except for the removal of this paragraph (this -paragraph not being relevant to the printed manual). - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that the -GNU Copyright statement is available to the distributee, and provided that -the entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. -@end ignore - -@node Using History Interactively -@chapter Using History Interactively - -@ifclear BashFeatures -@defcodeindex bt -@end ifclear - -@ifset BashFeatures -This chapter describes how to use the @sc{gnu} History Library -interactively, from a user's standpoint. -It should be considered a user's guide. -For information on using the @sc{gnu} History Library in other programs, -see the @sc{gnu} Readline Library Manual. -@end ifset -@ifclear BashFeatures -This chapter describes how to use the @sc{gnu} History Library interactively, -from a user's standpoint. It should be considered a user's guide. For -information on using the @sc{gnu} History Library in your own programs, -@pxref{Programming with GNU History}. -@end ifclear - -@ifset BashFeatures -@menu -* Bash History Facilities:: How Bash lets you manipulate your command - history. -* Bash History Builtins:: The Bash builtin commands that manipulate - the command history. -* History Interaction:: What it feels like using History as a user. -@end menu -@end ifset -@ifclear BashFeatures -@menu -* History Interaction:: What it feels like using History as a user. -@end menu -@end ifclear - -@ifset BashFeatures -@node Bash History Facilities -@section Bash History Facilities -@cindex command history -@cindex history list - -When the @option{-o history} option to the @code{set} builtin -is enabled (@pxref{The Set Builtin}), -the shell provides access to the @dfn{command history}, -the list of commands previously typed. -The value of the @env{HISTSIZE} shell variable is used as the -number of commands to save in a history list. -The text of the last @env{$HISTSIZE} -commands (default 500) is saved. -The shell stores each command in the history list prior to -parameter and variable expansion -but after history expansion is performed, subject to the -values of the shell variables -@env{HISTIGNORE} and @env{HISTCONTROL}. - -When the shell starts up, the history is initialized from the -file named by the @env{HISTFILE} variable (default @file{~/.bash_history}). -The file named by the value of @env{HISTFILE} is truncated, if -necessary, to contain no more than the number of lines specified by -the value of the @env{HISTFILESIZE} variable. -When an interactive shell exits, the last -@env{$HISTSIZE} lines are copied from the history list to the file -named by @env{$HISTFILE}. -If the @code{histappend} shell option is set (@pxref{Bash Builtins}), -the lines are appended to the history file, -otherwise the history file is overwritten. -If @env{HISTFILE} -is unset, or if the history file is unwritable, the history is -not saved. After saving the history, the history file is truncated -to contain no more than @env{$HISTFILESIZE} -lines. If @env{HISTFILESIZE} is not set, no truncation is performed. - -The builtin command @code{fc} may be used to list or edit and re-execute -a portion of the history list. -The @code{history} builtin may be used to display or modify the history -list and manipulate the history file. -When using command-line editing, search commands -are available in each editing mode that provide access to the -history list (@pxref{Commands For History}). - -The shell allows control over which commands are saved on the history -list. The @env{HISTCONTROL} and @env{HISTIGNORE} -variables may be set to cause the shell to save only a subset of the -commands entered. -The @code{cmdhist} -shell option, if enabled, causes the shell to attempt to save each -line of a multi-line command in the same history entry, adding -semicolons where necessary to preserve syntactic correctness. -The @code{lithist} -shell option causes the shell to save the command with embedded newlines -instead of semicolons. -The @code{shopt} builtin is used to set these options. -@xref{Bash Builtins}, for a description of @code{shopt}. - -@node Bash History Builtins -@section Bash History Builtins -@cindex history builtins - -Bash provides two builtin commands which manipulate the -history list and history file. - -@table @code - -@item fc -@btindex fc -@example -@code{fc [-e @var{ename}] [-nlr] [@var{first}] [@var{last}]} -@code{fc -s [@var{pat}=@var{rep}] [@var{command}]} -@end example - -Fix Command. In the first form, a range of commands from @var{first} to -@var{last} is selected from the history list. Both @var{first} and -@var{last} may be specified as a string (to locate the most recent -command beginning with that string) or as a number (an index into the -history list, where a negative number is used as an offset from the -current command number). If @var{last} is not specified it is set to -@var{first}. If @var{first} is not specified it is set to the previous -command for editing and @minus{}16 for listing. If the @option{-l} flag is -given, the commands are listed on standard output. The @option{-n} flag -suppresses the command numbers when listing. The @option{-r} flag -reverses the order of the listing. Otherwise, the editor given by -@var{ename} is invoked on a file containing those commands. If -@var{ename} is not given, the value of the following variable expansion -is used: @code{$@{FCEDIT:-$@{EDITOR:-vi@}@}}. This says to use the -value of the @env{FCEDIT} variable if set, or the value of the -@env{EDITOR} variable if that is set, or @code{vi} if neither is set. -When editing is complete, the edited commands are echoed and executed. - -In the second form, @var{command} is re-executed after each instance -of @var{pat} in the selected command is replaced by @var{rep}. - -A useful alias to use with the @code{fc} command is @code{r='fc -s'}, so -that typing @samp{r cc} runs the last command beginning with @code{cc} -and typing @samp{r} re-executes the last command (@pxref{Aliases}). - -@item history -@btindex history -@example -history [@var{n}] -history -c -history -d @var{offset} -history [-anrw] [@var{filename}] -history -ps @var{arg} -@end example - -With no options, display the history list with line numbers. -Lines prefixed with a @samp{*} have been modified. -An argument of @var{n} lists only the last @var{n} lines. -Options, if supplied, have the following meanings: - -@table @code -@item -c -Clear the history list. This may be combined -with the other options to replace the history list completely. - -@item -d @var{offset} -Delete the history entry at position @var{offset}. -@var{offset} should be specified as it appears when the history is -displayed. - -@item -a -Append the new -history lines (history lines entered since the beginning of the -current Bash session) to the history file. - -@item -n -Append the history lines not already read from the history file -to the current history list. These are lines appended to the history -file since the beginning of the current Bash session. - -@item -r -Read the current history file and append its contents to -the history list. - -@item -w -Write out the current history to the history file. - -@item -p -Perform history substitution on the @var{arg}s and display the result -on the standard output, without storing the results in the history list. - -@item -s -The @var{arg}s are added to the end of -the history list as a single entry. - -@end table - -When any of the @option{-w}, @option{-r}, @option{-a}, or @option{-n} options is -used, if @var{filename} -is given, then it is used as the history file. If not, then -the value of the @env{HISTFILE} variable is used. - -@end table -@end ifset - -@node History Interaction -@section History Expansion -@cindex history expansion - -The History library provides a history expansion feature that is similar -to the history expansion provided by @code{csh}. This section -describes the syntax used to manipulate the history information. - -History expansions introduce words from the history list into -the input stream, making it easy to repeat commands, insert the -arguments to a previous command into the current input line, or -fix errors in previous commands quickly. - -History expansion takes place in two parts. The first is to determine -which line from the history list should be used during substitution. -The second is to select portions of that line for inclusion into the -current one. The line selected from the history is called the -@dfn{event}, and the portions of that line that are acted upon are -called @dfn{words}. Various @dfn{modifiers} are available to manipulate -the selected words. The line is broken into words in the same fashion -that Bash does, so that several words -surrounded by quotes are considered one word. -History expansions are introduced by the appearance of the -history expansion character, which is @samp{!} by default. -@ifset BashFeatures -Only @samp{\} and @samp{'} may be used to escape the history expansion -character. -@end ifset - -@ifset BashFeatures -Several shell options settable with the @code{shopt} -builtin (@pxref{Bash Builtins}) may be used to tailor -the behavior of history expansion. If the -@code{histverify} shell option is enabled, and Readline -is being used, history substitutions are not immediately passed to -the shell parser. -Instead, the expanded line is reloaded into the Readline -editing buffer for further modification. -If Readline is being used, and the @code{histreedit} -shell option is enabled, a failed history expansion will be -reloaded into the Readline editing buffer for correction. -The @option{-p} option to the @code{history} builtin command -may be used to see what a history expansion will do before using it. -The @option{-s} option to the @code{history} builtin may be used to -add commands to the end of the history list without actually executing -them, so that they are available for subsequent recall. -This is most useful in conjunction with Readline. - -The shell allows control of the various characters used by the -history expansion mechanism with the @code{histchars} variable. -@end ifset - -@menu -* Event Designators:: How to specify which history line to use. -* Word Designators:: Specifying which words are of interest. -* Modifiers:: Modifying the results of substitution. -@end menu - -@node Event Designators -@subsection Event Designators -@cindex event designators - -An event designator is a reference to a command line entry in the -history list. -@cindex history events - -@table @asis - -@item @code{!} -Start a history substitution, except when followed by a space, tab, -the end of the line, @samp{=} or @samp{(}. - -@item @code{!@var{n}} -Refer to command line @var{n}. - -@item @code{!-@var{n}} -Refer to the command @var{n} lines back. - -@item @code{!!} -Refer to the previous command. This is a synonym for @samp{!-1}. - -@item @code{!@var{string}} -Refer to the most recent command starting with @var{string}. - -@item @code{!?@var{string}[?]} -Refer to the most recent command containing @var{string}. The trailing -@samp{?} may be omitted if the @var{string} is followed immediately by -a newline. - -@item @code{^@var{string1}^@var{string2}^} -Quick Substitution. Repeat the last command, replacing @var{string1} -with @var{string2}. Equivalent to -@code{!!:s/@var{string1}/@var{string2}/}. - -@item @code{!#} -The entire command line typed so far. - -@end table - -@node Word Designators -@subsection Word Designators - -Word designators are used to select desired words from the event. -A @samp{:} separates the event specification from the word designator. It -may be omitted if the word designator begins with a @samp{^}, @samp{$}, -@samp{*}, @samp{-}, or @samp{%}. Words are numbered from the beginning -of the line, with the first word being denoted by 0 (zero). Words are -inserted into the current line separated by single spaces. - -@need 0.75 -For example, - -@table @code -@item !! -designates the preceding command. When you type this, the preceding -command is repeated in toto. - -@item !!:$ -designates the last argument of the preceding command. This may be -shortened to @code{!$}. - -@item !fi:2 -designates the second argument of the most recent command starting with -the letters @code{fi}. -@end table - -@need 0.75 -Here are the word designators: - -@table @code - -@item 0 (zero) -The @code{0}th word. For many applications, this is the command word. - -@item @var{n} -The @var{n}th word. - -@item ^ -The first argument; that is, word 1. - -@item $ -The last argument. - -@item % -The word matched by the most recent @samp{?@var{string}?} search. - -@item @var{x}-@var{y} -A range of words; @samp{-@var{y}} abbreviates @samp{0-@var{y}}. - -@item * -All of the words, except the @code{0}th. This is a synonym for @samp{1-$}. -It is not an error to use @samp{*} if there is just one word in the event; -the empty string is returned in that case. - -@item @var{x}* -Abbreviates @samp{@var{x}-$} - -@item @var{x}- -Abbreviates @samp{@var{x}-$} like @samp{@var{x}*}, but omits the last word. - -@end table - -If a word designator is supplied without an event specification, the -previous command is used as the event. - -@node Modifiers -@subsection Modifiers - -After the optional word designator, you can add a sequence of one or more -of the following modifiers, each preceded by a @samp{:}. - -@table @code - -@item h -Remove a trailing pathname component, leaving only the head. - -@item t -Remove all leading pathname components, leaving the tail. - -@item r -Remove a trailing suffix of the form @samp{.@var{suffix}}, leaving -the basename. - -@item e -Remove all but the trailing suffix. - -@item p -Print the new command but do not execute it. - -@ifset BashFeatures -@item q -Quote the substituted words, escaping further substitutions. - -@item x -Quote the substituted words as with @samp{q}, -but break into words at spaces, tabs, and newlines. -@end ifset - -@item s/@var{old}/@var{new}/ -Substitute @var{new} for the first occurrence of @var{old} in the -event line. Any delimiter may be used in place of @samp{/}. -The delimiter may be quoted in @var{old} and @var{new} -with a single backslash. If @samp{&} appears in @var{new}, -it is replaced by @var{old}. A single backslash will quote -the @samp{&}. The final delimiter is optional if it is the last -character on the input line. - -@item & -Repeat the previous substitution. - -@item g -Cause changes to be applied over the entire event line. Used in -conjunction with @samp{s}, as in @code{gs/@var{old}/@var{new}/}, -or with @samp{&}. - -@end table diff --git a/readline/doc/inc-hist.texinfo b/readline/doc/inc-hist.texinfo index 37ed15f..b5ed3cb 100644 --- a/readline/doc/inc-hist.texinfo +++ b/readline/doc/inc-hist.texinfo @@ -1,7 +1,7 @@ @ignore This file documents the user interface to the GNU History library. -Copyright (C) 1988-1999 Free Software Foundation, Inc. +Copyright (C) 1988-2002 Free Software Foundation, Inc. Authored by Brian Fox and Chet Ramey. Permission is granted to make and distribute verbatim copies of this manual @@ -38,11 +38,10 @@ For information on using the @sc{gnu} History Library in other programs, see the @sc{gnu} Readline Library Manual. @end ifset @ifclear BashFeatures -This chapter describes how to use the GNU History Library interactively, +This chapter describes how to use the @sc{gnu} History Library interactively, from a user's standpoint. It should be considered a user's guide. -@c For -@c information on using the GNU History Library in your own programs, -@c @pxref{Programming with GNU History}. +For information on using the @sc{gnu} History Library in other programs, +see the @sc{gnu} Readline Library Manual. @end ifclear @ifset BashFeatures @@ -66,36 +65,39 @@ from a user's standpoint. It should be considered a user's guide. @cindex command history @cindex history list -When the @samp{-o history} option to the @code{set} builtin +When the @option{-o history} option to the @code{set} builtin is enabled (@pxref{The Set Builtin}), -the shell provides access to the @var{command history}, +the shell provides access to the @dfn{command history}, the list of commands previously typed. -The value of the @code{HISTSIZE} shell variable is used as the +The value of the @env{HISTSIZE} shell variable is used as the number of commands to save in a history list. -The text of the last @code{$HISTSIZE} +The text of the last @env{$HISTSIZE} commands (default 500) is saved. The shell stores each command in the history list prior to parameter and variable expansion but after history expansion is performed, subject to the values of the shell variables -@code{HISTIGNORE} and @code{HISTCONTROL}. +@env{HISTIGNORE} and @env{HISTCONTROL}. When the shell starts up, the history is initialized from the -file named by the @code{HISTFILE} variable (default @file{~/.bash_history}). -The file named by the value of @code{HISTFILE} is truncated, if +file named by the @env{HISTFILE} variable (default @file{~/.bash_history}). +The file named by the value of @env{HISTFILE} is truncated, if necessary, to contain no more than the number of lines specified by -the value of the @code{HISTFILESIZE} variable. +the value of the @env{HISTFILESIZE} variable. When an interactive shell exits, the last -@code{$HISTSIZE} lines are copied from the history list to the file -named by @code{$HISTFILE}. +@env{$HISTSIZE} lines are copied from the history list to the file +named by @env{$HISTFILE}. If the @code{histappend} shell option is set (@pxref{Bash Builtins}), the lines are appended to the history file, otherwise the history file is overwritten. -If @code{HISTFILE} +If @env{HISTFILE} is unset, or if the history file is unwritable, the history is not saved. After saving the history, the history file is truncated -to contain no more than @code{$HISTFILESIZE} -lines. If @code{HISTFILESIZE} is not set, no truncation is performed. +to contain no more than @env{$HISTFILESIZE} +lines. If @env{HISTFILESIZE} is not set, no truncation is performed. + +If the @env{HISTTIMEFORMAT} is set, the time stamp information +associated with each history entry is written to the history file. The builtin command @code{fc} may be used to list or edit and re-execute a portion of the history list. @@ -106,7 +108,7 @@ are available in each editing mode that provide access to the history list (@pxref{Commands For History}). The shell allows control over which commands are saved on the history -list. The @code{HISTCONTROL} and @code{HISTIGNORE} +list. The @env{HISTCONTROL} and @env{HISTIGNORE} variables may be set to cause the shell to save only a subset of the commands entered. The @code{cmdhist} @@ -142,15 +144,15 @@ command beginning with that string) or as a number (an index into the history list, where a negative number is used as an offset from the current command number). If @var{last} is not specified it is set to @var{first}. If @var{first} is not specified it is set to the previous -command for editing and @minus{}16 for listing. If the @samp{-l} flag is -given, the commands are listed on standard output. The @samp{-n} flag -suppresses the command numbers when listing. The @samp{-r} flag +command for editing and @minus{}16 for listing. If the @option{-l} flag is +given, the commands are listed on standard output. The @option{-n} flag +suppresses the command numbers when listing. The @option{-r} flag reverses the order of the listing. Otherwise, the editor given by @var{ename} is invoked on a file containing those commands. If @var{ename} is not given, the value of the following variable expansion is used: @code{$@{FCEDIT:-$@{EDITOR:-vi@}@}}. This says to use the -value of the @code{FCEDIT} variable if set, or the value of the -@code{EDITOR} variable if that is set, or @code{vi} if neither is set. +value of the @env{FCEDIT} variable if set, or the value of the +@env{EDITOR} variable if that is set, or @code{vi} if neither is set. When editing is complete, the edited commands are echoed and executed. In the second form, @var{command} is re-executed after each instance @@ -171,8 +173,14 @@ history -ps @var{arg} @end example With no options, display the history list with line numbers. -Lines prefixed with with a @samp{*} have been modified. +Lines prefixed with a @samp{*} have been modified. An argument of @var{n} lists only the last @var{n} lines. +If the shell variable @env{HISTTIMEFORMAT} is set and not null, +it is used as a format string for @var{strftime} to display +the time stamp associated with each displayed history entry. +No intervening blank is printed between the formatted time stamp +and the history line. + Options, if supplied, have the following meanings: @table @code @@ -212,10 +220,10 @@ the history list as a single entry. @end table -When any of the @samp{-w}, @samp{-r}, @samp{-a}, or @samp{-n} options is +When any of the @option{-w}, @option{-r}, @option{-a}, or @option{-n} options is used, if @var{filename} is given, then it is used as the history file. If not, then -the value of the @code{HISTFILE} variable is used. +the value of the @env{HISTFILE} variable is used. @end table @end ifset @@ -261,9 +269,9 @@ editing buffer for further modification. If Readline is being used, and the @code{histreedit} shell option is enabled, a failed history expansion will be reloaded into the Readline editing buffer for correction. -The @samp{-p} option to the @code{history} builtin command +The @option{-p} option to the @code{history} builtin command may be used to see what a history expansion will do before using it. -The @samp{-s} option to the @code{history} builtin may be used to +The @option{-s} option to the @code{history} builtin may be used to add commands to the end of the history list without actually executing them, so that they are available for subsequent recall. This is most useful in conjunction with Readline. @@ -289,8 +297,15 @@ history list. @table @asis @item @code{!} +@ifset BashFeatures Start a history substitution, except when followed by a space, tab, -the end of the line, @samp{=} or @samp{(}. +the end of the line, @samp{=} or @samp{(} (when the +@code{extglob} shell option is enabled using the @code{shopt} builtin). +@end ifset +@ifclear BashFeatures +Start a history substitution, except when followed by a space, tab, +the end of the line, or @samp{=}. +@end ifclear @item @code{!@var{n}} Refer to command line @var{n}. @@ -431,8 +446,12 @@ character on the input line. Repeat the previous substitution. @item g +@itemx a Cause changes to be applied over the entire event line. Used in conjunction with @samp{s}, as in @code{gs/@var{old}/@var{new}/}, or with @samp{&}. +@item G +Apply the following @samp{s} modifier once to each word in the event. + @end table diff --git a/readline/doc/manvers.texinfo b/readline/doc/manvers.texinfo deleted file mode 100644 index 1206cf0..0000000 --- a/readline/doc/manvers.texinfo +++ /dev/null @@ -1,10 +0,0 @@ -@ignore -Copyright (C) 1988-2002 Free Software Foundation, Inc. -@end ignore - -@set EDITION 4.3 -@set VERSION 4.3 -@set UPDATED 2002 March 4 -@set UPDATE-MONTH March 2002 - -@set LASTCHANGE Mon Mar 4 12:00:16 EST 2002 diff --git a/readline/doc/readline.3 b/readline/doc/readline.3 index afd6ba2..90cd997 100644 --- a/readline/doc/readline.3 +++ b/readline/doc/readline.3 @@ -6,9 +6,9 @@ .\" Case Western Reserve University .\" chet@ins.CWRU.Edu .\" -.\" Last Change: Tue Jan 22 09:18:25 EST 2002 +.\" Last Change: Tue Sep 13 12:07:26 EDT 2005 .\" -.TH READLINE 3 "2002 January 22" "GNU Readline 4.3" +.TH READLINE 3 "2005 Sep 13" "GNU Readline 5.1-beta1" .\" .\" File Name macro. This used to be `.PN', for Path Name, .\" but Sun doesn't seem to like that very much. @@ -34,8 +34,8 @@ readline \- get a line from a user with editing \fBreadline\fP (\fIconst char *prompt\fP); .fi .SH COPYRIGHT -.if n Readline is Copyright (C) 1989\-2002 by the Free Software Foundation, Inc. -.if t Readline is Copyright \(co 1989\-2002 by the Free Software Foundation, Inc. +.if n Readline is Copyright (C) 1989\-2004 by the Free Software Foundation, Inc. +.if t Readline is Copyright \(co 1989\-2004 by the Free Software Foundation, Inc. .SH DESCRIPTION .LP .B readline @@ -328,6 +328,10 @@ Except where noted, readline variables can take the values or .B Off (without regard to case). +Unrecognized variable names are ignored. +When a variable value is read, empty or null values, "on" (case-insensitive), +and "1" are equivalent to \fBOn\fP. All other values are equivalent to +\fBOff\fP. The variables and their default values are: .PP .PD 0 @@ -338,6 +342,11 @@ If set to \fBnone\fP, readline never rings the bell. If set to \fBvisible\fP, readline uses a visible bell if one is available. If set to \fBaudible\fP, readline attempts to ring the terminal's bell. .TP +.B bind\-tty\-special\-chars (On) +If set to \fBOn\fP, readline attempts to bind the control characters +treated specially by the kernel's terminal driver to their readline +equivalents. +.TP .B comment\-begin (``#'') The string that is inserted in \fBvi\fP mode when the .B insert\-comment @@ -360,7 +369,7 @@ It may be set to any integer value greater than or equal to zero. If the number of possible completions is greater than or equal to the value of this variable, the user is asked whether or not he wishes to view them; otherwise they are simply listed -on the terminal. +on the terminal. A negative value causes readline to never ask. .TP .B convert\-meta (On) If set to \fBOn\fP, readline will convert characters with the @@ -391,9 +400,9 @@ arrow keys. If set to \fBon\fP, tilde expansion is performed when readline attempts word completion. .TP -.B history-preserve-point +.B history\-preserve\-point (Off) If set to \fBon\fP, the history code attempts to place point at the -same location on each history line retrived with \fBprevious-history\fP +same location on each history line retrieved with \fBprevious-history\fP or \fBnext-history\fP. .TP .B horizontal\-scroll\-mode (Off) @@ -465,6 +474,16 @@ set to words which have more than one possible completion cause the matches to be listed immediately instead of ringing the bell. .TP +.B show\-all\-if\-unmodified (Off) +This alters the default behavior of the completion functions in +a fashion similar to \fBshow\-all\-if\-ambiguous\fP. +If set to +.BR on , +words which have more than one possible completion without any +possible partial completion (the possible completions don't share +a common prefix) cause the matches to be listed immediately instead +of ringing the bell. +.TP .B visible\-stats (Off) If set to \fBOn\fP, a character denoting a file's type as reported by \fIstat\fP(2) is appended to the filename when listing possible @@ -681,6 +700,8 @@ With an argument insert the \fIn\fPth word from the previous command (the words in the previous command begin with word 0). A negative argument inserts the \fIn\fPth word from the end of the previous command. +Once the argument \fIn\fP is computed, the argument is extracted +as if the "!\fIn\fP" history expansion had been specified. .TP .B yank\-last\-arg (M\-.\^, M\-_\^) @@ -689,6 +710,8 @@ the previous history entry). With an argument, behave exactly like \fByank\-nth\-arg\fP. Successive calls to \fByank\-last\-arg\fP move back through the history list, inserting the last argument of each line in turn. +The history expansion facilities are used to extract the last argument, +as if the "!$" history expansion had been specified. .PD .SS Commands for Changing Text .PP @@ -787,6 +810,11 @@ Word boundaries are the same as those used by \fBbackward\-word\fP. Kill the word behind point, using white space as a word boundary. The killed text is saved on the kill-ring. .TP +.B unix\-filename\-rubout +Kill the word behind point, using white space and the slash character +as the word boundaries. +The killed text is saved on the kill-ring. +.TP .B delete\-horizontal\-space (M\-\e) Delete all spaces and tabs around point. .TP @@ -868,7 +896,7 @@ with a single match from the list of possible completions. Repeated execution of \fBmenu\-complete\fP steps through the list of possible completions, inserting each match in turn. At the end of the list of completions, the bell is rung -(subject to the setting of \Bbell\-style\fP) +(subject to the setting of \fBbell\-style\fP) and the original text is restored. An argument of \fIn\fP moves \fIn\fP positions forward in the list of matches; a negative argument may be used to move backward @@ -979,7 +1007,7 @@ of an \fIinputrc\fP file. .TP .B dump\-macros Print all of the readline key sequences bound to macros and the -strings they ouput. If a numeric argument is supplied, +strings they output. If a numeric argument is supplied, the output is formatted in such a way that it can be made part of an \fIinputrc\fP file. .TP diff --git a/readline/doc/readline.pdf b/readline/doc/readline.pdf Binary files differdeleted file mode 100644 index 7fc2dfe..0000000 --- a/readline/doc/readline.pdf +++ /dev/null diff --git a/readline/doc/rlman.texinfo b/readline/doc/rlman.texinfo deleted file mode 100644 index 1ffebad..0000000 --- a/readline/doc/rlman.texinfo +++ /dev/null @@ -1,108 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@comment %**start of header (This is for running Texinfo on a region.) -@setfilename readline.info -@settitle GNU Readline Library -@comment %**end of header (This is for running Texinfo on a region.) -@synindex vr fn -@setchapternewpage odd - -@include manvers.texinfo - -@ifinfo -@dircategory Libraries -@direntry -* Readline: (readline). The GNU readline library API -@end direntry - -This document describes the GNU Readline Library, a utility which aids -in the consistency of user interface across discrete programs that need -to provide a command line interface. - -Copyright (C) 1988-2002 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -pare preserved on all copies. - -@ignore -Permission is granted to process this file through TeX and print the -results, provided the printed document carries copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). -@end ignore - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the entire -resulting derived work is distributed under the terms of a permission -notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that this permission notice may be stated in a translation approved -by the Free Software Foundation. -@end ifinfo - -@titlepage -@title GNU Readline Library -@subtitle Edition @value{EDITION}, for @code{Readline Library} Version @value{VERSION}. -@subtitle @value{UPDATE-MONTH} -@author Brian Fox, Free Software Foundation -@author Chet Ramey, Case Western Reserve University - -@page -This document describes the GNU Readline Library, a utility which aids -in the consistency of user interface across discrete programs that need -to provide a command line interface. - -Published by the Free Software Foundation @* -59 Temple Place, Suite 330, @* -Boston, MA 02111 USA - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the entire -resulting derived work is distributed under the terms of a permission -notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that this permission notice may be stated in a translation approved -by the Free Software Foundation. - -@vskip 0pt plus 1filll -Copyright @copyright{} 1988-2002 Free Software Foundation, Inc. -@end titlepage - -@ifinfo -@node Top -@top GNU Readline Library - -This document describes the GNU Readline Library, a utility which aids -in the consistency of user interface across discrete programs that need -to provide a command line interface. - -@menu -* Command Line Editing:: GNU Readline User's Manual. -* Programming with GNU Readline:: GNU Readline Programmer's Manual. -* Concept Index:: Index of concepts described in this manual. -* Function and Variable Index:: Index of externally visible functions - and variables. -@end menu -@end ifinfo - -@include rluser.texinfo -@include rltech.texinfo - -@node Concept Index -@unnumbered Concept Index -@printindex cp - -@node Function and Variable Index -@unnumbered Function and Variable Index -@printindex fn - -@contents -@bye diff --git a/readline/doc/rltech.texinfo b/readline/doc/rltech.texinfo deleted file mode 100644 index 037e824..0000000 --- a/readline/doc/rltech.texinfo +++ /dev/null @@ -1,2165 +0,0 @@ -@comment %**start of header (This is for running Texinfo on a region.) -@setfilename rltech.info -@comment %**end of header (This is for running Texinfo on a region.) -@setchapternewpage odd - -@ifinfo -This document describes the GNU Readline Library, a utility for aiding -in the consitency of user interface across discrete programs that need -to provide a command line interface. - -Copyright (C) 1988-2002 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -pare preserved on all copies. - -@ignore -Permission is granted to process this file through TeX and print the -results, provided the printed document carries copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). -@end ignore - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the entire -resulting derived work is distributed under the terms of a permission -notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that this permission notice may be stated in a translation approved -by the Foundation. -@end ifinfo - -@node Programming with GNU Readline -@chapter Programming with GNU Readline - -This chapter describes the interface between the @sc{gnu} Readline Library and -other programs. If you are a programmer, and you wish to include the -features found in @sc{gnu} Readline -such as completion, line editing, and interactive history manipulation -in your own programs, this section is for you. - -@menu -* Basic Behavior:: Using the default behavior of Readline. -* Custom Functions:: Adding your own functions to Readline. -* Readline Variables:: Variables accessible to custom - functions. -* Readline Convenience Functions:: Functions which Readline supplies to - aid in writing your own custom - functions. -* Readline Signal Handling:: How Readline behaves when it receives signals. -* Custom Completers:: Supplanting or supplementing Readline's - completion functions. -@end menu - -@node Basic Behavior -@section Basic Behavior - -Many programs provide a command line interface, such as @code{mail}, -@code{ftp}, and @code{sh}. For such programs, the default behaviour of -Readline is sufficient. This section describes how to use Readline in -the simplest way possible, perhaps to replace calls in your code to -@code{gets()} or @code{fgets()}. - -@findex readline -@cindex readline, function - -The function @code{readline()} prints a prompt @var{prompt} -and then reads and returns a single line of text from the user. -If @var{prompt} is @code{NULL} or the empty string, no prompt is displayed. -The line @code{readline} returns is allocated with @code{malloc()}; -the caller should @code{free()} the line when it has finished with it. -The declaration for @code{readline} in ANSI C is - -@example -@code{char *readline (const char *@var{prompt});} -@end example - -@noindent -So, one might say -@example -@code{char *line = readline ("Enter a line: ");} -@end example -@noindent -in order to read a line of text from the user. -The line returned has the final newline removed, so only the -text remains. - -If @code{readline} encounters an @code{EOF} while reading the line, and the -line is empty at that point, then @code{(char *)NULL} is returned. -Otherwise, the line is ended just as if a newline had been typed. - -If you want the user to be able to get at the line later, (with -@key{C-p} for example), you must call @code{add_history()} to save the -line away in a @dfn{history} list of such lines. - -@example -@code{add_history (line)}; -@end example - -@noindent -For full details on the GNU History Library, see the associated manual. - -It is preferable to avoid saving empty lines on the history list, since -users rarely have a burning need to reuse a blank line. Here is -a function which usefully replaces the standard @code{gets()} library -function, and has the advantage of no static buffer to overflow: - -@example -/* A static variable for holding the line. */ -static char *line_read = (char *)NULL; - -/* Read a string, and return a pointer to it. - Returns NULL on EOF. */ -char * -rl_gets () -@{ - /* If the buffer has already been allocated, - return the memory to the free pool. */ - if (line_read) - @{ - free (line_read); - line_read = (char *)NULL; - @} - - /* Get a line from the user. */ - line_read = readline (""); - - /* If the line has any text in it, - save it on the history. */ - if (line_read && *line_read) - add_history (line_read); - - return (line_read); -@} -@end example - -This function gives the user the default behaviour of @key{TAB} -completion: completion on file names. If you do not want Readline to -complete on filenames, you can change the binding of the @key{TAB} key -with @code{rl_bind_key()}. - -@example -@code{int rl_bind_key (int @var{key}, rl_command_func_t *@var{function});} -@end example - -@code{rl_bind_key()} takes two arguments: @var{key} is the character that -you want to bind, and @var{function} is the address of the function to -call when @var{key} is pressed. Binding @key{TAB} to @code{rl_insert()} -makes @key{TAB} insert itself. -@code{rl_bind_key()} returns non-zero if @var{key} is not a valid -ASCII character code (between 0 and 255). - -Thus, to disable the default @key{TAB} behavior, the following suffices: -@example -@code{rl_bind_key ('\t', rl_insert);} -@end example - -This code should be executed once at the start of your program; you -might write a function called @code{initialize_readline()} which -performs this and other desired initializations, such as installing -custom completers (@pxref{Custom Completers}). - -@node Custom Functions -@section Custom Functions - -Readline provides many functions for manipulating the text of -the line, but it isn't possible to anticipate the needs of all -programs. This section describes the various functions and variables -defined within the Readline library which allow a user program to add -customized functionality to Readline. - -Before declaring any functions that customize Readline's behavior, or -using any functionality Readline provides in other code, an -application writer should include the file @code{<readline/readline.h>} -in any file that uses Readline's features. Since some of the definitions -in @code{readline.h} use the @code{stdio} library, the file -@code{<stdio.h>} should be included before @code{readline.h}. - -@code{readline.h} defines a C preprocessor variable that should -be treated as an integer, @code{RL_READLINE_VERSION}, which may -be used to conditionally compile application code depending on -the installed Readline version. The value is a hexadecimal -encoding of the major and minor version numbers of the library, -of the form 0x@var{MMmm}. @var{MM} is the two-digit major -version number; @var{mm} is the two-digit minor version number. -For Readline 4.2, for example, the value of -@code{RL_READLINE_VERSION} would be @code{0x0402}. - -@menu -* Readline Typedefs:: C declarations to make code readable. -* Function Writing:: Variables and calling conventions. -@end menu - -@node Readline Typedefs -@subsection Readline Typedefs - -For readabilty, we declare a number of new object types, all pointers -to functions. - -The reason for declaring these new types is to make it easier to write -code describing pointers to C functions with appropriately prototyped -arguments and return values. - -For instance, say we want to declare a variable @var{func} as a pointer -to a function which takes two @code{int} arguments and returns an -@code{int} (this is the type of all of the Readline bindable functions). -Instead of the classic C declaration - -@code{int (*func)();} - -@noindent -or the ANSI-C style declaration - -@code{int (*func)(int, int);} - -@noindent -we may write - -@code{rl_command_func_t *func;} - -The full list of function pointer types available is - -@table @code -@item typedef int rl_command_func_t (int, int); - -@item typedef char *rl_compentry_func_t (const char *, int); - -@item typedef char **rl_completion_func_t (const char *, int, int); - -@item typedef char *rl_quote_func_t (char *, int, char *); - -@item typedef char *rl_dequote_func_t (char *, int); - -@item typedef int rl_compignore_func_t (char **); - -@item typedef void rl_compdisp_func_t (char **, int, int); - -@item typedef int rl_hook_func_t (void); - -@item typedef int rl_getc_func_t (FILE *); - -@item typedef int rl_linebuf_func_t (char *, int); - -@item typedef int rl_intfunc_t (int); -@item #define rl_ivoidfunc_t rl_hook_func_t -@item typedef int rl_icpfunc_t (char *); -@item typedef int rl_icppfunc_t (char **); - -@item typedef void rl_voidfunc_t (void); -@item typedef void rl_vintfunc_t (int); -@item typedef void rl_vcpfunc_t (char *); -@item typedef void rl_vcppfunc_t (char **); - -@end table - -@node Function Writing -@subsection Writing a New Function - -In order to write new functions for Readline, you need to know the -calling conventions for keyboard-invoked functions, and the names of the -variables that describe the current state of the line read so far. - -The calling sequence for a command @code{foo} looks like - -@example -@code{int foo (int count, int key)} -@end example - -@noindent -where @var{count} is the numeric argument (or 1 if defaulted) and -@var{key} is the key that invoked this function. - -It is completely up to the function as to what should be done with the -numeric argument. Some functions use it as a repeat count, some -as a flag, and others to choose alternate behavior (refreshing the current -line as opposed to refreshing the screen, for example). Some choose to -ignore it. In general, if a -function uses the numeric argument as a repeat count, it should be able -to do something useful with both negative and positive arguments. -At the very least, it should be aware that it can be passed a -negative argument. - -A command function should return 0 if its action completes successfully, -and a non-zero value if some error occurs. - -@node Readline Variables -@section Readline Variables - -These variables are available to function writers. - -@deftypevar {char *} rl_line_buffer -This is the line gathered so far. You are welcome to modify the -contents of the line, but see @ref{Allowing Undoing}. The -function @code{rl_extend_line_buffer} is available to increase -the memory allocated to @code{rl_line_buffer}. -@end deftypevar - -@deftypevar int rl_point -The offset of the current cursor position in @code{rl_line_buffer} -(the @emph{point}). -@end deftypevar - -@deftypevar int rl_end -The number of characters present in @code{rl_line_buffer}. When -@code{rl_point} is at the end of the line, @code{rl_point} and -@code{rl_end} are equal. -@end deftypevar - -@deftypevar int rl_mark -The @var{mark} (saved position) in the current line. If set, the mark -and point define a @emph{region}. -@end deftypevar - -@deftypevar int rl_done -Setting this to a non-zero value causes Readline to return the current -line immediately. -@end deftypevar - -@deftypevar int rl_num_chars_to_read -Setting this to a positive value before calling @code{readline()} causes -Readline to return after accepting that many characters, rather -than reading up to a character bound to @code{accept-line}. -@end deftypevar - -@deftypevar int rl_pending_input -Setting this to a value makes it the next keystroke read. This is a -way to stuff a single character into the input stream. -@end deftypevar - -@deftypevar int rl_dispatching -Set to a non-zero value if a function is being called from a key binding; -zero otherwise. Application functions can test this to discover whether -they were called directly or by Readline's dispatching mechanism. -@end deftypevar - -@deftypevar int rl_erase_empty_line -Setting this to a non-zero value causes Readline to completely erase -the current line, including any prompt, any time a newline is typed as -the only character on an otherwise-empty line. The cursor is moved to -the beginning of the newly-blank line. -@end deftypevar - -@deftypevar {char *} rl_prompt -The prompt Readline uses. This is set from the argument to -@code{readline()}, and should not be assigned to directly. -The @code{rl_set_prompt()} function (@pxref{Redisplay}) may -be used to modify the prompt string after calling @code{readline()}. -@end deftypevar - -@deftypevar int rl_already_prompted -If an application wishes to display the prompt itself, rather than have -Readline do it the first time @code{readline()} is called, it should set -this variable to a non-zero value after displaying the prompt. -The prompt must also be passed as the argument to @code{readline()} so -the redisplay functions can update the display properly. -The calling application is responsible for managing the value; Readline -never sets it. -@end deftypevar - -@deftypevar {const char *} rl_library_version -The version number of this revision of the library. -@end deftypevar - -@deftypevar int rl_readline_version -An integer encoding the current version of the library. The encoding is -of the form 0x@var{MMmm}, where @var{MM} is the two-digit major version -number, and @var{mm} is the two-digit minor version number. -For example, for Readline-4.2, @code{rl_readline_version} would have the -value 0x0402. -@end deftypevar - -@deftypevar {int} rl_gnu_readline_p -Always set to 1, denoting that this is @sc{gnu} readline rather than some -emulation. -@end deftypevar - -@deftypevar {const char *} rl_terminal_name -The terminal type, used for initialization. If not set by the application, -Readline sets this to the value of the @env{TERM} environment variable -the first time it is called. -@end deftypevar - -@deftypevar {const char *} rl_readline_name -This variable is set to a unique name by each application using Readline. -The value allows conditional parsing of the inputrc file -(@pxref{Conditional Init Constructs}). -@end deftypevar - -@deftypevar {FILE *} rl_instream -The stdio stream from which Readline reads input. -If @code{NULL}, Readline defaults to @var{stdin}. -@end deftypevar - -@deftypevar {FILE *} rl_outstream -The stdio stream to which Readline performs output. -If @code{NULL}, Readline defaults to @var{stdout}. -@end deftypevar - -@deftypevar {rl_command_func_t *} rl_last_func -The address of the last command function Readline executed. May be used to -test whether or not a function is being executed twice in succession, for -example. -@end deftypevar - -@deftypevar {rl_hook_func_t *} rl_startup_hook -If non-zero, this is the address of a function to call just -before @code{readline} prints the first prompt. -@end deftypevar - -@deftypevar {rl_hook_func_t *} rl_pre_input_hook -If non-zero, this is the address of a function to call after -the first prompt has been printed and just before @code{readline} -starts reading input characters. -@end deftypevar - -@deftypevar {rl_hook_func_t *} rl_event_hook -If non-zero, this is the address of a function to call periodically -when Readline is waiting for terminal input. -By default, this will be called at most ten times a second if there -is no keyboard input. -@end deftypevar - -@deftypevar {rl_getc_func_t *} rl_getc_function -If non-zero, Readline will call indirectly through this pointer -to get a character from the input stream. By default, it is set to -@code{rl_getc}, the default Readline character input function -(@pxref{Character Input}). -@end deftypevar - -@deftypevar {rl_voidfunc_t *} rl_redisplay_function -If non-zero, Readline will call indirectly through this pointer -to update the display with the current contents of the editing buffer. -By default, it is set to @code{rl_redisplay}, the default Readline -redisplay function (@pxref{Redisplay}). -@end deftypevar - -@deftypevar {rl_vintfunc_t *} rl_prep_term_function -If non-zero, Readline will call indirectly through this pointer -to initialize the terminal. The function takes a single argument, an -@code{int} flag that says whether or not to use eight-bit characters. -By default, this is set to @code{rl_prep_terminal} -(@pxref{Terminal Management}). -@end deftypevar - -@deftypevar {rl_voidfunc_t *} rl_deprep_term_function -If non-zero, Readline will call indirectly through this pointer -to reset the terminal. This function should undo the effects of -@code{rl_prep_term_function}. -By default, this is set to @code{rl_deprep_terminal} -(@pxref{Terminal Management}). -@end deftypevar - -@deftypevar {Keymap} rl_executing_keymap -This variable is set to the keymap (@pxref{Keymaps}) in which the -currently executing readline function was found. -@end deftypevar - -@deftypevar {Keymap} rl_binding_keymap -This variable is set to the keymap (@pxref{Keymaps}) in which the -last key binding occurred. -@end deftypevar - -@deftypevar {char *} rl_executing_macro -This variable is set to the text of any currently-executing macro. -@end deftypevar - -@deftypevar {int} rl_readline_state -A variable with bit values that encapsulate the current Readline state. -A bit is set with the @code{RL_SETSTATE} macro, and unset with the -@code{RL_UNSETSTATE} macro. Use the @code{RL_ISSTATE} macro to test -whether a particular state bit is set. Current state bits include: - -@table @code -@item RL_STATE_NONE -Readline has not yet been called, nor has it begun to intialize. -@item RL_STATE_INITIALIZING -Readline is initializing its internal data structures. -@item RL_STATE_INITIALIZED -Readline has completed its initialization. -@item RL_STATE_TERMPREPPED -Readline has modified the terminal modes to do its own input and redisplay. -@item RL_STATE_READCMD -Readline is reading a command from the keyboard. -@item RL_STATE_METANEXT -Readline is reading more input after reading the meta-prefix character. -@item RL_STATE_DISPATCHING -Readline is dispatching to a command. -@item RL_STATE_MOREINPUT -Readline is reading more input while executing an editing command. -@item RL_STATE_ISEARCH -Readline is performing an incremental history search. -@item RL_STATE_NSEARCH -Readline is performing a non-incremental history search. -@item RL_STATE_SEARCH -Readline is searching backward or forward through the history for a string. -@item RL_STATE_NUMERICARG -Readline is reading a numeric argument. -@item RL_STATE_MACROINPUT -Readline is currently getting its input from a previously-defined keyboard -macro. -@item RL_STATE_MACRODEF -Readline is currently reading characters defining a keyboard macro. -@item RL_STATE_OVERWRITE -Readline is in overwrite mode. -@item RL_STATE_COMPLETING -Readline is performing word completion. -@item RL_STATE_SIGHANDLER -Readline is currently executing the readline signal handler. -@item RL_STATE_UNDOING -Readline is performing an undo. -@item RL_STATE_DONE -Readline has read a key sequence bound to @code{accept-line} -and is about to return the line to the caller. -@end table - -@end deftypevar - -@deftypevar {int} rl_explicit_arg -Set to a non-zero value if an explicit numeric argument was specified by -the user. Only valid in a bindable command function. -@end deftypevar - -@deftypevar {int} rl_numeric_arg -Set to the value of any numeric argument explicitly specified by the user -before executing the current Readline function. Only valid in a bindable -command function. -@end deftypevar - -@deftypevar {int} rl_editing_mode -Set to a value denoting Readline's current editing mode. A value of -@var{1} means Readline is currently in emacs mode; @var{0} -means that vi mode is active. -@end deftypevar - - -@node Readline Convenience Functions -@section Readline Convenience Functions - -@menu -* Function Naming:: How to give a function you write a name. -* Keymaps:: Making keymaps. -* Binding Keys:: Changing Keymaps. -* Associating Function Names and Bindings:: Translate function names to - key sequences. -* Allowing Undoing:: How to make your functions undoable. -* Redisplay:: Functions to control line display. -* Modifying Text:: Functions to modify @code{rl_line_buffer}. -* Character Input:: Functions to read keyboard input. -* Terminal Management:: Functions to manage terminal settings. -* Utility Functions:: Generally useful functions and hooks. -* Miscellaneous Functions:: Functions that don't fall into any category. -* Alternate Interface:: Using Readline in a `callback' fashion. -* A Readline Example:: An example Readline function. -@end menu - -@node Function Naming -@subsection Naming a Function - -The user can dynamically change the bindings of keys while using -Readline. This is done by representing the function with a descriptive -name. The user is able to type the descriptive name when referring to -the function. Thus, in an init file, one might find - -@example -Meta-Rubout: backward-kill-word -@end example - -This binds the keystroke @key{Meta-Rubout} to the function -@emph{descriptively} named @code{backward-kill-word}. You, as the -programmer, should bind the functions you write to descriptive names as -well. Readline provides a function for doing that: - -@deftypefun int rl_add_defun (const char *name, rl_command_func_t *function, int key) -Add @var{name} to the list of named functions. Make @var{function} be -the function that gets called. If @var{key} is not -1, then bind it to -@var{function} using @code{rl_bind_key()}. -@end deftypefun - -Using this function alone is sufficient for most applications. It is -the recommended way to add a few functions to the default functions that -Readline has built in. If you need to do something other -than adding a function to Readline, you may need to use the -underlying functions described below. - -@node Keymaps -@subsection Selecting a Keymap - -Key bindings take place on a @dfn{keymap}. The keymap is the -association between the keys that the user types and the functions that -get run. You can make your own keymaps, copy existing keymaps, and tell -Readline which keymap to use. - -@deftypefun Keymap rl_make_bare_keymap (void) -Returns a new, empty keymap. The space for the keymap is allocated with -@code{malloc()}; the caller should free it by calling -@code{rl_discard_keymap()} when done. -@end deftypefun - -@deftypefun Keymap rl_copy_keymap (Keymap map) -Return a new keymap which is a copy of @var{map}. -@end deftypefun - -@deftypefun Keymap rl_make_keymap (void) -Return a new keymap with the printing characters bound to rl_insert, -the lowercase Meta characters bound to run their equivalents, and -the Meta digits bound to produce numeric arguments. -@end deftypefun - -@deftypefun void rl_discard_keymap (Keymap keymap) -Free the storage associated with @var{keymap}. -@end deftypefun - -Readline has several internal keymaps. These functions allow you to -change which keymap is active. - -@deftypefun Keymap rl_get_keymap (void) -Returns the currently active keymap. -@end deftypefun - -@deftypefun void rl_set_keymap (Keymap keymap) -Makes @var{keymap} the currently active keymap. -@end deftypefun - -@deftypefun Keymap rl_get_keymap_by_name (const char *name) -Return the keymap matching @var{name}. @var{name} is one which would -be supplied in a @code{set keymap} inputrc line (@pxref{Readline Init File}). -@end deftypefun - -@deftypefun {char *} rl_get_keymap_name (Keymap keymap) -Return the name matching @var{keymap}. @var{name} is one which would -be supplied in a @code{set keymap} inputrc line (@pxref{Readline Init File}). -@end deftypefun - -@node Binding Keys -@subsection Binding Keys - -Key sequences are associate with functions through the keymap. -Readline has several internal keymaps: @code{emacs_standard_keymap}, -@code{emacs_meta_keymap}, @code{emacs_ctlx_keymap}, -@code{vi_movement_keymap}, and @code{vi_insertion_keymap}. -@code{emacs_standard_keymap} is the default, and the examples in -this manual assume that. - -Since @code{readline()} installs a set of default key bindings the first -time it is called, there is always the danger that a custom binding -installed before the first call to @code{readline()} will be overridden. -An alternate mechanism is to install custom key bindings in an -initialization function assigned to the @code{rl_startup_hook} variable -(@pxref{Readline Variables}). - -These functions manage key bindings. - -@deftypefun int rl_bind_key (int key, rl_command_func_t *function) -Binds @var{key} to @var{function} in the currently active keymap. -Returns non-zero in the case of an invalid @var{key}. -@end deftypefun - -@deftypefun int rl_bind_key_in_map (int key, rl_command_func_t *function, Keymap map) -Bind @var{key} to @var{function} in @var{map}. Returns non-zero in the case -of an invalid @var{key}. -@end deftypefun - -@deftypefun int rl_unbind_key (int key) -Bind @var{key} to the null function in the currently active keymap. -Returns non-zero in case of error. -@end deftypefun - -@deftypefun int rl_unbind_key_in_map (int key, Keymap map) -Bind @var{key} to the null function in @var{map}. -Returns non-zero in case of error. -@end deftypefun - -@deftypefun int rl_unbind_function_in_map (rl_command_func_t *function, Keymap map) -Unbind all keys that execute @var{function} in @var{map}. -@end deftypefun - -@deftypefun int rl_unbind_command_in_map (const char *command, Keymap map) -Unbind all keys that are bound to @var{command} in @var{map}. -@end deftypefun - -@deftypefun int rl_set_key (const char *keyseq, rl_command_func_t *function, Keymap map) -Bind the key sequence represented by the string @var{keyseq} to the function -@var{function}. This makes new keymaps as -necessary. The initial keymap in which to do bindings is @var{map}. -@end deftypefun - -@deftypefun int rl_generic_bind (int type, const char *keyseq, char *data, Keymap map) -Bind the key sequence represented by the string @var{keyseq} to the arbitrary -pointer @var{data}. @var{type} says what kind of data is pointed to by -@var{data}; this can be a function (@code{ISFUNC}), a macro -(@code{ISMACR}), or a keymap (@code{ISKMAP}). This makes new keymaps as -necessary. The initial keymap in which to do bindings is @var{map}. -@end deftypefun - -@deftypefun int rl_parse_and_bind (char *line) -Parse @var{line} as if it had been read from the @code{inputrc} file and -perform any key bindings and variable assignments found -(@pxref{Readline Init File}). -@end deftypefun - -@deftypefun int rl_read_init_file (const char *filename) -Read keybindings and variable assignments from @var{filename} -(@pxref{Readline Init File}). -@end deftypefun - -@node Associating Function Names and Bindings -@subsection Associating Function Names and Bindings - -These functions allow you to find out what keys invoke named functions -and the functions invoked by a particular key sequence. You may also -associate a new function name with an arbitrary function. - -@deftypefun {rl_command_func_t *} rl_named_function (const char *name) -Return the function with name @var{name}. -@end deftypefun - -@deftypefun {rl_command_func_t *} rl_function_of_keyseq (const char *keyseq, Keymap map, int *type) -Return the function invoked by @var{keyseq} in keymap @var{map}. -If @var{map} is @code{NULL}, the current keymap is used. If @var{type} is -not @code{NULL}, the type of the object is returned in the @code{int} variable -it points to (one of @code{ISFUNC}, @code{ISKMAP}, or @code{ISMACR}). -@end deftypefun - -@deftypefun {char **} rl_invoking_keyseqs (rl_command_func_t *function) -Return an array of strings representing the key sequences used to -invoke @var{function} in the current keymap. -@end deftypefun - -@deftypefun {char **} rl_invoking_keyseqs_in_map (rl_command_func_t *function, Keymap map) -Return an array of strings representing the key sequences used to -invoke @var{function} in the keymap @var{map}. -@end deftypefun - -@deftypefun void rl_function_dumper (int readable) -Print the readline function names and the key sequences currently -bound to them to @code{rl_outstream}. If @var{readable} is non-zero, -the list is formatted in such a way that it can be made part of an -@code{inputrc} file and re-read. -@end deftypefun - -@deftypefun void rl_list_funmap_names (void) -Print the names of all bindable Readline functions to @code{rl_outstream}. -@end deftypefun - -@deftypefun {const char **} rl_funmap_names (void) -Return a NULL terminated array of known function names. The array is -sorted. The array itself is allocated, but not the strings inside. You -should @code{free()} the array when you are done, but not the pointers. -@end deftypefun - -@deftypefun int rl_add_funmap_entry (const char *name, rl_command_func_t *function) -Add @var{name} to the list of bindable Readline command names, and make -@var{function} the function to be called when @var{name} is invoked. -@end deftypefun - -@node Allowing Undoing -@subsection Allowing Undoing - -Supporting the undo command is a painless thing, and makes your -functions much more useful. It is certainly easy to try -something if you know you can undo it. - -If your function simply inserts text once, or deletes text once, and -uses @code{rl_insert_text()} or @code{rl_delete_text()} to do it, then -undoing is already done for you automatically. - -If you do multiple insertions or multiple deletions, or any combination -of these operations, you should group them together into one operation. -This is done with @code{rl_begin_undo_group()} and -@code{rl_end_undo_group()}. - -The types of events that can be undone are: - -@smallexample -enum undo_code @{ UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END @}; -@end smallexample - -Notice that @code{UNDO_DELETE} means to insert some text, and -@code{UNDO_INSERT} means to delete some text. That is, the undo code -tells what to undo, not how to undo it. @code{UNDO_BEGIN} and -@code{UNDO_END} are tags added by @code{rl_begin_undo_group()} and -@code{rl_end_undo_group()}. - -@deftypefun int rl_begin_undo_group (void) -Begins saving undo information in a group construct. The undo -information usually comes from calls to @code{rl_insert_text()} and -@code{rl_delete_text()}, but could be the result of calls to -@code{rl_add_undo()}. -@end deftypefun - -@deftypefun int rl_end_undo_group (void) -Closes the current undo group started with @code{rl_begin_undo_group -()}. There should be one call to @code{rl_end_undo_group()} -for each call to @code{rl_begin_undo_group()}. -@end deftypefun - -@deftypefun void rl_add_undo (enum undo_code what, int start, int end, char *text) -Remember how to undo an event (according to @var{what}). The affected -text runs from @var{start} to @var{end}, and encompasses @var{text}. -@end deftypefun - -@deftypefun void rl_free_undo_list (void) -Free the existing undo list. -@end deftypefun - -@deftypefun int rl_do_undo (void) -Undo the first thing on the undo list. Returns @code{0} if there was -nothing to undo, non-zero if something was undone. -@end deftypefun - -Finally, if you neither insert nor delete text, but directly modify the -existing text (e.g., change its case), call @code{rl_modifying()} -once, just before you modify the text. You must supply the indices of -the text range that you are going to modify. - -@deftypefun int rl_modifying (int start, int end) -Tell Readline to save the text between @var{start} and @var{end} as a -single undo unit. It is assumed that you will subsequently modify -that text. -@end deftypefun - -@node Redisplay -@subsection Redisplay - -@deftypefun void rl_redisplay (void) -Change what's displayed on the screen to reflect the current contents -of @code{rl_line_buffer}. -@end deftypefun - -@deftypefun int rl_forced_update_display (void) -Force the line to be updated and redisplayed, whether or not -Readline thinks the screen display is correct. -@end deftypefun - -@deftypefun int rl_on_new_line (void) -Tell the update functions that we have moved onto a new (empty) line, -usually after ouputting a newline. -@end deftypefun - -@deftypefun int rl_on_new_line_with_prompt (void) -Tell the update functions that we have moved onto a new line, with -@var{rl_prompt} already displayed. -This could be used by applications that want to output the prompt string -themselves, but still need Readline to know the prompt string length for -redisplay. -It should be used after setting @var{rl_already_prompted}. -@end deftypefun - -@deftypefun int rl_reset_line_state (void) -Reset the display state to a clean state and redisplay the current line -starting on a new line. -@end deftypefun - -@deftypefun int rl_crlf (void) -Move the cursor to the start of the next screen line. -@end deftypefun - -@deftypefun int rl_show_char (int c) -Display character @var{c} on @code{rl_outstream}. -If Readline has not been set to display meta characters directly, this -will convert meta characters to a meta-prefixed key sequence. -This is intended for use by applications which wish to do their own -redisplay. -@end deftypefun - -@deftypefun int rl_message (const char *, @dots{}) -The arguments are a format string as would be supplied to @code{printf}, -possibly containing conversion specifications such as @samp{%d}, and -any additional arguments necessary to satisfy the conversion specifications. -The resulting string is displayed in the @dfn{echo area}. The echo area -is also used to display numeric arguments and search strings. -@end deftypefun - -@deftypefun int rl_clear_message (void) -Clear the message in the echo area. -@end deftypefun - -@deftypefun void rl_save_prompt (void) -Save the local Readline prompt display state in preparation for -displaying a new message in the message area with @code{rl_message()}. -@end deftypefun - -@deftypefun void rl_restore_prompt (void) -Restore the local Readline prompt display state saved by the most -recent call to @code{rl_save_prompt}. -@end deftypefun - -@deftypefun int rl_expand_prompt (char *prompt) -Expand any special character sequences in @var{prompt} and set up the -local Readline prompt redisplay variables. -This function is called by @code{readline()}. It may also be called to -expand the primary prompt if the @code{rl_on_new_line_with_prompt()} -function or @code{rl_already_prompted} variable is used. -It returns the number of visible characters on the last line of the -(possibly multi-line) prompt. -@end deftypefun - -@deftypefun int rl_set_prompt (const char *prompt) -Make Readline use @var{prompt} for subsequent redisplay. This calls -@code{rl_expand_prompt()} to expand the prompt and sets @code{rl_prompt} -to the result. -@end deftypefun - -@node Modifying Text -@subsection Modifying Text - -@deftypefun int rl_insert_text (const char *text) -Insert @var{text} into the line at the current cursor position. -Returns the number of characters inserted. -@end deftypefun - -@deftypefun int rl_delete_text (int start, int end) -Delete the text between @var{start} and @var{end} in the current line. -Returns the number of characters deleted. -@end deftypefun - -@deftypefun {char *} rl_copy_text (int start, int end) -Return a copy of the text between @var{start} and @var{end} in -the current line. -@end deftypefun - -@deftypefun int rl_kill_text (int start, int end) -Copy the text between @var{start} and @var{end} in the current line -to the kill ring, appending or prepending to the last kill if the -last command was a kill command. The text is deleted. -If @var{start} is less than @var{end}, -the text is appended, otherwise prepended. If the last command was -not a kill, a new kill ring slot is used. -@end deftypefun - -@deftypefun int rl_push_macro_input (char *macro) -Cause @var{macro} to be inserted into the line, as if it had been invoked -by a key bound to a macro. Not especially useful; use -@code{rl_insert_text()} instead. -@end deftypefun - -@node Character Input -@subsection Character Input - -@deftypefun int rl_read_key (void) -Return the next character available from Readline's current input stream. -This handles input inserted into -the input stream via @var{rl_pending_input} (@pxref{Readline Variables}) -and @code{rl_stuff_char()}, macros, and characters read from the keyboard. -While waiting for input, this function will call any function assigned to -the @code{rl_event_hook} variable. -@end deftypefun - -@deftypefun int rl_getc (FILE *stream) -Return the next character available from @var{stream}, which is assumed to -be the keyboard. -@end deftypefun - -@deftypefun int rl_stuff_char (int c) -Insert @var{c} into the Readline input stream. It will be "read" -before Readline attempts to read characters from the terminal with -@code{rl_read_key()}. Up to 512 characters may be pushed back. -@code{rl_stuff_char} returns 1 if the character was successfully inserted; -0 otherwise. -@end deftypefun - -@deftypefun int rl_execute_next (int c) -Make @var{c} be the next command to be executed when @code{rl_read_key()} -is called. This sets @var{rl_pending_input}. -@end deftypefun - -@deftypefun int rl_clear_pending_input (void) -Unset @var{rl_pending_input}, effectively negating the effect of any -previous call to @code{rl_execute_next()}. This works only if the -pending input has not already been read with @code{rl_read_key()}. -@end deftypefun - -@deftypefun int rl_set_keyboard_input_timeout (int u) -While waiting for keyboard input in @code{rl_read_key()}, Readline will -wait for @var{u} microseconds for input before calling any function -assigned to @code{rl_event_hook}. The default waiting period is -one-tenth of a second. Returns the old timeout value. -@end deftypefun - -@node Terminal Management -@subsection Terminal Management - -@deftypefun void rl_prep_terminal (int meta_flag) -Modify the terminal settings for Readline's use, so @code{readline()} -can read a single character at a time from the keyboard. -The @var{meta_flag} argument should be non-zero if Readline should -read eight-bit input. -@end deftypefun - -@deftypefun void rl_deprep_terminal (void) -Undo the effects of @code{rl_prep_terminal()}, leaving the terminal in -the state in which it was before the most recent call to -@code{rl_prep_terminal()}. -@end deftypefun - -@deftypefun void rl_tty_set_default_bindings (Keymap kmap) -Read the operating system's terminal editing characters (as would be displayed -by @code{stty}) to their Readline equivalents. The bindings are performed -in @var{kmap}. -@end deftypefun - -@deftypefun int rl_reset_terminal (const char *terminal_name) -Reinitialize Readline's idea of the terminal settings using -@var{terminal_name} as the terminal type (e.g., @code{vt100}). -If @var{terminal_name} is @code{NULL}, the value of the @code{TERM} -environment variable is used. -@end deftypefun - -@node Utility Functions -@subsection Utility Functions - -@deftypefun void rl_replace_line (const char *text, int clear_undo) -Replace the contents of @code{rl_line_buffer} with @var{text}. -The point and mark are preserved, if possible. -If @var{clear_undo} is non-zero, the undo list associated with the -current line is cleared. -@end deftypefun - -@deftypefun int rl_extend_line_buffer (int len) -Ensure that @code{rl_line_buffer} has enough space to hold @var{len} -characters, possibly reallocating it if necessary. -@end deftypefun - -@deftypefun int rl_initialize (void) -Initialize or re-initialize Readline's internal state. -It's not strictly necessary to call this; @code{readline()} calls it before -reading any input. -@end deftypefun - -@deftypefun int rl_ding (void) -Ring the terminal bell, obeying the setting of @code{bell-style}. -@end deftypefun - -@deftypefun int rl_alphabetic (int c) -Return 1 if @var{c} is an alphabetic character. -@end deftypefun - -@deftypefun void rl_display_match_list (char **matches, int len, int max) -A convenience function for displaying a list of strings in -columnar format on Readline's output stream. @code{matches} is the list -of strings, in argv format, such as a list of completion matches. -@code{len} is the number of strings in @code{matches}, and @code{max} -is the length of the longest string in @code{matches}. This function uses -the setting of @code{print-completions-horizontally} to select how the -matches are displayed (@pxref{Readline Init File Syntax}). -@end deftypefun - -The following are implemented as macros, defined in @code{chardefs.h}. -Applications should refrain from using them. - -@deftypefun int _rl_uppercase_p (int c) -Return 1 if @var{c} is an uppercase alphabetic character. -@end deftypefun - -@deftypefun int _rl_lowercase_p (int c) -Return 1 if @var{c} is a lowercase alphabetic character. -@end deftypefun - -@deftypefun int _rl_digit_p (int c) -Return 1 if @var{c} is a numeric character. -@end deftypefun - -@deftypefun int _rl_to_upper (int c) -If @var{c} is a lowercase alphabetic character, return the corresponding -uppercase character. -@end deftypefun - -@deftypefun int _rl_to_lower (int c) -If @var{c} is an uppercase alphabetic character, return the corresponding -lowercase character. -@end deftypefun - -@deftypefun int _rl_digit_value (int c) -If @var{c} is a number, return the value it represents. -@end deftypefun - -@node Miscellaneous Functions -@subsection Miscellaneous Functions - -@deftypefun int rl_macro_bind (const char *keyseq, const char *macro, Keymap map) -Bind the key sequence @var{keyseq} to invoke the macro @var{macro}. -The binding is performed in @var{map}. When @var{keyseq} is invoked, the -@var{macro} will be inserted into the line. This function is deprecated; -use @code{rl_generic_bind()} instead. -@end deftypefun - -@deftypefun void rl_macro_dumper (int readable) -Print the key sequences bound to macros and their values, using -the current keymap, to @code{rl_outstream}. -If @var{readable} is non-zero, the list is formatted in such a way -that it can be made part of an @code{inputrc} file and re-read. -@end deftypefun - -@deftypefun int rl_variable_bind (const char *variable, const char *value) -Make the Readline variable @var{variable} have @var{value}. -This behaves as if the readline command -@samp{set @var{variable} @var{value}} had been executed in an @code{inputrc} -file (@pxref{Readline Init File Syntax}). -@end deftypefun - -@deftypefun void rl_variable_dumper (int readable) -Print the readline variable names and their current values -to @code{rl_outstream}. -If @var{readable} is non-zero, the list is formatted in such a way -that it can be made part of an @code{inputrc} file and re-read. -@end deftypefun - -@deftypefun int rl_set_paren_blink_timeout (int u) -Set the time interval (in microseconds) that Readline waits when showing -a balancing character when @code{blink-matching-paren} has been enabled. -@end deftypefun - -@deftypefun {char *} rl_get_termcap (const char *cap) -Retrieve the string value of the termcap capability @var{cap}. -Readline fetches the termcap entry for the current terminal name and -uses those capabilities to move around the screen line and perform other -terminal-specific operations, like erasing a line. Readline does not -use all of a terminal's capabilities, and this function will return -values for only those capabilities Readline uses. -@end deftypefun - -@node Alternate Interface -@subsection Alternate Interface - -An alternate interface is available to plain @code{readline()}. Some -applications need to interleave keyboard I/O with file, device, or -window system I/O, typically by using a main loop to @code{select()} -on various file descriptors. To accomodate this need, readline can -also be invoked as a `callback' function from an event loop. There -are functions available to make this easy. - -@deftypefun void rl_callback_handler_install (const char *prompt, rl_vcpfunc_t *lhandler) -Set up the terminal for readline I/O and display the initial -expanded value of @var{prompt}. Save the value of @var{lhandler} to -use as a function to call when a complete line of input has been entered. -The function takes the text of the line as an argument. -@end deftypefun - -@deftypefun void rl_callback_read_char (void) -Whenever an application determines that keyboard input is available, it -should call @code{rl_callback_read_char()}, which will read the next -character from the current input source. -If that character completes the line, @code{rl_callback_read_char} will -invoke the @var{lhandler} function saved by @code{rl_callback_handler_install} -to process the line. -Before calling the @var{lhandler} function, the terminal settings are -reset to the values they had before calling -@code{rl_callback_handler_install}. -If the @var{lhandler} function returns, -the terminal settings are modified for Readline's use again. -@code{EOF} is indicated by calling @var{lhandler} with a -@code{NULL} line. -@end deftypefun - -@deftypefun void rl_callback_handler_remove (void) -Restore the terminal to its initial state and remove the line handler. -This may be called from within a callback as well as independently. -If the @var{lhandler} installed by @code{rl_callback_handler_install} -does not exit the program, either this function or the function referred -to by the value of @code{rl_deprep_term_function} should be called before -the program exits to reset the terminal settings. -@end deftypefun - -@node A Readline Example -@subsection A Readline Example - -Here is a function which changes lowercase characters to their uppercase -equivalents, and uppercase characters to lowercase. If -this function was bound to @samp{M-c}, then typing @samp{M-c} would -change the case of the character under point. Typing @samp{M-1 0 M-c} -would change the case of the following 10 characters, leaving the cursor on -the last character changed. - -@example -/* Invert the case of the COUNT following characters. */ -int -invert_case_line (count, key) - int count, key; -@{ - register int start, end, i; - - start = rl_point; - - if (rl_point >= rl_end) - return (0); - - if (count < 0) - @{ - direction = -1; - count = -count; - @} - else - direction = 1; - - /* Find the end of the range to modify. */ - end = start + (count * direction); - - /* Force it to be within range. */ - if (end > rl_end) - end = rl_end; - else if (end < 0) - end = 0; - - if (start == end) - return (0); - - if (start > end) - @{ - int temp = start; - start = end; - end = temp; - @} - - /* Tell readline that we are modifying the line, - so it will save the undo information. */ - rl_modifying (start, end); - - for (i = start; i != end; i++) - @{ - if (_rl_uppercase_p (rl_line_buffer[i])) - rl_line_buffer[i] = _rl_to_lower (rl_line_buffer[i]); - else if (_rl_lowercase_p (rl_line_buffer[i])) - rl_line_buffer[i] = _rl_to_upper (rl_line_buffer[i]); - @} - /* Move point to on top of the last character changed. */ - rl_point = (direction == 1) ? end - 1 : start; - return (0); -@} -@end example - -@node Readline Signal Handling -@section Readline Signal Handling - -Signals are asynchronous events sent to a process by the Unix kernel, -sometimes on behalf of another process. They are intended to indicate -exceptional events, like a user pressing the interrupt key on his terminal, -or a network connection being broken. There is a class of signals that can -be sent to the process currently reading input from the keyboard. Since -Readline changes the terminal attributes when it is called, it needs to -perform special processing when such a signal is received in order to -restore the terminal to a sane state, or provide application writers with -functions to do so manually. - -Readline contains an internal signal handler that is installed for a -number of signals (@code{SIGINT}, @code{SIGQUIT}, @code{SIGTERM}, -@code{SIGALRM}, @code{SIGTSTP}, @code{SIGTTIN}, and @code{SIGTTOU}). -When one of these signals is received, the signal handler -will reset the terminal attributes to those that were in effect before -@code{readline()} was called, reset the signal handling to what it was -before @code{readline()} was called, and resend the signal to the calling -application. -If and when the calling application's signal handler returns, Readline -will reinitialize the terminal and continue to accept input. -When a @code{SIGINT} is received, the Readline signal handler performs -some additional work, which will cause any partially-entered line to be -aborted (see the description of @code{rl_free_line_state()} below). - -There is an additional Readline signal handler, for @code{SIGWINCH}, which -the kernel sends to a process whenever the terminal's size changes (for -example, if a user resizes an @code{xterm}). The Readline @code{SIGWINCH} -handler updates Readline's internal screen size information, and then calls -any @code{SIGWINCH} signal handler the calling application has installed. -Readline calls the application's @code{SIGWINCH} signal handler without -resetting the terminal to its original state. If the application's signal -handler does more than update its idea of the terminal size and return (for -example, a @code{longjmp} back to a main processing loop), it @emph{must} -call @code{rl_cleanup_after_signal()} (described below), to restore the -terminal state. - -Readline provides two variables that allow application writers to -control whether or not it will catch certain signals and act on them -when they are received. It is important that applications change the -values of these variables only when calling @code{readline()}, not in -a signal handler, so Readline's internal signal state is not corrupted. - -@deftypevar int rl_catch_signals -If this variable is non-zero, Readline will install signal handlers for -@code{SIGINT}, @code{SIGQUIT}, @code{SIGTERM}, @code{SIGALRM}, -@code{SIGTSTP}, @code{SIGTTIN}, and @code{SIGTTOU}. - -The default value of @code{rl_catch_signals} is 1. -@end deftypevar - -@deftypevar int rl_catch_sigwinch -If this variable is non-zero, Readline will install a signal handler for -@code{SIGWINCH}. - -The default value of @code{rl_catch_sigwinch} is 1. -@end deftypevar - -If an application does not wish to have Readline catch any signals, or -to handle signals other than those Readline catches (@code{SIGHUP}, -for example), -Readline provides convenience functions to do the necessary terminal -and internal state cleanup upon receipt of a signal. - -@deftypefun void rl_cleanup_after_signal (void) -This function will reset the state of the terminal to what it was before -@code{readline()} was called, and remove the Readline signal handlers for -all signals, depending on the values of @code{rl_catch_signals} and -@code{rl_catch_sigwinch}. -@end deftypefun - -@deftypefun void rl_free_line_state (void) -This will free any partial state associated with the current input line -(undo information, any partial history entry, any partially-entered -keyboard macro, and any partially-entered numeric argument). This -should be called before @code{rl_cleanup_after_signal()}. The -Readline signal handler for @code{SIGINT} calls this to abort the -current input line. -@end deftypefun - -@deftypefun void rl_reset_after_signal (void) -This will reinitialize the terminal and reinstall any Readline signal -handlers, depending on the values of @code{rl_catch_signals} and -@code{rl_catch_sigwinch}. -@end deftypefun - -If an application does not wish Readline to catch @code{SIGWINCH}, it may -call @code{rl_resize_terminal()} or @code{rl_set_screen_size()} to force -Readline to update its idea of the terminal size when a @code{SIGWINCH} -is received. - -@deftypefun void rl_resize_terminal (void) -Update Readline's internal screen size by reading values from the kernel. -@end deftypefun - -@deftypefun void rl_set_screen_size (int rows, int cols) -Set Readline's idea of the terminal size to @var{rows} rows and -@var{cols} columns. -@end deftypefun - -If an application does not want to install a @code{SIGWINCH} handler, but -is still interested in the screen dimensions, Readline's idea of the screen -size may be queried. - -@deftypefun void rl_get_screen_size (int *rows, int *cols) -Return Readline's idea of the terminal's size in the -variables pointed to by the arguments. -@end deftypefun - -The following functions install and remove Readline's signal handlers. - -@deftypefun int rl_set_signals (void) -Install Readline's signal handler for @code{SIGINT}, @code{SIGQUIT}, -@code{SIGTERM}, @code{SIGALRM}, @code{SIGTSTP}, @code{SIGTTIN}, -@code{SIGTTOU}, and @code{SIGWINCH}, depending on the values of -@code{rl_catch_signals} and @code{rl_catch_sigwinch}. -@end deftypefun - -@deftypefun int rl_clear_signals (void) -Remove all of the Readline signal handlers installed by -@code{rl_set_signals()}. -@end deftypefun - -@node Custom Completers -@section Custom Completers - -Typically, a program that reads commands from the user has a way of -disambiguating commands and data. If your program is one of these, then -it can provide completion for commands, data, or both. -The following sections describe how your program and Readline -cooperate to provide this service. - -@menu -* How Completing Works:: The logic used to do completion. -* Completion Functions:: Functions provided by Readline. -* Completion Variables:: Variables which control completion. -* A Short Completion Example:: An example of writing completer subroutines. -@end menu - -@node How Completing Works -@subsection How Completing Works - -In order to complete some text, the full list of possible completions -must be available. That is, it is not possible to accurately -expand a partial word without knowing all of the possible words -which make sense in that context. The Readline library provides -the user interface to completion, and two of the most common -completion functions: filename and username. For completing other types -of text, you must write your own completion function. This section -describes exactly what such functions must do, and provides an example. - -There are three major functions used to perform completion: - -@enumerate -@item -The user-interface function @code{rl_complete()}. This function is -called with the same arguments as other bindable Readline functions: -@var{count} and @var{invoking_key}. -It isolates the word to be completed and calls -@code{rl_completion_matches()} to generate a list of possible completions. -It then either lists the possible completions, inserts the possible -completions, or actually performs the -completion, depending on which behavior is desired. - -@item -The internal function @code{rl_completion_matches()} uses an -application-supplied @dfn{generator} function to generate the list of -possible matches, and then returns the array of these matches. -The caller should place the address of its generator function in -@code{rl_completion_entry_function}. - -@item -The generator function is called repeatedly from -@code{rl_completion_matches()}, returning a string each time. The -arguments to the generator function are @var{text} and @var{state}. -@var{text} is the partial word to be completed. @var{state} is zero the -first time the function is called, allowing the generator to perform -any necessary initialization, and a positive non-zero integer for -each subsequent call. The generator function returns -@code{(char *)NULL} to inform @code{rl_completion_matches()} that there are -no more possibilities left. Usually the generator function computes the -list of possible completions when @var{state} is zero, and returns them -one at a time on subsequent calls. Each string the generator function -returns as a match must be allocated with @code{malloc()}; Readline -frees the strings when it has finished with them. - -@end enumerate - -@deftypefun int rl_complete (int ignore, int invoking_key) -Complete the word at or before point. You have supplied the function -that does the initial simple matching selection algorithm (see -@code{rl_completion_matches()}). The default is to do filename completion. -@end deftypefun - -@deftypevar {rl_compentry_func_t *} rl_completion_entry_function -This is a pointer to the generator function for -@code{rl_completion_matches()}. -If the value of @code{rl_completion_entry_function} is -@code{NULL} then the default filename generator -function, @code{rl_filename_completion_function()}, is used. -@end deftypevar - -@node Completion Functions -@subsection Completion Functions - -Here is the complete list of callable completion functions present in -Readline. - -@deftypefun int rl_complete_internal (int what_to_do) -Complete the word at or before point. @var{what_to_do} says what to do -with the completion. A value of @samp{?} means list the possible -completions. @samp{TAB} means do standard completion. @samp{*} means -insert all of the possible completions. @samp{!} means to display -all of the possible completions, if there is more than one, as well as -performing partial completion. -@end deftypefun - -@deftypefun int rl_complete (int ignore, int invoking_key) -Complete the word at or before point. You have supplied the function -that does the initial simple matching selection algorithm (see -@code{rl_completion_matches()} and @code{rl_completion_entry_function}). -The default is to do filename -completion. This calls @code{rl_complete_internal()} with an -argument depending on @var{invoking_key}. -@end deftypefun - -@deftypefun int rl_possible_completions (int count, int invoking_key) -List the possible completions. See description of @code{rl_complete -()}. This calls @code{rl_complete_internal()} with an argument of -@samp{?}. -@end deftypefun - -@deftypefun int rl_insert_completions (int count, int invoking_key) -Insert the list of possible completions into the line, deleting the -partially-completed word. See description of @code{rl_complete()}. -This calls @code{rl_complete_internal()} with an argument of @samp{*}. -@end deftypefun - -@deftypefun int rl_completion_mode (rl_command_func_t *cfunc) -Returns the apppriate value to pass to @code{rl_complete_internal()} -depending on whether @var{cfunc} was called twice in succession and -the value of the @code{show-all-if-ambiguous} variable. -Application-specific completion functions may use this function to present -the same interface as @code{rl_complete()}. -@end deftypefun - -@deftypefun {char **} rl_completion_matches (const char *text, rl_compentry_func_t *entry_func) -Returns an array of strings which is a list of completions for -@var{text}. If there are no completions, returns @code{NULL}. -The first entry in the returned array is the substitution for @var{text}. -The remaining entries are the possible completions. The array is -terminated with a @code{NULL} pointer. - -@var{entry_func} is a function of two args, and returns a -@code{char *}. The first argument is @var{text}. The second is a -state argument; it is zero on the first call, and non-zero on subsequent -calls. @var{entry_func} returns a @code{NULL} pointer to the caller -when there are no more matches. -@end deftypefun - -@deftypefun {char *} rl_filename_completion_function (const char *text, int state) -A generator function for filename completion in the general case. -@var{text} is a partial filename. -The Bash source is a useful reference for writing custom -completion functions (the Bash completion functions call this and other -Readline functions). -@end deftypefun - -@deftypefun {char *} rl_username_completion_function (const char *text, int state) -A completion generator for usernames. @var{text} contains a partial -username preceded by a random character (usually @samp{~}). As with all -completion generators, @var{state} is zero on the first call and non-zero -for subsequent calls. -@end deftypefun - -@node Completion Variables -@subsection Completion Variables - -@deftypevar {rl_compentry_func_t *} rl_completion_entry_function -A pointer to the generator function for @code{rl_completion_matches()}. -@code{NULL} means to use @code{rl_filename_completion_function()}, the default -filename completer. -@end deftypevar - -@deftypevar {rl_completion_func_t *} rl_attempted_completion_function -A pointer to an alternative function to create matches. -The function is called with @var{text}, @var{start}, and @var{end}. -@var{start} and @var{end} are indices in @code{rl_line_buffer} defining -the boundaries of @var{text}, which is a character string. -If this function exists and returns @code{NULL}, or if this variable is -set to @code{NULL}, then @code{rl_complete()} will call the value of -@code{rl_completion_entry_function} to generate matches, otherwise the -array of strings returned will be used. -If this function sets the @code{rl_attempted_completion_over} -variable to a non-zero value, Readline will not perform its default -completion even if this function returns no matches. -@end deftypevar - -@deftypevar {rl_quote_func_t *} rl_filename_quoting_function -A pointer to a function that will quote a filename in an -application-specific fashion. This is called if filename completion is being -attempted and one of the characters in @code{rl_filename_quote_characters} -appears in a completed filename. The function is called with -@var{text}, @var{match_type}, and @var{quote_pointer}. The @var{text} -is the filename to be quoted. The @var{match_type} is either -@code{SINGLE_MATCH}, if there is only one completion match, or -@code{MULT_MATCH}. Some functions use this to decide whether or not to -insert a closing quote character. The @var{quote_pointer} is a pointer -to any opening quote character the user typed. Some functions choose -to reset this character. -@end deftypevar - -@deftypevar {rl_dequote_func_t *} rl_filename_dequoting_function -A pointer to a function that will remove application-specific quoting -characters from a filename before completion is attempted, so those -characters do not interfere with matching the text against names in -the filesystem. It is called with @var{text}, the text of the word -to be dequoted, and @var{quote_char}, which is the quoting character -that delimits the filename (usually @samp{'} or @samp{"}). If -@var{quote_char} is zero, the filename was not in an embedded string. -@end deftypevar - -@deftypevar {rl_linebuf_func_t *} rl_char_is_quoted_p -A pointer to a function to call that determines whether or not a specific -character in the line buffer is quoted, according to whatever quoting -mechanism the program calling Readline uses. The function is called with -two arguments: @var{text}, the text of the line, and @var{index}, the -index of the character in the line. It is used to decide whether a -character found in @code{rl_completer_word_break_characters} should be -used to break words for the completer. -@end deftypevar - -@deftypevar {rl_compignore_func_t *} rl_ignore_some_completions_function -This function, if defined, is called by the completer when real filename -completion is done, after all the matching names have been generated. -It is passed a @code{NULL} terminated array of matches. -The first element (@code{matches[0]}) is the -maximal substring common to all matches. This function can -re-arrange the list of matches as required, but each element deleted -from the array must be freed. -@end deftypevar - -@deftypevar {rl_icppfunc_t *} rl_directory_completion_hook -This function, if defined, is allowed to modify the directory portion -of filenames Readline completes. It is called with the address of a -string (the current directory name) as an argument, and may modify that string. -If the string is replaced with a new string, the old value should be freed. -Any modified directory name should have a trailing slash. -The modified value will be displayed as part of the completion, replacing -the directory portion of the pathname the user typed. -It returns an integer that should be non-zero if the function modifies -its directory argument. -It could be used to expand symbolic links or shell variables in pathnames. -@end deftypevar - -@deftypevar {rl_compdisp_func_t *} rl_completion_display_matches_hook -If non-zero, then this is the address of a function to call when -completing a word would normally display the list of possible matches. -This function is called in lieu of Readline displaying the list. -It takes three arguments: -(@code{char **}@var{matches}, @code{int} @var{num_matches}, @code{int} @var{max_length}) -where @var{matches} is the array of matching strings, -@var{num_matches} is the number of strings in that array, and -@var{max_length} is the length of the longest string in that array. -Readline provides a convenience function, @code{rl_display_match_list}, -that takes care of doing the display to Readline's output stream. That -function may be called from this hook. -@end deftypevar - -@deftypevar {const char *} rl_basic_word_break_characters -The basic list of characters that signal a break between words for the -completer routine. The default value of this variable is the characters -which break words for completion in Bash: -@code{" \t\n\"\\'`@@$><=;|&@{("}. -@end deftypevar - -@deftypevar {const char *} rl_basic_quote_characters -A list of quote characters which can cause a word break. -@end deftypevar - -@deftypevar {const char *} rl_completer_word_break_characters -The list of characters that signal a break between words for -@code{rl_complete_internal()}. The default list is the value of -@code{rl_basic_word_break_characters}. -@end deftypevar - -@deftypevar {const char *} rl_completer_quote_characters -A list of characters which can be used to quote a substring of the line. -Completion occurs on the entire substring, and within the substring -@code{rl_completer_word_break_characters} are treated as any other character, -unless they also appear within this list. -@end deftypevar - -@deftypevar {const char *} rl_filename_quote_characters -A list of characters that cause a filename to be quoted by the completer -when they appear in a completed filename. The default is the null string. -@end deftypevar - -@deftypevar {const char *} rl_special_prefixes -The list of characters that are word break characters, but should be -left in @var{text} when it is passed to the completion function. -Programs can use this to help determine what kind of completing to do. -For instance, Bash sets this variable to "$@@" so that it can complete -shell variables and hostnames. -@end deftypevar - -@deftypevar int rl_completion_query_items -Up to this many items will be displayed in response to a -possible-completions call. After that, we ask the user if she is sure -she wants to see them all. The default value is 100. -@end deftypevar - -@deftypevar {int} rl_completion_append_character -When a single completion alternative matches at the end of the command -line, this character is appended to the inserted completion text. The -default is a space character (@samp{ }). Setting this to the null -character (@samp{\0}) prevents anything being appended automatically. -This can be changed in custom completion functions to -provide the ``most sensible word separator character'' according to -an application-specific command line syntax specification. -@end deftypevar - -@deftypevar int rl_completion_suppress_append -If non-zero, @var{rl_completion_append_character} is not appended to -matches at the end of the command line, as described above. It is -set to 0 before any application-specific completion function is called. -@end deftypevar - -@deftypevar int rl_completion_mark_symlink_dirs -If non-zero, a slash will be appended to completed filenames that are -symbolic links to directory names, subject to the value of the -user-settable @var{mark-directories} variable. -This variable exists so that application completion functions can -override the user's global preference (set via the -@var{mark-symlinked-directories} Readline variable) if appropriate. -This variable is set to the user's preference before any -application completion function is called, so unless that function -modifies the value, the user's preferences are honored. -@end deftypevar - -@deftypevar int rl_ignore_completion_duplicates -If non-zero, then duplicates in the matches are removed. -The default is 1. -@end deftypevar - -@deftypevar int rl_filename_completion_desired -Non-zero means that the results of the matches are to be treated as -filenames. This is @emph{always} zero on entry, and can only be changed -within a completion entry generator function. If it is set to a non-zero -value, directory names have a slash appended and Readline attempts to -quote completed filenames if they contain any characters in -@code{rl_filename_quote_characters} and @code{rl_filename_quoting_desired} -is set to a non-zero value. -@end deftypevar - -@deftypevar int rl_filename_quoting_desired -Non-zero means that the results of the matches are to be quoted using -double quotes (or an application-specific quoting mechanism) if the -completed filename contains any characters in -@code{rl_filename_quote_chars}. This is @emph{always} non-zero -on entry, and can only be changed within a completion entry generator -function. The quoting is effected via a call to the function pointed to -by @code{rl_filename_quoting_function}. -@end deftypevar - -@deftypevar int rl_attempted_completion_over -If an application-specific completion function assigned to -@code{rl_attempted_completion_function} sets this variable to a non-zero -value, Readline will not perform its default filename completion even -if the application's completion function returns no matches. -It should be set only by an application's completion function. -@end deftypevar - -@deftypevar int rl_completion_type -Set to a character describing the type of completion Readline is currently -attempting; see the description of @code{rl_complete_internal()} -(@pxref{Completion Functions}) for the list of characters. -@end deftypevar - -@deftypevar int rl_inhibit_completion -If this variable is non-zero, completion is inhibited. The completion -character will be inserted as any other bound to @code{self-insert}. -@end deftypevar - -@node A Short Completion Example -@subsection A Short Completion Example - -Here is a small application demonstrating the use of the GNU Readline -library. It is called @code{fileman}, and the source code resides in -@file{examples/fileman.c}. This sample application provides -completion of command names, line editing features, and access to the -history list. - -@page -@smallexample -/* fileman.c -- A tiny application which demonstrates how to use the - GNU Readline library. This application interactively allows users - to manipulate files and their modes. */ - -#include <stdio.h> -#include <sys/types.h> -#include <sys/file.h> -#include <sys/stat.h> -#include <sys/errno.h> - -#include <readline/readline.h> -#include <readline/history.h> - -extern char *xmalloc (); - -/* The names of functions that actually do the manipulation. */ -int com_list __P((char *)); -int com_view __P((char *)); -int com_rename __P((char *)); -int com_stat __P((char *)); -int com_pwd __P((char *)); -int com_delete __P((char *)); -int com_help __P((char *)); -int com_cd __P((char *)); -int com_quit __P((char *)); - -/* A structure which contains information on the commands this program - can understand. */ - -typedef struct @{ - char *name; /* User printable name of the function. */ - rl_icpfunc_t *func; /* Function to call to do the job. */ - char *doc; /* Documentation for this function. */ -@} COMMAND; - -COMMAND commands[] = @{ - @{ "cd", com_cd, "Change to directory DIR" @}, - @{ "delete", com_delete, "Delete FILE" @}, - @{ "help", com_help, "Display this text" @}, - @{ "?", com_help, "Synonym for `help'" @}, - @{ "list", com_list, "List files in DIR" @}, - @{ "ls", com_list, "Synonym for `list'" @}, - @{ "pwd", com_pwd, "Print the current working directory" @}, - @{ "quit", com_quit, "Quit using Fileman" @}, - @{ "rename", com_rename, "Rename FILE to NEWNAME" @}, - @{ "stat", com_stat, "Print out statistics on FILE" @}, - @{ "view", com_view, "View the contents of FILE" @}, - @{ (char *)NULL, (rl_icpfunc_t *)NULL, (char *)NULL @} -@}; - -/* Forward declarations. */ -char *stripwhite (); -COMMAND *find_command (); - -/* The name of this program, as taken from argv[0]. */ -char *progname; - -/* When non-zero, this means the user is done using this program. */ -int done; - -char * -dupstr (s) - int s; -@{ - char *r; - - r = xmalloc (strlen (s) + 1); - strcpy (r, s); - return (r); -@} - -main (argc, argv) - int argc; - char **argv; -@{ - char *line, *s; - - progname = argv[0]; - - initialize_readline (); /* Bind our completer. */ - - /* Loop reading and executing lines until the user quits. */ - for ( ; done == 0; ) - @{ - line = readline ("FileMan: "); - - if (!line) - break; - - /* Remove leading and trailing whitespace from the line. - Then, if there is anything left, add it to the history list - and execute it. */ - s = stripwhite (line); - - if (*s) - @{ - add_history (s); - execute_line (s); - @} - - free (line); - @} - exit (0); -@} - -/* Execute a command line. */ -int -execute_line (line) - char *line; -@{ - register int i; - COMMAND *command; - char *word; - - /* Isolate the command word. */ - i = 0; - while (line[i] && whitespace (line[i])) - i++; - word = line + i; - - while (line[i] && !whitespace (line[i])) - i++; - - if (line[i]) - line[i++] = '\0'; - - command = find_command (word); - - if (!command) - @{ - fprintf (stderr, "%s: No such command for FileMan.\n", word); - return (-1); - @} - - /* Get argument to command, if any. */ - while (whitespace (line[i])) - i++; - - word = line + i; - - /* Call the function. */ - return ((*(command->func)) (word)); -@} - -/* Look up NAME as the name of a command, and return a pointer to that - command. Return a NULL pointer if NAME isn't a command name. */ -COMMAND * -find_command (name) - char *name; -@{ - register int i; - - for (i = 0; commands[i].name; i++) - if (strcmp (name, commands[i].name) == 0) - return (&commands[i]); - - return ((COMMAND *)NULL); -@} - -/* Strip whitespace from the start and end of STRING. Return a pointer - into STRING. */ -char * -stripwhite (string) - char *string; -@{ - register char *s, *t; - - for (s = string; whitespace (*s); s++) - ; - - if (*s == 0) - return (s); - - t = s + strlen (s) - 1; - while (t > s && whitespace (*t)) - t--; - *++t = '\0'; - - return s; -@} - -/* **************************************************************** */ -/* */ -/* Interface to Readline Completion */ -/* */ -/* **************************************************************** */ - -char *command_generator __P((const char *, int)); -char **fileman_completion __P((const char *, int, int)); - -/* Tell the GNU Readline library how to complete. We want to try to - complete on command names if this is the first word in the line, or - on filenames if not. */ -initialize_readline () -@{ - /* Allow conditional parsing of the ~/.inputrc file. */ - rl_readline_name = "FileMan"; - - /* Tell the completer that we want a crack first. */ - rl_attempted_completion_function = fileman_completion; -@} - -/* Attempt to complete on the contents of TEXT. START and END - bound the region of rl_line_buffer that contains the word to - complete. TEXT is the word to complete. We can use the entire - contents of rl_line_buffer in case we want to do some simple - parsing. Returnthe array of matches, or NULL if there aren't any. */ -char ** -fileman_completion (text, start, end) - const char *text; - int start, end; -@{ - char **matches; - - matches = (char **)NULL; - - /* If this word is at the start of the line, then it is a command - to complete. Otherwise it is the name of a file in the current - directory. */ - if (start == 0) - matches = rl_completion_matches (text, command_generator); - - return (matches); -@} - -/* Generator function for command completion. STATE lets us - know whether to start from scratch; without any state - (i.e. STATE == 0), then we start at the top of the list. */ -char * -command_generator (text, state) - const char *text; - int state; -@{ - static int list_index, len; - char *name; - - /* If this is a new word to complete, initialize now. This - includes saving the length of TEXT for efficiency, and - initializing the index variable to 0. */ - if (!state) - @{ - list_index = 0; - len = strlen (text); - @} - - /* Return the next name which partially matches from the - command list. */ - while (name = commands[list_index].name) - @{ - list_index++; - - if (strncmp (name, text, len) == 0) - return (dupstr(name)); - @} - - /* If no names matched, then return NULL. */ - return ((char *)NULL); -@} - -/* **************************************************************** */ -/* */ -/* FileMan Commands */ -/* */ -/* **************************************************************** */ - -/* String to pass to system (). This is for the LIST, VIEW and RENAME - commands. */ -static char syscom[1024]; - -/* List the file(s) named in arg. */ -com_list (arg) - char *arg; -@{ - if (!arg) - arg = ""; - - sprintf (syscom, "ls -FClg %s", arg); - return (system (syscom)); -@} - -com_view (arg) - char *arg; -@{ - if (!valid_argument ("view", arg)) - return 1; - - sprintf (syscom, "more %s", arg); - return (system (syscom)); -@} - -com_rename (arg) - char *arg; -@{ - too_dangerous ("rename"); - return (1); -@} - -com_stat (arg) - char *arg; -@{ - struct stat finfo; - - if (!valid_argument ("stat", arg)) - return (1); - - if (stat (arg, &finfo) == -1) - @{ - perror (arg); - return (1); - @} - - printf ("Statistics for `%s':\n", arg); - - printf ("%s has %d link%s, and is %d byte%s in length.\n", arg, - finfo.st_nlink, - (finfo.st_nlink == 1) ? "" : "s", - finfo.st_size, - (finfo.st_size == 1) ? "" : "s"); - printf ("Inode Last Change at: %s", ctime (&finfo.st_ctime)); - printf (" Last access at: %s", ctime (&finfo.st_atime)); - printf (" Last modified at: %s", ctime (&finfo.st_mtime)); - return (0); -@} - -com_delete (arg) - char *arg; -@{ - too_dangerous ("delete"); - return (1); -@} - -/* Print out help for ARG, or for all of the commands if ARG is - not present. */ -com_help (arg) - char *arg; -@{ - register int i; - int printed = 0; - - for (i = 0; commands[i].name; i++) - @{ - if (!*arg || (strcmp (arg, commands[i].name) == 0)) - @{ - printf ("%s\t\t%s.\n", commands[i].name, commands[i].doc); - printed++; - @} - @} - - if (!printed) - @{ - printf ("No commands match `%s'. Possibilties are:\n", arg); - - for (i = 0; commands[i].name; i++) - @{ - /* Print in six columns. */ - if (printed == 6) - @{ - printed = 0; - printf ("\n"); - @} - - printf ("%s\t", commands[i].name); - printed++; - @} - - if (printed) - printf ("\n"); - @} - return (0); -@} - -/* Change to the directory ARG. */ -com_cd (arg) - char *arg; -@{ - if (chdir (arg) == -1) - @{ - perror (arg); - return 1; - @} - - com_pwd (""); - return (0); -@} - -/* Print out the current working directory. */ -com_pwd (ignore) - char *ignore; -@{ - char dir[1024], *s; - - s = getcwd (dir, sizeof(dir) - 1); - if (s == 0) - @{ - printf ("Error getting pwd: %s\n", dir); - return 1; - @} - - printf ("Current directory is %s\n", dir); - return 0; -@} - -/* The user wishes to quit using this program. Just set DONE - non-zero. */ -com_quit (arg) - char *arg; -@{ - done = 1; - return (0); -@} - -/* Function which tells you that you can't do this. */ -too_dangerous (caller) - char *caller; -@{ - fprintf (stderr, - "%s: Too dangerous for me to distribute.\n" - caller); - fprintf (stderr, "Write it yourself.\n"); -@} - -/* Return non-zero if ARG is a valid argument for CALLER, - else print an error message and return zero. */ -int -valid_argument (caller, arg) - char *caller, *arg; -@{ - if (!arg || !*arg) - @{ - fprintf (stderr, "%s: Argument required.\n", caller); - return (0); - @} - - return (1); -@} -@end smallexample diff --git a/readline/doc/rluser.texinfo b/readline/doc/rluser.texinfo deleted file mode 100644 index 94f851e..0000000 --- a/readline/doc/rluser.texinfo +++ /dev/null @@ -1,1796 +0,0 @@ -@comment %**start of header (This is for running Texinfo on a region.) -@setfilename rluser.info -@comment %**end of header (This is for running Texinfo on a region.) -@setchapternewpage odd - -@ignore -This file documents the end user interface to the GNU command line -editing features. It is to be an appendix to manuals for programs which -use these features. There is a document entitled "readline.texinfo" -which contains both end-user and programmer documentation for the -GNU Readline Library. - -Copyright (C) 1988-2002 Free Software Foundation, Inc. - -Authored by Brian Fox and Chet Ramey. - -Permission is granted to process this file through Tex and print the -results, provided the printed document carries copying permission notice -identical to this one except for the removal of this paragraph (this -paragraph not being relevant to the printed manual). - -Permission is granted to make and distribute verbatim copies of this manual -provided the copyright notice and this permission notice are preserved on -all copies. - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that the -GNU Copyright statement is available to the distributee, and provided that -the entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. -@end ignore - -@comment If you are including this manual as an appendix, then set the -@comment variable readline-appendix. - -@ifclear BashFeatures -@defcodeindex bt -@end ifclear - -@node Command Line Editing -@chapter Command Line Editing - -This chapter describes the basic features of the @sc{gnu} -command line editing interface. -@ifset BashFeatures -Command line editing is provided by the Readline library, which is -used by several different programs, including Bash. -@end ifset - -@menu -* Introduction and Notation:: Notation used in this text. -* Readline Interaction:: The minimum set of commands for editing a line. -* Readline Init File:: Customizing Readline from a user's view. -* Bindable Readline Commands:: A description of most of the Readline commands - available for binding -* Readline vi Mode:: A short description of how to make Readline - behave like the vi editor. -@ifset BashFeatures -* Programmable Completion:: How to specify the possible completions for - a specific command. -* Programmable Completion Builtins:: Builtin commands to specify how to - complete arguments for a particular command. -@end ifset -@end menu - -@node Introduction and Notation -@section Introduction to Line Editing - -The following paragraphs describe the notation used to represent -keystrokes. - -The text @kbd{C-k} is read as `Control-K' and describes the character -produced when the @key{k} key is pressed while the Control key -is depressed. - -The text @kbd{M-k} is read as `Meta-K' and describes the character -produced when the Meta key (if you have one) is depressed, and the @key{k} -key is pressed. -The Meta key is labeled @key{ALT} on many keyboards. -On keyboards with two keys labeled @key{ALT} (usually to either side of -the space bar), the @key{ALT} on the left side is generally set to -work as a Meta key. -The @key{ALT} key on the right may also be configured to work as a -Meta key or may be configured as some other modifier, such as a -Compose key for typing accented characters. - -If you do not have a Meta or @key{ALT} key, or another key working as -a Meta key, the identical keystroke can be generated by typing @key{ESC} -@emph{first}, and then typing @key{k}. -Either process is known as @dfn{metafying} the @key{k} key. - -The text @kbd{M-C-k} is read as `Meta-Control-k' and describes the -character produced by @dfn{metafying} @kbd{C-k}. - -In addition, several keys have their own names. Specifically, -@key{DEL}, @key{ESC}, @key{LFD}, @key{SPC}, @key{RET}, and @key{TAB} all -stand for themselves when seen in this text, or in an init file -(@pxref{Readline Init File}). -If your keyboard lacks a @key{LFD} key, typing @key{C-j} will -produce the desired character. -The @key{RET} key may be labeled @key{Return} or @key{Enter} on -some keyboards. - -@node Readline Interaction -@section Readline Interaction -@cindex interaction, readline - -Often during an interactive session you type in a long line of text, -only to notice that the first word on the line is misspelled. The -Readline library gives you a set of commands for manipulating the text -as you type it in, allowing you to just fix your typo, and not forcing -you to retype the majority of the line. Using these editing commands, -you move the cursor to the place that needs correction, and delete or -insert the text of the corrections. Then, when you are satisfied with -the line, you simply press @key{RET}. You do not have to be at the -end of the line to press @key{RET}; the entire line is accepted -regardless of the location of the cursor within the line. - -@menu -* Readline Bare Essentials:: The least you need to know about Readline. -* Readline Movement Commands:: Moving about the input line. -* Readline Killing Commands:: How to delete text, and how to get it back! -* Readline Arguments:: Giving numeric arguments to commands. -* Searching:: Searching through previous lines. -@end menu - -@node Readline Bare Essentials -@subsection Readline Bare Essentials -@cindex notation, readline -@cindex command editing -@cindex editing command lines - -In order to enter characters into the line, simply type them. The typed -character appears where the cursor was, and then the cursor moves one -space to the right. If you mistype a character, you can use your -erase character to back up and delete the mistyped character. - -Sometimes you may mistype a character, and -not notice the error until you have typed several other characters. In -that case, you can type @kbd{C-b} to move the cursor to the left, and then -correct your mistake. Afterwards, you can move the cursor to the right -with @kbd{C-f}. - -When you add text in the middle of a line, you will notice that characters -to the right of the cursor are `pushed over' to make room for the text -that you have inserted. Likewise, when you delete text behind the cursor, -characters to the right of the cursor are `pulled back' to fill in the -blank space created by the removal of the text. A list of the bare -essentials for editing the text of an input line follows. - -@table @asis -@item @kbd{C-b} -Move back one character. -@item @kbd{C-f} -Move forward one character. -@item @key{DEL} or @key{Backspace} -Delete the character to the left of the cursor. -@item @kbd{C-d} -Delete the character underneath the cursor. -@item @w{Printing characters} -Insert the character into the line at the cursor. -@item @kbd{C-_} or @kbd{C-x C-u} -Undo the last editing command. You can undo all the way back to an -empty line. -@end table - -@noindent -(Depending on your configuration, the @key{Backspace} key be set to -delete the character to the left of the cursor and the @key{DEL} key set -to delete the character underneath the cursor, like @kbd{C-d}, rather -than the character to the left of the cursor.) - -@node Readline Movement Commands -@subsection Readline Movement Commands - - -The above table describes the most basic keystrokes that you need -in order to do editing of the input line. For your convenience, many -other commands have been added in addition to @kbd{C-b}, @kbd{C-f}, -@kbd{C-d}, and @key{DEL}. Here are some commands for moving more rapidly -about the line. - -@table @kbd -@item C-a -Move to the start of the line. -@item C-e -Move to the end of the line. -@item M-f -Move forward a word, where a word is composed of letters and digits. -@item M-b -Move backward a word. -@item C-l -Clear the screen, reprinting the current line at the top. -@end table - -Notice how @kbd{C-f} moves forward a character, while @kbd{M-f} moves -forward a word. It is a loose convention that control keystrokes -operate on characters while meta keystrokes operate on words. - -@node Readline Killing Commands -@subsection Readline Killing Commands - -@cindex killing text -@cindex yanking text - -@dfn{Killing} text means to delete the text from the line, but to save -it away for later use, usually by @dfn{yanking} (re-inserting) -it back into the line. -(`Cut' and `paste' are more recent jargon for `kill' and `yank'.) - -If the description for a command says that it `kills' text, then you can -be sure that you can get the text back in a different (or the same) -place later. - -When you use a kill command, the text is saved in a @dfn{kill-ring}. -Any number of consecutive kills save all of the killed text together, so -that when you yank it back, you get it all. The kill -ring is not line specific; the text that you killed on a previously -typed line is available to be yanked back later, when you are typing -another line. -@cindex kill ring - -Here is the list of commands for killing text. - -@table @kbd -@item C-k -Kill the text from the current cursor position to the end of the line. - -@item M-d -Kill from the cursor to the end of the current word, or, if between -words, to the end of the next word. -Word boundaries are the same as those used by @kbd{M-f}. - -@item M-@key{DEL} -Kill from the cursor the start of the current word, or, if between -words, to the start of the previous word. -Word boundaries are the same as those used by @kbd{M-b}. - -@item C-w -Kill from the cursor to the previous whitespace. This is different than -@kbd{M-@key{DEL}} because the word boundaries differ. - -@end table - -Here is how to @dfn{yank} the text back into the line. Yanking -means to copy the most-recently-killed text from the kill buffer. - -@table @kbd -@item C-y -Yank the most recently killed text back into the buffer at the cursor. - -@item M-y -Rotate the kill-ring, and yank the new top. You can only do this if -the prior command is @kbd{C-y} or @kbd{M-y}. -@end table - -@node Readline Arguments -@subsection Readline Arguments - -You can pass numeric arguments to Readline commands. Sometimes the -argument acts as a repeat count, other times it is the @i{sign} of the -argument that is significant. If you pass a negative argument to a -command which normally acts in a forward direction, that command will -act in a backward direction. For example, to kill text back to the -start of the line, you might type @samp{M-- C-k}. - -The general way to pass numeric arguments to a command is to type meta -digits before the command. If the first `digit' typed is a minus -sign (@samp{-}), then the sign of the argument will be negative. Once -you have typed one meta digit to get the argument started, you can type -the remainder of the digits, and then the command. For example, to give -the @kbd{C-d} command an argument of 10, you could type @samp{M-1 0 C-d}, -which will delete the next ten characters on the input line. - -@node Searching -@subsection Searching for Commands in the History - -Readline provides commands for searching through the command history -@ifset BashFeatures -(@pxref{Bash History Facilities}) -@end ifset -for lines containing a specified string. -There are two search modes: @dfn{incremental} and @dfn{non-incremental}. - -Incremental searches begin before the user has finished typing the -search string. -As each character of the search string is typed, Readline displays -the next entry from the history matching the string typed so far. -An incremental search requires only as many characters as needed to -find the desired history entry. -To search backward in the history for a particular string, type -@kbd{C-r}. Typing @kbd{C-s} searches forward through the history. -The characters present in the value of the @code{isearch-terminators} variable -are used to terminate an incremental search. -If that variable has not been assigned a value, the @key{ESC} and -@kbd{C-J} characters will terminate an incremental search. -@kbd{C-g} will abort an incremental search and restore the original line. -When the search is terminated, the history entry containing the -search string becomes the current line. - -To find other matching entries in the history list, type @kbd{C-r} or -@kbd{C-s} as appropriate. -This will search backward or forward in the history for the next -entry matching the search string typed so far. -Any other key sequence bound to a Readline command will terminate -the search and execute that command. -For instance, a @key{RET} will terminate the search and accept -the line, thereby executing the command from the history list. -A movement command will terminate the search, make the last line found -the current line, and begin editing. - -Readline remembers the last incremental search string. If two -@kbd{C-r}s are typed without any intervening characters defining a new -search string, any remembered search string is used. - -Non-incremental searches read the entire search string before starting -to search for matching history lines. The search string may be -typed by the user or be part of the contents of the current line. - -@node Readline Init File -@section Readline Init File -@cindex initialization file, readline - -Although the Readline library comes with a set of Emacs-like -keybindings installed by default, it is possible to use a different set -of keybindings. -Any user can customize programs that use Readline by putting -commands in an @dfn{inputrc} file, conventionally in his home directory. -The name of this -@ifset BashFeatures -file is taken from the value of the shell variable @env{INPUTRC}. If -@end ifset -@ifclear BashFeatures -file is taken from the value of the environment variable @env{INPUTRC}. If -@end ifclear -that variable is unset, the default is @file{~/.inputrc}. - -When a program which uses the Readline library starts up, the -init file is read, and the key bindings are set. - -In addition, the @code{C-x C-r} command re-reads this init file, thus -incorporating any changes that you might have made to it. - -@menu -* Readline Init File Syntax:: Syntax for the commands in the inputrc file. - -* Conditional Init Constructs:: Conditional key bindings in the inputrc file. - -* Sample Init File:: An example inputrc file. -@end menu - -@node Readline Init File Syntax -@subsection Readline Init File Syntax - -There are only a few basic constructs allowed in the -Readline init file. Blank lines are ignored. -Lines beginning with a @samp{#} are comments. -Lines beginning with a @samp{$} indicate conditional -constructs (@pxref{Conditional Init Constructs}). Other lines -denote variable settings and key bindings. - -@table @asis -@item Variable Settings -You can modify the run-time behavior of Readline by -altering the values of variables in Readline -using the @code{set} command within the init file. -The syntax is simple: - -@example -set @var{variable} @var{value} -@end example - -@noindent -Here, for example, is how to -change from the default Emacs-like key binding to use -@code{vi} line editing commands: - -@example -set editing-mode vi -@end example - -Variable names and values, where appropriate, are recognized without regard -to case. - -@ifset BashFeatures -The @w{@code{bind -V}} command lists the current Readline variable names -and values. @xref{Bash Builtins}. -@end ifset - -A great deal of run-time behavior is changeable with the following -variables. - -@cindex variables, readline -@table @code - -@item bell-style -@vindex bell-style -Controls what happens when Readline wants to ring the terminal bell. -If set to @samp{none}, Readline never rings the bell. If set to -@samp{visible}, Readline uses a visible bell if one is available. -If set to @samp{audible} (the default), Readline attempts to ring -the terminal's bell. - -@item comment-begin -@vindex comment-begin -The string to insert at the beginning of the line when the -@code{insert-comment} command is executed. The default value -is @code{"#"}. - -@item completion-ignore-case -If set to @samp{on}, Readline performs filename matching and completion -in a case-insensitive fashion. -The default value is @samp{off}. - -@item completion-query-items -@vindex completion-query-items -The number of possible completions that determines when the user is -asked whether he wants to see the list of possibilities. If the -number of possible completions is greater than this value, -Readline will ask the user whether or not he wishes to view -them; otherwise, they are simply listed. -This variable must be set to an integer value greater than or equal to 0. -The default limit is @code{100}. - -@item convert-meta -@vindex convert-meta -If set to @samp{on}, Readline will convert characters with the -eighth bit set to an @sc{ascii} key sequence by stripping the eighth -bit and prefixing an @key{ESC} character, converting them to a -meta-prefixed key sequence. The default value is @samp{on}. - -@item disable-completion -@vindex disable-completion -If set to @samp{On}, Readline will inhibit word completion. -Completion characters will be inserted into the line as if they had -been mapped to @code{self-insert}. The default is @samp{off}. - -@item editing-mode -@vindex editing-mode -The @code{editing-mode} variable controls which default set of -key bindings is used. By default, Readline starts up in Emacs editing -mode, where the keystrokes are most similar to Emacs. This variable can be -set to either @samp{emacs} or @samp{vi}. - -@item enable-keypad -@vindex enable-keypad -When set to @samp{on}, Readline will try to enable the application -keypad when it is called. Some systems need this to enable the -arrow keys. The default is @samp{off}. - -@item expand-tilde -@vindex expand-tilde -If set to @samp{on}, tilde expansion is performed when Readline -attempts word completion. The default is @samp{off}. - -@vindex history-preserve-point -If set to @samp{on}, the history code attempts to place point at the -same location on each history line retrived with @code{previous-history} -or @code{next-history}. - -@item horizontal-scroll-mode -@vindex horizontal-scroll-mode -This variable can be set to either @samp{on} or @samp{off}. Setting it -to @samp{on} means that the text of the lines being edited will scroll -horizontally on a single screen line when they are longer than the width -of the screen, instead of wrapping onto a new screen line. By default, -this variable is set to @samp{off}. - -@item input-meta -@vindex input-meta -@vindex meta-flag -If set to @samp{on}, Readline will enable eight-bit input (it -will not clear the eighth bit in the characters it reads), -regardless of what the terminal claims it can support. The -default value is @samp{off}. The name @code{meta-flag} is a -synonym for this variable. - -@item isearch-terminators -@vindex isearch-terminators -The string of characters that should terminate an incremental search without -subsequently executing the character as a command (@pxref{Searching}). -If this variable has not been given a value, the characters @key{ESC} and -@kbd{C-J} will terminate an incremental search. - -@item keymap -@vindex keymap -Sets Readline's idea of the current keymap for key binding commands. -Acceptable @code{keymap} names are -@code{emacs}, -@code{emacs-standard}, -@code{emacs-meta}, -@code{emacs-ctlx}, -@code{vi}, -@code{vi-move}, -@code{vi-command}, and -@code{vi-insert}. -@code{vi} is equivalent to @code{vi-command}; @code{emacs} is -equivalent to @code{emacs-standard}. The default value is @code{emacs}. -The value of the @code{editing-mode} variable also affects the -default keymap. - -@item mark-directories -If set to @samp{on}, completed directory names have a slash -appended. The default is @samp{on}. - -@item mark-modified-lines -@vindex mark-modified-lines -This variable, when set to @samp{on}, causes Readline to display an -asterisk (@samp{*}) at the start of history lines which have been modified. -This variable is @samp{off} by default. - -@item mark-symlinked-directories -@vindex mark-symlinked-directories -If set to @samp{on}, completed names which are symbolic links -to directories have a slash appended (subject to the value of -@code{mark-directories}). -The default is @samp{off}. - -@item match-hidden-files -@vindex match-hidden-files -This variable, when set to @samp{on}, causes Readline to match files whose -names begin with a @samp{.} (hidden files) when performing filename -completion, unless the leading @samp{.} is -supplied by the user in the filename to be completed. -This variable is @samp{on} by default. - -@item output-meta -@vindex output-meta -If set to @samp{on}, Readline will display characters with the -eighth bit set directly rather than as a meta-prefixed escape -sequence. The default is @samp{off}. - -@item page-completions -@vindex page-completions -If set to @samp{on}, Readline uses an internal @code{more}-like pager -to display a screenful of possible completions at a time. -This variable is @samp{on} by default. - -@item print-completions-horizontally -If set to @samp{on}, Readline will display completions with matches -sorted horizontally in alphabetical order, rather than down the screen. -The default is @samp{off}. - -@item show-all-if-ambiguous -@vindex show-all-if-ambiguous -This alters the default behavior of the completion functions. If -set to @samp{on}, -words which have more than one possible completion cause the -matches to be listed immediately instead of ringing the bell. -The default value is @samp{off}. - -@item visible-stats -@vindex visible-stats -If set to @samp{on}, a character denoting a file's type -is appended to the filename when listing possible -completions. The default is @samp{off}. - -@end table - -@item Key Bindings -The syntax for controlling key bindings in the init file is -simple. First you need to find the name of the command that you -want to change. The following sections contain tables of the command -name, the default keybinding, if any, and a short description of what -the command does. - -Once you know the name of the command, simply place on a line -in the init file the name of the key -you wish to bind the command to, a colon, and then the name of the -command. The name of the key -can be expressed in different ways, depending on what you find most -comfortable. - -In addition to command names, readline allows keys to be bound -to a string that is inserted when the key is pressed (a @var{macro}). - -@ifset BashFeatures -The @w{@code{bind -p}} command displays Readline function names and -bindings in a format that can put directly into an initialization file. -@xref{Bash Builtins}. -@end ifset - -@table @asis -@item @w{@var{keyname}: @var{function-name} or @var{macro}} -@var{keyname} is the name of a key spelled out in English. For example: -@example -Control-u: universal-argument -Meta-Rubout: backward-kill-word -Control-o: "> output" -@end example - -In the above example, @kbd{C-u} is bound to the function -@code{universal-argument}, -@kbd{M-DEL} is bound to the function @code{backward-kill-word}, and -@kbd{C-o} is bound to run the macro -expressed on the right hand side (that is, to insert the text -@samp{> output} into the line). - -A number of symbolic character names are recognized while -processing this key binding syntax: -@var{DEL}, -@var{ESC}, -@var{ESCAPE}, -@var{LFD}, -@var{NEWLINE}, -@var{RET}, -@var{RETURN}, -@var{RUBOUT}, -@var{SPACE}, -@var{SPC}, -and -@var{TAB}. - -@item @w{"@var{keyseq}": @var{function-name} or @var{macro}} -@var{keyseq} differs from @var{keyname} above in that strings -denoting an entire key sequence can be specified, by placing -the key sequence in double quotes. Some @sc{gnu} Emacs style key -escapes can be used, as in the following example, but the -special character names are not recognized. - -@example -"\C-u": universal-argument -"\C-x\C-r": re-read-init-file -"\e[11~": "Function Key 1" -@end example - -In the above example, @kbd{C-u} is again bound to the function -@code{universal-argument} (just as it was in the first example), -@samp{@kbd{C-x} @kbd{C-r}} is bound to the function @code{re-read-init-file}, -and @samp{@key{ESC} @key{[} @key{1} @key{1} @key{~}} is bound to insert -the text @samp{Function Key 1}. - -@end table - -The following @sc{gnu} Emacs style escape sequences are available when -specifying key sequences: - -@table @code -@item @kbd{\C-} -control prefix -@item @kbd{\M-} -meta prefix -@item @kbd{\e} -an escape character -@item @kbd{\\} -backslash -@item @kbd{\"} -@key{"}, a double quotation mark -@item @kbd{\'} -@key{'}, a single quote or apostrophe -@end table - -In addition to the @sc{gnu} Emacs style escape sequences, a second -set of backslash escapes is available: - -@table @code -@item \a -alert (bell) -@item \b -backspace -@item \d -delete -@item \f -form feed -@item \n -newline -@item \r -carriage return -@item \t -horizontal tab -@item \v -vertical tab -@item \@var{nnn} -the eight-bit character whose value is the octal value @var{nnn} -(one to three digits) -@item \x@var{HH} -the eight-bit character whose value is the hexadecimal value @var{HH} -(one or two hex digits) -@end table - -When entering the text of a macro, single or double quotes must -be used to indicate a macro definition. -Unquoted text is assumed to be a function name. -In the macro body, the backslash escapes described above are expanded. -Backslash will quote any other character in the macro text, -including @samp{"} and @samp{'}. -For example, the following binding will make @samp{@kbd{C-x} \} -insert a single @samp{\} into the line: -@example -"\C-x\\": "\\" -@end example - -@end table - -@node Conditional Init Constructs -@subsection Conditional Init Constructs - -Readline implements a facility similar in spirit to the conditional -compilation features of the C preprocessor which allows key -bindings and variable settings to be performed as the result -of tests. There are four parser directives used. - -@table @code -@item $if -The @code{$if} construct allows bindings to be made based on the -editing mode, the terminal being used, or the application using -Readline. The text of the test extends to the end of the line; -no characters are required to isolate it. - -@table @code -@item mode -The @code{mode=} form of the @code{$if} directive is used to test -whether Readline is in @code{emacs} or @code{vi} mode. -This may be used in conjunction -with the @samp{set keymap} command, for instance, to set bindings in -the @code{emacs-standard} and @code{emacs-ctlx} keymaps only if -Readline is starting out in @code{emacs} mode. - -@item term -The @code{term=} form may be used to include terminal-specific -key bindings, perhaps to bind the key sequences output by the -terminal's function keys. The word on the right side of the -@samp{=} is tested against both the full name of the terminal and -the portion of the terminal name before the first @samp{-}. This -allows @code{sun} to match both @code{sun} and @code{sun-cmd}, -for instance. - -@item application -The @var{application} construct is used to include -application-specific settings. Each program using the Readline -library sets the @var{application name}, and you can test for -a particular value. -This could be used to bind key sequences to functions useful for -a specific program. For instance, the following command adds a -key sequence that quotes the current or previous word in Bash: -@example -$if Bash -# Quote the current or previous word -"\C-xq": "\eb\"\ef\"" -$endif -@end example -@end table - -@item $endif -This command, as seen in the previous example, terminates an -@code{$if} command. - -@item $else -Commands in this branch of the @code{$if} directive are executed if -the test fails. - -@item $include -This directive takes a single filename as an argument and reads commands -and bindings from that file. -For example, the following directive reads from @file{/etc/inputrc}: -@example -$include /etc/inputrc -@end example -@end table - -@node Sample Init File -@subsection Sample Init File - -Here is an example of an @var{inputrc} file. This illustrates key -binding, variable assignment, and conditional syntax. - -@example -@page -# This file controls the behaviour of line input editing for -# programs that use the GNU Readline library. Existing -# programs include FTP, Bash, and GDB. -# -# You can re-read the inputrc file with C-x C-r. -# Lines beginning with '#' are comments. -# -# First, include any systemwide bindings and variable -# assignments from /etc/Inputrc -$include /etc/Inputrc - -# -# Set various bindings for emacs mode. - -set editing-mode emacs - -$if mode=emacs - -Meta-Control-h: backward-kill-word Text after the function name is ignored - -# -# Arrow keys in keypad mode -# -#"\M-OD": backward-char -#"\M-OC": forward-char -#"\M-OA": previous-history -#"\M-OB": next-history -# -# Arrow keys in ANSI mode -# -"\M-[D": backward-char -"\M-[C": forward-char -"\M-[A": previous-history -"\M-[B": next-history -# -# Arrow keys in 8 bit keypad mode -# -#"\M-\C-OD": backward-char -#"\M-\C-OC": forward-char -#"\M-\C-OA": previous-history -#"\M-\C-OB": next-history -# -# Arrow keys in 8 bit ANSI mode -# -#"\M-\C-[D": backward-char -#"\M-\C-[C": forward-char -#"\M-\C-[A": previous-history -#"\M-\C-[B": next-history - -C-q: quoted-insert - -$endif - -# An old-style binding. This happens to be the default. -TAB: complete - -# Macros that are convenient for shell interaction -$if Bash -# edit the path -"\C-xp": "PATH=$@{PATH@}\e\C-e\C-a\ef\C-f" -# prepare to type a quoted word -- -# insert open and close double quotes -# and move to just after the open quote -"\C-x\"": "\"\"\C-b" -# insert a backslash (testing backslash escapes -# in sequences and macros) -"\C-x\\": "\\" -# Quote the current or previous word -"\C-xq": "\eb\"\ef\"" -# Add a binding to refresh the line, which is unbound -"\C-xr": redraw-current-line -# Edit variable on current line. -"\M-\C-v": "\C-a\C-k$\C-y\M-\C-e\C-a\C-y=" -$endif - -# use a visible bell if one is available -set bell-style visible - -# don't strip characters to 7 bits when reading -set input-meta on - -# allow iso-latin1 characters to be inserted rather -# than converted to prefix-meta sequences -set convert-meta off - -# display characters with the eighth bit set directly -# rather than as meta-prefixed characters -set output-meta on - -# if there are more than 150 possible completions for -# a word, ask the user if he wants to see all of them -set completion-query-items 150 - -# For FTP -$if Ftp -"\C-xg": "get \M-?" -"\C-xt": "put \M-?" -"\M-.": yank-last-arg -$endif -@end example - -@node Bindable Readline Commands -@section Bindable Readline Commands - -@menu -* Commands For Moving:: Moving about the line. -* Commands For History:: Getting at previous lines. -* Commands For Text:: Commands for changing text. -* Commands For Killing:: Commands for killing and yanking. -* Numeric Arguments:: Specifying numeric arguments, repeat counts. -* Commands For Completion:: Getting Readline to do the typing for you. -* Keyboard Macros:: Saving and re-executing typed characters -* Miscellaneous Commands:: Other miscellaneous commands. -@end menu - -This section describes Readline commands that may be bound to key -sequences. -@ifset BashFeatures -You can list your key bindings by executing -@w{@code{bind -P}} or, for a more terse format, suitable for an -@var{inputrc} file, @w{@code{bind -p}}. (@xref{Bash Builtins}.) -@end ifset -Command names without an accompanying key sequence are unbound by default. - -In the following descriptions, @dfn{point} refers to the current cursor -position, and @dfn{mark} refers to a cursor position saved by the -@code{set-mark} command. -The text between the point and mark is referred to as the @dfn{region}. - -@node Commands For Moving -@subsection Commands For Moving -@ftable @code -@item beginning-of-line (C-a) -Move to the start of the current line. - -@item end-of-line (C-e) -Move to the end of the line. - -@item forward-char (C-f) -Move forward a character. - -@item backward-char (C-b) -Move back a character. - -@item forward-word (M-f) -Move forward to the end of the next word. Words are composed of -letters and digits. - -@item backward-word (M-b) -Move back to the start of the current or previous word. Words are -composed of letters and digits. - -@item clear-screen (C-l) -Clear the screen and redraw the current line, -leaving the current line at the top of the screen. - -@item redraw-current-line () -Refresh the current line. By default, this is unbound. - -@end ftable - -@node Commands For History -@subsection Commands For Manipulating The History - -@ftable @code -@item accept-line (Newline or Return) -@ifset BashFeatures -Accept the line regardless of where the cursor is. -If this line is -non-empty, add it to the history list according to the setting of -the @env{HISTCONTROL} and @env{HISTIGNORE} variables. -If this line is a modified history line, then restore the history line -to its original state. -@end ifset -@ifclear BashFeatures -Accept the line regardless of where the cursor is. -If this line is -non-empty, it may be added to the history list for future recall with -@code{add_history()}. -If this line is a modified history line, the history line is restored -to its original state. -@end ifclear - -@item previous-history (C-p) -Move `back' through the history list, fetching the previous command. - -@item next-history (C-n) -Move `forward' through the history list, fetching the next command. - -@item beginning-of-history (M-<) -Move to the first line in the history. - -@item end-of-history (M->) -Move to the end of the input history, i.e., the line currently -being entered. - -@item reverse-search-history (C-r) -Search backward starting at the current line and moving `up' through -the history as necessary. This is an incremental search. - -@item forward-search-history (C-s) -Search forward starting at the current line and moving `down' through -the the history as necessary. This is an incremental search. - -@item non-incremental-reverse-search-history (M-p) -Search backward starting at the current line and moving `up' -through the history as necessary using a non-incremental search -for a string supplied by the user. - -@item non-incremental-forward-search-history (M-n) -Search forward starting at the current line and moving `down' -through the the history as necessary using a non-incremental search -for a string supplied by the user. - -@item history-search-forward () -Search forward through the history for the string of characters -between the start of the current line and the point. -This is a non-incremental search. -By default, this command is unbound. - -@item history-search-backward () -Search backward through the history for the string of characters -between the start of the current line and the point. This -is a non-incremental search. By default, this command is unbound. - -@item yank-nth-arg (M-C-y) -Insert the first argument to the previous command (usually -the second word on the previous line) at point. -With an argument @var{n}, -insert the @var{n}th word from the previous command (the words -in the previous command begin with word 0). A negative argument -inserts the @var{n}th word from the end of the previous command. - -@item yank-last-arg (M-. or M-_) -Insert last argument to the previous command (the last word of the -previous history entry). With an -argument, behave exactly like @code{yank-nth-arg}. -Successive calls to @code{yank-last-arg} move back through the history -list, inserting the last argument of each line in turn. - -@end ftable - -@node Commands For Text -@subsection Commands For Changing Text - -@ftable @code -@item delete-char (C-d) -Delete the character at point. If point is at the -beginning of the line, there are no characters in the line, and -the last character typed was not bound to @code{delete-char}, then -return @sc{eof}. - -@item backward-delete-char (Rubout) -Delete the character behind the cursor. A numeric argument means -to kill the characters instead of deleting them. - -@item forward-backward-delete-char () -Delete the character under the cursor, unless the cursor is at the -end of the line, in which case the character behind the cursor is -deleted. By default, this is not bound to a key. - -@item quoted-insert (C-q or C-v) -Add the next character typed to the line verbatim. This is -how to insert key sequences like @kbd{C-q}, for example. - -@ifclear BashFeatures -@item tab-insert (M-@key{TAB}) -Insert a tab character. -@end ifclear - -@item self-insert (a, b, A, 1, !, @dots{}) -Insert yourself. - -@item transpose-chars (C-t) -Drag the character before the cursor forward over -the character at the cursor, moving the -cursor forward as well. If the insertion point -is at the end of the line, then this -transposes the last two characters of the line. -Negative arguments have no effect. - -@item transpose-words (M-t) -Drag the word before point past the word after point, -moving point past that word as well. -If the insertion point is at the end of the line, this transposes -the last two words on the line. - -@item upcase-word (M-u) -Uppercase the current (or following) word. With a negative argument, -uppercase the previous word, but do not move the cursor. - -@item downcase-word (M-l) -Lowercase the current (or following) word. With a negative argument, -lowercase the previous word, but do not move the cursor. - -@item capitalize-word (M-c) -Capitalize the current (or following) word. With a negative argument, -capitalize the previous word, but do not move the cursor. - -@item overwrite-mode () -Toggle overwrite mode. With an explicit positive numeric argument, -switches to overwrite mode. With an explicit non-positive numeric -argument, switches to insert mode. This command affects only -@code{emacs} mode; @code{vi} mode does overwrite differently. -Each call to @code{readline()} starts in insert mode. - -In overwrite mode, characters bound to @code{self-insert} replace -the text at point rather than pushing the text to the right. -Characters bound to @code{backward-delete-char} replace the character -before point with a space. - -By default, this command is unbound. - -@end ftable - -@node Commands For Killing -@subsection Killing And Yanking - -@ftable @code - -@item kill-line (C-k) -Kill the text from point to the end of the line. - -@item backward-kill-line (C-x Rubout) -Kill backward to the beginning of the line. - -@item unix-line-discard (C-u) -Kill backward from the cursor to the beginning of the current line. - -@item kill-whole-line () -Kill all characters on the current line, no matter where point is. -By default, this is unbound. - -@item kill-word (M-d) -Kill from point to the end of the current word, or if between -words, to the end of the next word. -Word boundaries are the same as @code{forward-word}. - -@item backward-kill-word (M-@key{DEL}) -Kill the word behind point. -Word boundaries are the same as @code{backward-word}. - -@item unix-word-rubout (C-w) -Kill the word behind point, using white space as a word boundary. -The killed text is saved on the kill-ring. - -@item delete-horizontal-space () -Delete all spaces and tabs around point. By default, this is unbound. - -@item kill-region () -Kill the text in the current region. -By default, this command is unbound. - -@item copy-region-as-kill () -Copy the text in the region to the kill buffer, so it can be yanked -right away. By default, this command is unbound. - -@item copy-backward-word () -Copy the word before point to the kill buffer. -The word boundaries are the same as @code{backward-word}. -By default, this command is unbound. - -@item copy-forward-word () -Copy the word following point to the kill buffer. -The word boundaries are the same as @code{forward-word}. -By default, this command is unbound. - -@item yank (C-y) -Yank the top of the kill ring into the buffer at point. - -@item yank-pop (M-y) -Rotate the kill-ring, and yank the new top. You can only do this if -the prior command is @code{yank} or @code{yank-pop}. -@end ftable - -@node Numeric Arguments -@subsection Specifying Numeric Arguments -@ftable @code - -@item digit-argument (@kbd{M-0}, @kbd{M-1}, @dots{} @kbd{M--}) -Add this digit to the argument already accumulating, or start a new -argument. @kbd{M--} starts a negative argument. - -@item universal-argument () -This is another way to specify an argument. -If this command is followed by one or more digits, optionally with a -leading minus sign, those digits define the argument. -If the command is followed by digits, executing @code{universal-argument} -again ends the numeric argument, but is otherwise ignored. -As a special case, if this command is immediately followed by a -character that is neither a digit or minus sign, the argument count -for the next command is multiplied by four. -The argument count is initially one, so executing this function the -first time makes the argument count four, a second time makes the -argument count sixteen, and so on. -By default, this is not bound to a key. -@end ftable - -@node Commands For Completion -@subsection Letting Readline Type For You - -@ftable @code -@item complete (@key{TAB}) -Attempt to perform completion on the text before point. -The actual completion performed is application-specific. -@ifset BashFeatures -Bash attempts completion treating the text as a variable (if the -text begins with @samp{$}), username (if the text begins with -@samp{~}), hostname (if the text begins with @samp{@@}), or -command (including aliases and functions) in turn. If none -of these produces a match, filename completion is attempted. -@end ifset -@ifclear BashFeatures -The default is filename completion. -@end ifclear - -@item possible-completions (M-?) -List the possible completions of the text before point. - -@item insert-completions (M-*) -Insert all completions of the text before point that would have -been generated by @code{possible-completions}. - -@item menu-complete () -Similar to @code{complete}, but replaces the word to be completed -with a single match from the list of possible completions. -Repeated execution of @code{menu-complete} steps through the list -of possible completions, inserting each match in turn. -At the end of the list of completions, the bell is rung -(subject to the setting of @code{bell-style}) -and the original text is restored. -An argument of @var{n} moves @var{n} positions forward in the list -of matches; a negative argument may be used to move backward -through the list. -This command is intended to be bound to @key{TAB}, but is unbound -by default. - -@item delete-char-or-list () -Deletes the character under the cursor if not at the beginning or -end of the line (like @code{delete-char}). -If at the end of the line, behaves identically to -@code{possible-completions}. -This command is unbound by default. - -@ifset BashFeatures -@item complete-filename (M-/) -Attempt filename completion on the text before point. - -@item possible-filename-completions (C-x /) -List the possible completions of the text before point, -treating it as a filename. - -@item complete-username (M-~) -Attempt completion on the text before point, treating -it as a username. - -@item possible-username-completions (C-x ~) -List the possible completions of the text before point, -treating it as a username. - -@item complete-variable (M-$) -Attempt completion on the text before point, treating -it as a shell variable. - -@item possible-variable-completions (C-x $) -List the possible completions of the text before point, -treating it as a shell variable. - -@item complete-hostname (M-@@) -Attempt completion on the text before point, treating -it as a hostname. - -@item possible-hostname-completions (C-x @@) -List the possible completions of the text before point, -treating it as a hostname. - -@item complete-command (M-!) -Attempt completion on the text before point, treating -it as a command name. Command completion attempts to -match the text against aliases, reserved words, shell -functions, shell builtins, and finally executable filenames, -in that order. - -@item possible-command-completions (C-x !) -List the possible completions of the text before point, -treating it as a command name. - -@item dynamic-complete-history (M-@key{TAB}) -Attempt completion on the text before point, comparing -the text against lines from the history list for possible -completion matches. - -@item complete-into-braces (M-@{) -Perform filename completion and insert the list of possible completions -enclosed within braces so the list is available to the shell -(@pxref{Brace Expansion}). - -@end ifset -@end ftable - -@node Keyboard Macros -@subsection Keyboard Macros -@ftable @code - -@item start-kbd-macro (C-x () -Begin saving the characters typed into the current keyboard macro. - -@item end-kbd-macro (C-x )) -Stop saving the characters typed into the current keyboard macro -and save the definition. - -@item call-last-kbd-macro (C-x e) -Re-execute the last keyboard macro defined, by making the characters -in the macro appear as if typed at the keyboard. - -@end ftable - -@node Miscellaneous Commands -@subsection Some Miscellaneous Commands -@ftable @code - -@item re-read-init-file (C-x C-r) -Read in the contents of the @var{inputrc} file, and incorporate -any bindings or variable assignments found there. - -@item abort (C-g) -Abort the current editing command and -ring the terminal's bell (subject to the setting of -@code{bell-style}). - -@item do-uppercase-version (M-a, M-b, M-@var{x}, @dots{}) -If the metafied character @var{x} is lowercase, run the command -that is bound to the corresponding uppercase character. - -@item prefix-meta (@key{ESC}) -Metafy the next character typed. This is for keyboards -without a meta key. Typing @samp{@key{ESC} f} is equivalent to typing -@kbd{M-f}. - -@item undo (C-_ or C-x C-u) -Incremental undo, separately remembered for each line. - -@item revert-line (M-r) -Undo all changes made to this line. This is like executing the @code{undo} -command enough times to get back to the beginning. - -@ifset BashFeatures -@item tilde-expand (M-&) -@end ifset -@ifclear BashFeatures -@item tilde-expand (M-~) -@end ifclear -Perform tilde expansion on the current word. - -@item set-mark (C-@@) -Set the mark to the point. If a -numeric argument is supplied, the mark is set to that position. - -@item exchange-point-and-mark (C-x C-x) -Swap the point with the mark. The current cursor position is set to -the saved position, and the old cursor position is saved as the mark. - -@item character-search (C-]) -A character is read and point is moved to the next occurrence of that -character. A negative count searches for previous occurrences. - -@item character-search-backward (M-C-]) -A character is read and point is moved to the previous occurrence -of that character. A negative count searches for subsequent -occurrences. - -@item insert-comment (M-#) -Without a numeric argument, the value of the @code{comment-begin} -variable is inserted at the beginning of the current line. -If a numeric argument is supplied, this command acts as a toggle: if -the characters at the beginning of the line do not match the value -of @code{comment-begin}, the value is inserted, otherwise -the characters in @code{comment-begin} are deleted from the beginning of -the line. -In either case, the line is accepted as if a newline had been typed. -@ifset BashFeatures -The default value of @code{comment-begin} causes this command -to make the current line a shell comment. -If a numeric argument causes the comment character to be removed, the line -will be executed by the shell. -@end ifset - -@item dump-functions () -Print all of the functions and their key bindings to the -Readline output stream. If a numeric argument is supplied, -the output is formatted in such a way that it can be made part -of an @var{inputrc} file. This command is unbound by default. - -@item dump-variables () -Print all of the settable variables and their values to the -Readline output stream. If a numeric argument is supplied, -the output is formatted in such a way that it can be made part -of an @var{inputrc} file. This command is unbound by default. - -@item dump-macros () -Print all of the Readline key sequences bound to macros and the -strings they output. If a numeric argument is supplied, -the output is formatted in such a way that it can be made part -of an @var{inputrc} file. This command is unbound by default. - -@ifset BashFeatures -@item glob-complete-word (M-g) -The word before point is treated as a pattern for pathname expansion, -with an asterisk implicitly appended. This pattern is used to -generate a list of matching file names for possible completions. - -@item glob-expand-word (C-x *) -The word before point is treated as a pattern for pathname expansion, -and the list of matching file names is inserted, replacing the word. -If a numeric argument is supplied, a @samp{*} is appended before -pathname expansion. - -@item glob-list-expansions (C-x g) -The list of expansions that would have been generated by -@code{glob-expand-word} is displayed, and the line is redrawn. -If a numeric argument is supplied, a @samp{*} is appended before -pathname expansion. - -@item display-shell-version (C-x C-v) -Display version information about the current instance of Bash. - -@item shell-expand-line (M-C-e) -Expand the line as the shell does. -This performs alias and history expansion as well as all of the shell -word expansions (@pxref{Shell Expansions}). - -@item history-expand-line (M-^) -Perform history expansion on the current line. - -@item magic-space () -Perform history expansion on the current line and insert a space -(@pxref{History Interaction}). - -@item alias-expand-line () -Perform alias expansion on the current line (@pxref{Aliases}). - -@item history-and-alias-expand-line () -Perform history and alias expansion on the current line. - -@item insert-last-argument (M-. or M-_) -A synonym for @code{yank-last-arg}. - -@item operate-and-get-next (C-o) -Accept the current line for execution and fetch the next line -relative to the current line from the history for editing. Any -argument is ignored. - -@item edit-and-execute-command (C-xC-e) -Invoke an editor on the current command line, and execute the result as shell -commands. -Bash attempts to invoke -@code{$FCEDIT}, @code{$EDITOR}, and @code{emacs} -as the editor, in that order. - -@end ifset - -@ifclear BashFeatures -@item emacs-editing-mode (C-e) -When in @code{vi} command mode, this causes a switch to @code{emacs} -editing mode. - -@item vi-editing-mode (M-C-j) -When in @code{emacs} editing mode, this causes a switch to @code{vi} -editing mode. - -@end ifclear - -@end ftable - -@node Readline vi Mode -@section Readline vi Mode - -While the Readline library does not have a full set of @code{vi} -editing functions, it does contain enough to allow simple editing -of the line. The Readline @code{vi} mode behaves as specified in -the @sc{posix} 1003.2 standard. - -@ifset BashFeatures -In order to switch interactively between @code{emacs} and @code{vi} -editing modes, use the @samp{set -o emacs} and @samp{set -o vi} -commands (@pxref{The Set Builtin}). -@end ifset -@ifclear BashFeatures -In order to switch interactively between @code{emacs} and @code{vi} -editing modes, use the command @kbd{M-C-j} (bound to emacs-editing-mode -when in @code{vi} mode and to vi-editing-mode in @code{emacs} mode). -@end ifclear -The Readline default is @code{emacs} mode. - -When you enter a line in @code{vi} mode, you are already placed in -`insertion' mode, as if you had typed an @samp{i}. Pressing @key{ESC} -switches you into `command' mode, where you can edit the text of the -line with the standard @code{vi} movement keys, move to previous -history lines with @samp{k} and subsequent lines with @samp{j}, and -so forth. - -@ifset BashFeatures -@node Programmable Completion -@section Programmable Completion -@cindex programmable completion - -When word completion is attempted for an argument to a command for -which a completion specification (a @var{compspec}) has been defined -using the @code{complete} builtin (@pxref{Programmable Completion Builtins}), -the programmable completion facilities are invoked. - -First, the command name is identified. -If a compspec has been defined for that command, the -compspec is used to generate the list of possible completions for the word. -If the command word is a full pathname, a compspec for the full -pathname is searched for first. -If no compspec is found for the full pathname, an attempt is made to -find a compspec for the portion following the final slash. - -Once a compspec has been found, it is used to generate the list of -matching words. -If a compspec is not found, the default Bash completion -described above (@pxref{Commands For Completion}) is performed. - -First, the actions specified by the compspec are used. -Only matches which are prefixed by the word being completed are -returned. -When the @option{-f} or @option{-d} option is used for filename or -directory name completion, the shell variable @env{FIGNORE} is -used to filter the matches. -@xref{Bash Variables}, for a description of @env{FIGNORE}. - -Any completions specified by a filename expansion pattern to the -@option{-G} option are generated next. -The words generated by the pattern need not match the word being completed. -The @env{GLOBIGNORE} shell variable is not used to filter the matches, -but the @env{FIGNORE} shell variable is used. - -Next, the string specified as the argument to the @option{-W} option -is considered. -The string is first split using the characters in the @env{IFS} -special variable as delimiters. -Shell quoting is honored. -Each word is then expanded using -brace expansion, tilde expansion, parameter and variable expansion, -command substitution, arithmetic expansion, and pathname expansion, -as described above (@pxref{Shell Expansions}). -The results are split using the rules described above -(@pxref{Word Splitting}). -The results of the expansion are prefix-matched against the word being -completed, and the matching words become the possible completions. - -After these matches have been generated, any shell function or command -specified with the @option{-F} and @option{-C} options is invoked. -When the command or function is invoked, the @env{COMP_LINE} and -@env{COMP_POINT} variables are assigned values as described above -(@pxref{Bash Variables}). -If a shell function is being invoked, the @env{COMP_WORDS} and -@env{COMP_CWORD} variables are also set. -When the function or command is invoked, the first argument is the -name of the command whose arguments are being completed, the -second argument is the word being completed, and the third argument -is the word preceding the word being completed on the current command line. -No filtering of the generated completions against the word being completed -is performed; the function or command has complete freedom in generating -the matches. - -Any function specified with @option{-F} is invoked first. -The function may use any of the shell facilities, including the -@code{compgen} builtin described below -(@pxref{Programmable Completion Builtins}), to generate the matches. -It must put the possible completions in the @env{COMPREPLY} array -variable. - -Next, any command specified with the @option{-C} option is invoked -in an environment equivalent to command substitution. -It should print a list of completions, one per line, to -the standard output. -Backslash may be used to escape a newline, if necessary. - -After all of the possible completions are generated, any filter -specified with the @option{-X} option is applied to the list. -The filter is a pattern as used for pathname expansion; a @samp{&} -in the pattern is replaced with the text of the word being completed. -A literal @samp{&} may be escaped with a backslash; the backslash -is removed before attempting a match. -Any completion that matches the pattern will be removed from the list. -A leading @samp{!} negates the pattern; in this case any completion -not matching the pattern will be removed. - -Finally, any prefix and suffix specified with the @option{-P} and @option{-S} -options are added to each member of the completion list, and the result is -returned to the Readline completion code as the list of possible -completions. - -If the previously-applied actions do not generate any matches, and the -@option{-o dirnames} option was supplied to @code{complete} when the -compspec was defined, directory name completion is attempted. - -By default, if a compspec is found, whatever it generates is returned to -the completion code as the full set of possible completions. -The default Bash completions are not attempted, and the Readline default -of filename completion is disabled. -If the @option{-o default} option was supplied to @code{complete} when the -compspec was defined, Readline's default completion will be performed -if the compspec generates no matches. - -When a compspec indicates that directory name completion is desired, -the programmable completion functions force Readline to append a slash -to completed names which are symbolic links to directories, subject to -the value of the @var{mark-directories} Readline variable, regardless -of the setting of the @var{mark-symlinked-directories} Readline variable. - -@node Programmable Completion Builtins -@section Programmable Completion Builtins -@cindex completion builtins - -Two builtin commands are available to manipulate the programmable completion -facilities. - -@table @code -@item compgen -@btindex compgen -@example -@code{compgen [@var{option}] [@var{word}]} -@end example - -Generate possible completion matches for @var{word} according to -the @var{option}s, which may be any option accepted by the -@code{complete} -builtin with the exception of @option{-p} and @option{-r}, and write -the matches to the standard output. -When using the @option{-F} or @option{-C} options, the various shell variables -set by the programmable completion facilities, while available, will not -have useful values. - -The matches will be generated in the same way as if the programmable -completion code had generated them directly from a completion specification -with the same flags. -If @var{word} is specified, only those completions matching @var{word} -will be displayed. - -The return value is true unless an invalid option is supplied, or no -matches were generated. - -@item complete -@btindex complete -@example -@code{complete [-abcdefgjksuv] [-o @var{comp-option}] [-A @var{action}] [-G @var{globpat}] [-W @var{wordlist}] -[-P @var{prefix}] [-S @var{suffix}] [-X @var{filterpat}] [-F @var{function}] -[-C @var{command}] @var{name} [@var{name} @dots{}]} -@code{complete -pr [@var{name} @dots{}]} -@end example - -Specify how arguments to each @var{name} should be completed. -If the @option{-p} option is supplied, or if no options are supplied, existing -completion specifications are printed in a way that allows them to be -reused as input. -The @option{-r} option removes a completion specification for -each @var{name}, or, if no @var{name}s are supplied, all -completion specifications. - -The process of applying these completion specifications when word completion -is attempted is described above (@pxref{Programmable Completion}). - -Other options, if specified, have the following meanings. -The arguments to the @option{-G}, @option{-W}, and @option{-X} options -(and, if necessary, the @option{-P} and @option{-S} options) -should be quoted to protect them from expansion before the -@code{complete} builtin is invoked. - - -@table @code -@item -o @var{comp-option} -The @var{comp-option} controls several aspects of the compspec's behavior -beyond the simple generation of completions. -@var{comp-option} may be one of: - -@table @code - -@item default -Use Readline's default filename completion if the compspec generates -no matches. - -@item dirnames -Perform directory name completion if the compspec generates no matches. - -@item filenames -Tell Readline that the compspec generates filenames, so it can perform any -filename\-specific processing (like adding a slash to directory names or -suppressing trailing spaces). This option is intended to be used with -shell functions specified with @option{-F}. - -@item nospace -Tell Readline not to append a space (the default) to words completed at -the end of the line. -@end table - -@item -A @var{action} -The @var{action} may be one of the following to generate a list of possible -completions: - -@table @code -@item alias -Alias names. May also be specified as @option{-a}. - -@item arrayvar -Array variable names. - -@item binding -Readline key binding names (@pxref{Bindable Readline Commands}). - -@item builtin -Names of shell builtin commands. May also be specified as @option{-b}. - -@item command -Command names. May also be specified as @option{-c}. - -@item directory -Directory names. May also be specified as @option{-d}. - -@item disabled -Names of disabled shell builtins. - -@item enabled -Names of enabled shell builtins. - -@item export -Names of exported shell variables. May also be specified as @option{-e}. - -@item file -File names. May also be specified as @option{-f}. - -@item function -Names of shell functions. - -@item group -Group names. May also be specified as @option{-g}. - -@item helptopic -Help topics as accepted by the @code{help} builtin (@pxref{Bash Builtins}). - -@item hostname -Hostnames, as taken from the file specified by the -@env{HOSTFILE} shell variable (@pxref{Bash Variables}). - -@item job -Job names, if job control is active. May also be specified as @option{-j}. - -@item keyword -Shell reserved words. May also be specified as @option{-k}. - -@item running -Names of running jobs, if job control is active. - -@item service -Service names. May also be specified as @option{-s}. - -@item setopt -Valid arguments for the @option{-o} option to the @code{set} builtin -(@pxref{The Set Builtin}). - -@item shopt -Shell option names as accepted by the @code{shopt} builtin -(@pxref{Bash Builtins}). - -@item signal -Signal names. - -@item stopped -Names of stopped jobs, if job control is active. - -@item user -User names. May also be specified as @option{-u}. - -@item variable -Names of all shell variables. May also be specified as @option{-v}. -@end table - -@item -G @var{globpat} -The filename expansion pattern @var{globpat} is expanded to generate -the possible completions. - -@item -W @var{wordlist} -The @var{wordlist} is split using the characters in the -@env{IFS} special variable as delimiters, and each resultant word -is expanded. -The possible completions are the members of the resultant list which -match the word being completed. - -@item -C @var{command} -@var{command} is executed in a subshell environment, and its output is -used as the possible completions. - -@item -F @var{function} -The shell function @var{function} is executed in the current shell -environment. -When it finishes, the possible completions are retrieved from the value -of the @env{COMPREPLY} array variable. - -@item -X @var{filterpat} -@var{filterpat} is a pattern as used for filename expansion. -It is applied to the list of possible completions generated by the -preceding options and arguments, and each completion matching -@var{filterpat} is removed from the list. -A leading @samp{!} in @var{filterpat} negates the pattern; in this -case, any completion not matching @var{filterpat} is removed. - -@item -P @var{prefix} -@var{prefix} is added at the beginning of each possible completion -after all other options have been applied. - -@item -S @var{suffix} -@var{suffix} is appended to each possible completion -after all other options have been applied. -@end table - -The return value is true unless an invalid option is supplied, an option -other than @option{-p} or @option{-r} is supplied without a @var{name} -argument, an attempt is made to remove a completion specification for -a @var{name} for which no specification exists, or -an error occurs adding a completion specification. - -@end table -@end ifset diff --git a/readline/doc/rluserman.pdf b/readline/doc/rluserman.pdf Binary files differdeleted file mode 100644 index 4a2184b..0000000 --- a/readline/doc/rluserman.pdf +++ /dev/null diff --git a/readline/doc/rluserman.texinfo b/readline/doc/rluserman.texinfo deleted file mode 100644 index 89abe31..0000000 --- a/readline/doc/rluserman.texinfo +++ /dev/null @@ -1,94 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@comment %**start of header (This is for running Texinfo on a region.) -@setfilename rluserman.info -@settitle GNU Readline Library -@comment %**end of header (This is for running Texinfo on a region.) -@setchapternewpage odd - -@include manvers.texinfo - -@ifinfo -@dircategory Libraries -@direntry -* RLuserman: (rluserman). The GNU readline library User's Manual. -@end direntry - -This document describes the end user interface of the GNU Readline Library, -a utility which aids in the consistency of user interface across discrete -programs that need to provide a command line interface. - -Copyright (C) 1988-2002 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -pare preserved on all copies. - -@ignore -Permission is granted to process this file through TeX and print the -results, provided the printed document carries copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). -@end ignore - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the entire -resulting derived work is distributed under the terms of a permission -notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that this permission notice may be stated in a translation approved -by the Free Software Foundation. -@end ifinfo - -@titlepage -@title GNU Readline Library User Interface -@subtitle Edition @value{EDITION}, for @code{Readline Library} Version @value{VERSION}. -@subtitle @value{UPDATE-MONTH} -@author Brian Fox, Free Software Foundation -@author Chet Ramey, Case Western Reserve University - -@page -This document describes the end user interface of the GNU Readline Library, -a utility which aids in the consistency of user interface across discrete -programs that need to provide a command line interface. - -Published by the Free Software Foundation @* -59 Temple Place, Suite 330, @* -Boston, MA 02111 USA - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the entire -resulting derived work is distributed under the terms of a permission -notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that this permission notice may be stated in a translation approved -by the Free Software Foundation. - -@vskip 0pt plus 1filll -Copyright @copyright{} 1988-2002 Free Software Foundation, Inc. -@end titlepage - -@ifinfo -@node Top -@top GNU Readline Library - -This document describes the end user interface of the GNU Readline Library, -a utility which aids in the consistency of user interface across discrete -programs that need to provide a command line interface. - -@menu -* Command Line Editing:: GNU Readline User's Manual. -@end menu -@end ifinfo - -@include rluser.texinfo - -@contents -@bye diff --git a/readline/doc/texi2dvi b/readline/doc/texi2dvi index c186848..c0bcc0a 100755 --- a/readline/doc/texi2dvi +++ b/readline/doc/texi2dvi @@ -2,7 +2,8 @@ # texi2dvi --- produce DVI (or PDF) files from Texinfo (or LaTeX) sources. # $Id$ # -# Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 99 Free Software Foundation, Inc. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001, +# 2002, 2003 Free Software Foundation, Inc. # # 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 @@ -29,9 +30,9 @@ rcs_revision='$Revision$' rcs_version=`set - $rcs_revision; echo $2` program=`echo $0 | sed -e 's!.*/!!'` -version="texi2dvi (GNU Texinfo 4.0) $rcs_version +version="texi2dvi (GNU Texinfo 4.5) $rcs_version -Copyright (C) 1999 Free Software Foundation, Inc. +Copyright (C) 2003 Free Software Foundation, Inc. There is NO warranty. You may redistribute this software under the terms of the GNU General Public License. For more information about these matters, see the files named COPYING." @@ -46,46 +47,52 @@ is used to determine its language (LaTeX or Texinfo). Makeinfo is used to perform Texinfo macro expansion before running TeX when needed. -Options: - -@ Use @input instead of \input; for preloaded Texinfo. - -b, --batch No interaction. - -c, --clean Remove all auxiliary files. - -D, --debug Turn on shell debugging (set -x). - -e, --expand Force macro expansion using makeinfo. - -I DIR Search DIR for Texinfo files. - -h, --help Display this help and exit successfully. - -l, --language=LANG Specify the LANG of FILE: LaTeX or Texinfo. - -p, --pdf Use pdftex or pdflatex for processing. - -q, --quiet No output unless errors (implies --batch). - -s, --silent Same as --quiet. - -t, --texinfo=CMD Insert CMD after @setfilename in copy of input file. - Multiple values accumulate. - -v, --version Display version information and exit successfully. - -V, --verbose Report on what is done. +Operation modes: + -b, --batch no interaction + -c, --clean remove all auxiliary files + -D, --debug turn on shell debugging (set -x) + -h, --help display this help and exit successfully + -o, --output=OFILE leave output in OFILE (implies --clean); + Only one input FILE may be specified in this case + -q, --quiet no output unless errors (implies --batch) + -s, --silent same as --quiet + -v, --version display version information and exit successfully + -V, --verbose report on what is done + +TeX tuning: + -@ use @input instead of \input; for preloaded Texinfo + -e, -E, --expand force macro expansion using makeinfo + -I DIR search DIR for Texinfo files + -l, --language=LANG specify the LANG of FILE (LaTeX or Texinfo) + -p, --pdf use pdftex or pdflatex for processing + -t, --texinfo=CMD insert CMD after @setfilename in copy of input file + multiple values accumulate The values of the BIBTEX, LATEX (or PDFLATEX), MAKEINDEX, MAKEINFO, TEX (or PDFTEX), and TEXINDEX environment variables are used to run those commands, if they are set. Email bug reports to <bug-texinfo@gnu.org>, -general questions and discussion to <help-texinfo@gnu.org>." +general questions and discussion to <help-texinfo@gnu.org>. +Texinfo home page: http://www.gnu.org/software/texinfo/" # Initialize variables for option overriding and otherwise. # Don't use `unset' since old bourne shells don't have this command. # Instead, assign them an empty value. -escape='\' batch=false # eval for batch mode clean= debug= +escape='\' expand= # t for expansion via makeinfo +miincludes= # makeinfo include path oformat=dvi +oname= # --output +quiet= # by default let the tools' message be displayed set_language= -miincludes= # makeinfo include path textra= tmpdir=${TMPDIR:-/tmp}/t2d$$ # avoid collisions on 8.3 filesystems. -txincludes= # TEXINPUTS extensions +txincludes= # TEXINPUTS extensions, with trailing colon txiprereq=19990129 # minimum texinfo.tex version to have macro expansion -quiet= # by default let the tools' message be displayed verbose=false # echo for verbose mode orig_pwd=`pwd` @@ -98,6 +105,12 @@ else path_sep=":" fi +# Pacify verbose cds. +CDPATH=${ZSH_VERSION+.}$path_sep + +# In case someone crazy insists on using grep -E. +: ${EGREP=egrep} + # Save this so we can construct a new TEXINPUTS path for each file. TEXINPUTS_orig="$TEXINPUTS" # Unfortunately makeindex does not read TEXINPUTS. @@ -136,14 +149,21 @@ while test x"$1" != x"$arg_sep"; do -q | -s | --q* | --s*) quiet=t; batch=eval;; -c | --c*) clean=t;; -D | --d*) debug=t;; - -e | --e*) expand=t;; + -e | -E | --e*) expand=t;; -h | --h*) echo "$usage"; exit 0;; -I | --I*) shift miincludes="$miincludes -I $1" - txincludes="$txincludes$path_sep$1" + txincludes="$txincludes$1$path_sep" ;; -l | --l*) shift; set_language=$1;; + -o | --o*) + shift + clean=t + case "$1" in + /* | ?:/*) oname=$1;; + *) oname="$orig_pwd/$1";; + esac;; -p | --p*) oformat=pdf;; -t | --t*) shift; textra="$textra\\ $1";; @@ -168,11 +188,20 @@ done shift # Interpret remaining command line args as filenames. -if test $# = 0; then +case $# in + 0) echo "$0: Missing file arguments." >&2 echo "$0: Try \`--help' for more information." >&2 exit 2 -fi + ;; + 1) ;; + *) + if test -n "$oname"; then + echo "$0: Can't use option \`--output' with more than one argument." >&2 + exit 2 + fi + ;; +esac # Prepare the temporary directory. Remove it at exit, unless debugging. if test -z "$debug"; then @@ -205,14 +234,23 @@ cat <<EOF >$comment_iftex_sed s/^@c texi2dvi// } } -/^@html/,/^@end html/d -/^@ifhtml/,/^@end ifhtml/d -/^@ifnottex/,/^@end ifnottex/d +/^@html/,/^@end html/{ + s/^/@c (texi2dvi)/ +} +/^@ifhtml/,/^@end ifhtml/{ + s/^/@c (texi2dvi)/ +} +/^@ifnottex/,/^@end ifnottex/{ + s/^/@c (texi2dvi)/ +} /^@ifinfo/,/^@end ifinfo/{ /^@node/p /^@menu/,/^@end menu/p - d + t + s/^/@c (texi2dvi)/ } +s/^@ifnotinfo/@c texi2dvi@ifnotinfo/ +s/^@end ifnotinfo/@c texi2dvi@end ifnotinfo/ EOF # Uncommenting is simple: Remove any leading `@c texi2dvi'. uncomment_iftex_sed=$utildir/uncomment.sed @@ -230,7 +268,7 @@ cat <<\EOF >$get_xref_files # Get list of xref files (indexes, tables and lists). # Find all files having root filename with a two-letter extension, # saves the ones that are really Texinfo-related files. .?o? catches -# LaTeX tables and lists. +# many files: .toc, .log, LaTeX tables and lists, FiXme's .lox, maybe more. for this_file in "$1".?o? "$1".aux "$1".?? "$1".idx; do # If file is empty, skip it. test -s "$this_file" || continue @@ -273,7 +311,7 @@ for command_line_filename in ${1+"$@"}; do # If the COMMAND_LINE_FILENAME is not absolute (e.g., --debug.tex), # prepend `./' in order to avoid that the tools take it as an option. - echo "$command_line_filename" | egrep '^(/|[A-z]:/)' >/dev/null \ + echo "$command_line_filename" | $EGREP '^(/|[A-z]:/)' >/dev/null \ || command_line_filename="./$command_line_filename" # See if the file exists. If it doesn't we're in trouble since, even @@ -314,22 +352,67 @@ for command_line_filename in ${1+"$@"}; do # Make all those directories and give up if we can't succeed. mkdir $tmpdir_src $tmpdir_xtr $tmpdir_bak || exit 1 - # Source file might include additional sources. Put `.' and - # directory where source file(s) reside in TEXINPUTS before anything - # else. `.' goes first to ensure that any old .aux, .cps, + # Source file might include additional sources. + # We want `.:$orig_pwd' before anything else. (We'll add `.:' later + # after all other directories have been turned into absolute paths.) + # `.' goes first to ensure that any old .aux, .cps, # etc. files in ${directory} don't get used in preference to fresher # files in `.'. Include orig_pwd in case we are in clean mode, where # we've cd'd to a temp directory. - common=".$path_sep$orig_pwd$path_sep$filename_dir$path_sep$txincludes$path_sep" + common="$orig_pwd$path_sep$filename_dir$path_sep$txincludes" TEXINPUTS="$common$TEXINPUTS_orig" INDEXSTYLE="$common$INDEXSTYLE_orig" + # Convert relative paths to absolute paths, so we can run in another + # directory (e.g., in --clean mode, or during the macro-support + # detection.) + # + # Empty path components are meaningful to tex. We rewrite them + # as `EMPTY' so they don't get lost when we split on $path_sep. + TEXINPUTS=`echo $TEXINPUTS |sed 's/^:/EMPTY:/;s/:$/:EMPTY/;s/::/:EMPTY:/g'` + INDEXSTYLE=`echo $INDEXSTYLE |sed 's/^:/EMPTY:/;s/:$/:EMPTY/;s/::/:EMPTY:/g'` + save_IFS=$IFS + IFS=$path_sep + set x $TEXINPUTS; shift + TEXINPUTS=. + for dir + do + case $dir in + EMPTY) + TEXINPUTS=$TEXINPUTS$path_sep + ;; + [\\/]* | ?:[\\/]*) # Absolute paths don't need to be expansed. + TEXINPUTS=$TEXINPUTS$path_sep$dir + ;; + *) + abs=`cd "$dir" && pwd` && TEXINPUTS=$TEXINPUTS$path_sep$abs + ;; + esac + done + set x $INDEXSTYLE; shift + INDEXSTYLE=. + for dir + do + case $dir in + EMPTY) + INDEXSTYLE=$INDEXSTYLE$path_sep + ;; + [\\/]* | ?:[\\/]*) # Absolute paths don't need to be expansed. + INDEXSTYLE=$INDEXSTYLE$path_sep$dir + ;; + *) + abs=`cd "$dir" && pwd` && INDEXSTYLE=$INDEXSTYLE$path_sep$abs + ;; + esac + done + IFS=$save_IFS + # If the user explicitly specified the language, use that. # Otherwise, if the first line is \input texinfo, assume it's texinfo. # Otherwise, guess from the file extension. if test -n "$set_language"; then language=$set_language - elif sed 1q "$command_line_filename" | fgrep 'input texinfo' >/dev/null; then + elif sed 1q "$command_line_filename" | grep 'input texinfo' >/dev/null; then language=texinfo else language= @@ -373,9 +456,9 @@ for command_line_filename in ${1+"$@"}; do txiversion_tex=txiversion.tex echo '\input texinfo.tex @bye' >$tmpdir/$txiversion_tex # Run in the tmpdir to avoid leaving files. - eval `cd $tmpdir >/dev/null \ - && $tex $txiversion_tex 2>/dev/null \ -| sed -n 's/^.*\[\(.*\)version \(....\)-\(..\)-\(..\).*$/txiformat=\1 txiversion="\2\3\4"/p'` + eval `cd $tmpdir >/dev/null && + $tex $txiversion_tex 2>/dev/null | + sed -n 's/^.*\[\(.*\)version \(....\)-\(..\)-\(..\).*$/txiformat=\1 txiversion="\2\3\4"/p'` $verbose "texinfo.tex preloaded as \`$txiformat', version is \`$txiversion' ..." if test "$txiprereq" -le "$txiversion" >/dev/null 2>&1; then makeinfo= @@ -467,10 +550,14 @@ for command_line_filename in ${1+"$@"}; do # What we'll run texindex on -- exclude non-index files. # Since we know index files are last, it is correct to remove everything - # before .aux and .?o?. + # before .aux and .?o?. But don't really do <anything>o<anything> + # -- don't match whitespace as <anything>. + # Otherwise, if orig_xref_files contains something like + # foo.xo foo.whatever + # the space after the o will get matched. index_files=`echo "$orig_xref_files" \ | sed "s!.*\.aux!!g; - s!./$filename_noext\..o.!!g; + s!./$filename_noext\.[^ ]o[^ ]!!g; s/^[ ]*//;s/[ ]*$//"` # Run texindex (or makeindex) on current index files. If they # already exist, and after running TeX a first time the index @@ -489,8 +576,8 @@ for command_line_filename in ${1+"$@"}; do # Prevent $ESCAPE from being interpreted by the shell if it happens # to be `/'. $batch tex_args="\\${escape}nonstopmode\ \\${escape}input" - $verbose "Running $cmd ..." cmd="$tex $tex_args $filename_input" + $verbose "Running $cmd ..." if $cmd >&5; then :; else echo "$0: $tex exited with bad status, quitting." >&2 echo "$0: see $filename_noext.log for errors." >&2 @@ -508,7 +595,7 @@ for command_line_filename in ${1+"$@"}; do # subdirs, since texi2dvi does not try to compare xref files in # subdirs. Performing xref files test is still good since LaTeX # does not report changes in xref files. - if fgrep "Rerun to get" "$filename_noext.log" >/dev/null 2>&1; then + if grep "Rerun to get" "$filename_noext.log" >/dev/null 2>&1; then finished= fi @@ -550,8 +637,13 @@ for command_line_filename in ${1+"$@"}; do # - the next file is processed in correct conditions # - the temporary file can be removed if test -n "$clean"; then - $verbose "Copying $oformat file from `pwd` to $orig_pwd" - cp -p "./$filename_noext.$oformat" "$orig_pwd" + if test -n "$oname"; then + dest=$oname + else + dest=$orig_pwd + fi + $verbose "Copying $oformat file from `pwd` to $dest" + cp -p "./$filename_noext.$oformat" "$dest" cd / # in case $orig_pwd is on a different drive (for DOS) cd $orig_pwd || exit 1 fi diff --git a/readline/emacs_keymap.c b/readline/emacs_keymap.c index ca9d134..c739953 100644 --- a/readline/emacs_keymap.c +++ b/readline/emacs_keymap.c @@ -278,7 +278,13 @@ KEYMAP_ENTRY_ARRAY emacs_standard_keymap = { { ISFUNC, rl_insert }, /* Latin capital letter Y with acute */ { ISFUNC, rl_insert }, /* Latin capital letter thorn (Icelandic) */ { ISFUNC, rl_insert }, /* Latin small letter sharp s (German) */ +#ifndef __MINGW32__ { ISFUNC, rl_insert }, /* Latin small letter a with grave */ +#else + /* Temporary - this is a bug in readline 5.1 that should be fixed in + readline 5.2. */ + { ISFUNC, 0 }, /* Must leave this unbound for the arrow keys to work. */ +#endif { ISFUNC, rl_insert }, /* Latin small letter a with acute */ { ISFUNC, rl_insert }, /* Latin small letter a with circumflex */ { ISFUNC, rl_insert }, /* Latin small letter a with tilde */ diff --git a/readline/examples/ChangeLog.gdb b/readline/examples/ChangeLog.gdb index 5ff9ba1..4896654 100644 --- a/readline/examples/ChangeLog.gdb +++ b/readline/examples/ChangeLog.gdb @@ -1,3 +1,7 @@ +2006-04-24 Daniel Jacobowitz <dan@codesourcery.com> + + Imported readline 5.1, and upstream patches 001-004. + 2002-02-24 Elena Zannoni <ezannoni@redhat.com> * ChangeLog.gdb: Rename from ChangeLog.Cygnus. diff --git a/readline/examples/Makefile.in b/readline/examples/Makefile.in index 72c9904..e27bbc0 100644 --- a/readline/examples/Makefile.in +++ b/readline/examples/Makefile.in @@ -40,6 +40,8 @@ INCLUDES = -I$(srcdir) -I$(top_srcdir) -I.. CCFLAGS = $(DEFS) $(LOCAL_CFLAGS) $(CPPFLAGS) $(INCLUDES) $(CFLAGS) LDFLAGS = -g -L.. @LDFLAGS@ +PURIFY = @PURIFY@ + READLINE_LIB = ../libreadline.a HISTORY_LIB = ../libhistory.a @@ -50,33 +52,35 @@ TERMCAP_LIB = @TERMCAP_LIB@ $(CC) $(CCFLAGS) -c $< EXECUTABLES = fileman rltest rl rlcat rlversion histexamp -OBJECTS = fileman.o rltest.o rl.o rlversion.o histexamp.o +OBJECTS = fileman.o rltest.o rl.o rlcat.o rlversion.o histexamp.o all: $(EXECUTABLES) -everything: all rlfe +everything: all rl: rl.o $(READLINE_LIB) - $(CC) $(LDFLAGS) -o $@ rl.o -lreadline $(TERMCAP_LIB) + $(PURIFY) $(CC) $(LDFLAGS) -o $@ rl.o $(READLINE_LIB) $(TERMCAP_LIB) rlcat: rlcat.o $(READLINE_LIB) - $(CC) $(LDFLAGS) -o $@ rlcat.o -lreadline $(TERMCAP_LIB) + $(PURIFY) $(CC) $(LDFLAGS) -o $@ rlcat.o $(READLINE_LIB) $(TERMCAP_LIB) fileman: fileman.o $(READLINE_LIB) - $(CC) $(LDFLAGS) -o $@ fileman.o -lreadline $(TERMCAP_LIB) + $(PURIFY) $(CC) $(LDFLAGS) -o $@ fileman.o $(READLINE_LIB) $(TERMCAP_LIB) rltest: rltest.o $(READLINE_LIB) - $(CC) $(LDFLAGS) -o $@ rltest.o -lreadline $(TERMCAP_LIB) + $(PURIFY) $(CC) $(LDFLAGS) -o $@ rltest.o $(READLINE_LIB) $(TERMCAP_LIB) + +rlptytest: rlptytest.o $(READLINE_LIB) + $(PURIFY) $(CC) $(LDFLAGS) -o $@ rlptytest.o $(READLINE_LIB) $(TERMCAP_LIB) rlversion: rlversion.o $(READLINE_LIB) - $(CC) $(LDFLAGS) -o $@ rlversion.o -lreadline $(TERMCAP_LIB) + $(CC) $(LDFLAGS) -o $@ rlversion.o $(READLINE_LIB) $(TERMCAP_LIB) histexamp: histexamp.o $(HISTORY_LIB) - $(CC) $(LDFLAGS) -o $@ histexamp.o -lhistory $(TERMCAP_LIB) + $(PURIFY) $(CC) $(LDFLAGS) -o $@ histexamp.o -lhistory $(TERMCAP_LIB) clean mostlyclean: $(RM) $(OBJECTS) $(RM) $(EXECUTABLES) *.exe - $(RM) rlfe.o rlfe distclean maintainer-clean: clean $(RM) Makefile @@ -86,19 +90,13 @@ rltest.o: rltest.c rl.o: rl.c rlversion.o: rlversion.c histexamp.o: histexamp.c +rlcat.o: rlcat.c +rlptytest.o: rlptytest.c fileman.o: $(top_srcdir)/readline.h rltest.o: $(top_srcdir)/readline.h rl.o: $(top_srcdir)/readline.h rlversion.o: $(top_srcdir)/readline.h histexamp.o: $(top_srcdir)/history.h - -# Stuff for Per Bothner's `rlfe' program - -rlfe: rlfe.o $(READLINE_LIB) $(HISTORY_LIB) - $(CC) $(LDFLAGS) -o $@ rlfe.o -lreadline -lhistory ${TERMCAP_LIB} - -rlfe.o: rlfe.c - -rlfe.o: $(top_srcdir)/readline.h -rlfe.o: $(top_srcdir)/history.h +rlcat.o: $(top_srcdir)/readline.h $(top_srcdir)/history.h +rlptytest.o: $(top_srcdir)/readline.h $(top_srcdir)/history.h diff --git a/readline/examples/histexamp.c b/readline/examples/histexamp.c index 45651df..4f059c1 100644 --- a/readline/examples/histexamp.c +++ b/readline/examples/histexamp.c @@ -26,14 +26,17 @@ # include <readline/history.h> #endif +#include <string.h> + main (argc, argv) int argc; char **argv; { char line[1024], *t; - int len, done = 0; + int len, done; line[0] = 0; + done = 0; using_history (); while (!done) @@ -42,71 +45,80 @@ main (argc, argv) fflush (stdout); t = fgets (line, sizeof (line) - 1, stdin); if (t && *t) - { - len = strlen (t); - if (t[len - 1] == '\n') - t[len - 1] = '\0'; - } + { + len = strlen (t); + if (t[len - 1] == '\n') + t[len - 1] = '\0'; + } if (!t) - strcpy (line, "quit"); + strcpy (line, "quit"); if (line[0]) - { - char *expansion; - int result; + { + char *expansion; + int result; - using_history (); + using_history (); - result = history_expand (line, &expansion); - if (result) - fprintf (stderr, "%s\n", expansion); + result = history_expand (line, &expansion); + if (result) + fprintf (stderr, "%s\n", expansion); - if (result < 0 || result == 2) - { - free (expansion); - continue; - } + if (result < 0 || result == 2) + { + free (expansion); + continue; + } - add_history (expansion); - strncpy (line, expansion, sizeof (line) - 1); - free (expansion); - } + add_history (expansion); + strncpy (line, expansion, sizeof (line) - 1); + free (expansion); + } if (strcmp (line, "quit") == 0) - done = 1; + done = 1; else if (strcmp (line, "save") == 0) - write_history ("history_file"); + write_history ("history_file"); else if (strcmp (line, "read") == 0) - read_history ("history_file"); + read_history ("history_file"); else if (strcmp (line, "list") == 0) - { - register HIST_ENTRY **the_list; - register int i; - - the_list = history_list (); - if (the_list) - for (i = 0; the_list[i]; i++) - printf ("%d: %s\n", i + history_base, the_list[i]->line); - } + { + register HIST_ENTRY **the_list; + register int i; + time_t tt; + char timestr[128]; + + the_list = history_list (); + if (the_list) + for (i = 0; the_list[i]; i++) + { + tt = history_get_time (the_list[i]); + if (tt) + strftime (timestr, sizeof (timestr), "%a %R", localtime(&tt)); + else + strcpy (timestr, "??"); + printf ("%d: %s: %s\n", i + history_base, timestr, the_list[i]->line); + } + } else if (strncmp (line, "delete", 6) == 0) - { - int which; - if ((sscanf (line + 6, "%d", &which)) == 1) - { - HIST_ENTRY *entry = remove_history (which); - if (!entry) - fprintf (stderr, "No such entry %d\n", which); - else - { - free (entry->line); - free (entry); - } - } - else - { - fprintf (stderr, "non-numeric arg given to `delete'\n"); - } - } + { + int which; + if ((sscanf (line + 6, "%d", &which)) == 1) + { + HIST_ENTRY *entry = remove_history (which); + if (!entry) + fprintf (stderr, "No such entry %d\n", which); + else + { + free (entry->line); + free (entry); + } + } + else + { + fprintf (stderr, "non-numeric arg given to `delete'\n"); + } + } } } diff --git a/readline/examples/rl.c b/readline/examples/rl.c index d260489..c608c15 100644 --- a/readline/examples/rl.c +++ b/readline/examples/rl.c @@ -31,12 +31,19 @@ #include <stdio.h> #include <sys/types.h> -#include "posixstat.h" + +#ifdef HAVE_STDLIB_H +# include <stdlib.h> +#else +extern void exit(); +#endif #if defined (READLINE_LIBRARY) +# include "posixstat.h" # include "readline.h" # include "history.h" #else +# include <sys/stat.h> # include <readline/readline.h> # include <readline/history.h> #endif diff --git a/readline/examples/rlcat.c b/readline/examples/rlcat.c index 176b9f4..33aea4a 100644 --- a/readline/examples/rlcat.c +++ b/readline/examples/rlcat.c @@ -40,6 +40,12 @@ #include <string.h> #include <errno.h> +#ifdef HAVE_STDLIB_H +# include <stdlib.h> +#else +extern void exit(); +#endif + #ifndef errno extern int errno; #endif diff --git a/readline/examples/rlfe.c b/readline/examples/rlfe.c deleted file mode 100644 index d634d7c..0000000 --- a/readline/examples/rlfe.c +++ /dev/null @@ -1,1042 +0,0 @@ -/* A front-end using readline to "cook" input lines for Kawa. - * - * Copyright (C) 1999 Per Bothner - * - * This front-end 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, or (at your option) - * any later version. - * - * Some code from Johnson & Troan: "Linux Application Development" - * (Addison-Wesley, 1998) was used directly or for inspiration. - */ - -/* PROBLEMS/TODO: - * - * Only tested under Linux; needs to be ported. - * - * When running mc -c under the Linux console, mc does not recognize - * mouse clicks, which mc does when not running under fep. - * - * Pasting selected text containing tabs is like hitting the tab character, - * which invokes readline completion. We don't want this. I don't know - * if this is fixable without integrating fep into a terminal emulator. - * - * Echo suppression is a kludge, but can only be avoided with better kernel - * support: We need a tty mode to disable "real" echoing, while still - * letting the inferior think its tty driver to doing echoing. - * Stevens's book claims SCR$ and BSD4.3+ have TIOCREMOTE. - * - * The latest readline may have some hooks we can use to avoid having - * to back up the prompt. - * - * Desirable readline feature: When in cooked no-echo mode (e.g. password), - * echo characters are they are types with '*', but remove them when done. - * - * A synchronous output while we're editing an input line should be - * inserted in the output view *before* the input line, so that the - * lines being edited (with the prompt) float at the end of the input. - * - * A "page mode" option to emulate more/less behavior: At each page of - * output, pause for a user command. This required parsing the output - * to keep track of line lengths. It also requires remembering the - * output, if we want an option to scroll back, which suggests that - * this should be integrated with a terminal emulator like xterm. - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <stdio.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <signal.h> -#include <netdb.h> -#include <stdlib.h> -#include <errno.h> -#include <grp.h> -#include <string.h> -#include <sys/stat.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <termios.h> -#include <limits.h> -#include <dirent.h> - -#ifdef READLINE_LIBRARY -# include "readline.h" -# include "history.h" -#else -# include <readline/readline.h> -# include <readline/history.h> -#endif - -#ifndef COMMAND -#define COMMAND "/bin/sh" -#endif -#ifndef COMMAND_ARGS -#define COMMAND_ARGS COMMAND -#endif - -#ifndef HAVE_MEMMOVE -#ifndef memmove -# if __GNUC__ > 1 -# define memmove(d, s, n) __builtin_memcpy(d, s, n) -# else -# define memmove(d, s, n) memcpy(d, s, n) -# endif -#else -# define memmove(d, s, n) memcpy(d, s, n) -#endif -#endif - -#define APPLICATION_NAME "Rlfe" - -#ifndef errno -extern int errno; -#endif - -extern int optind; -extern char *optarg; - -static char *progname; -static char *progversion; - -static int in_from_inferior_fd; -static int out_to_inferior_fd; - -/* Unfortunately, we cannot safely display echo from the inferior process. - The reason is that the echo bit in the pty is "owned" by the inferior, - and if we try to turn it off, we could confuse the inferior. - Thus, when echoing, we get echo twice: First readline echoes while - we're actually editing. Then we send the line to the inferior, and the - terminal driver send back an extra echo. - The work-around is to remember the input lines, and when we see that - line come back, we supress the output. - A better solution (supposedly available on SVR4) would be a smarter - terminal driver, with more flags ... */ -#define ECHO_SUPPRESS_MAX 1024 -char echo_suppress_buffer[ECHO_SUPPRESS_MAX]; -int echo_suppress_start = 0; -int echo_suppress_limit = 0; - -/* #define DEBUG */ - -static FILE *logfile = NULL; - -#ifdef DEBUG -FILE *debugfile = NULL; -#define DPRINT0(FMT) (fprintf(debugfile, FMT), fflush(debugfile)) -#define DPRINT1(FMT, V1) (fprintf(debugfile, FMT, V1), fflush(debugfile)) -#define DPRINT2(FMT, V1, V2) (fprintf(debugfile, FMT, V1, V2), fflush(debugfile)) -#else -#define DPRINT0(FMT) /* Do nothing */ -#define DPRINT1(FMT, V1) /* Do nothing */ -#define DPRINT2(FMT, V1, V2) /* Do nothing */ -#endif - -struct termios orig_term; - -static int rlfe_directory_completion_hook __P((char **)); -static int rlfe_directory_rewrite_hook __P((char **)); -static char *rlfe_filename_completion_function __P((const char *, int)); - -/* Pid of child process. */ -static pid_t child = -1; - -static void -sig_child (int signo) -{ - int status; - wait (&status); - DPRINT0 ("(Child process died.)\n"); - tcsetattr(STDIN_FILENO, TCSANOW, &orig_term); - exit (0); -} - -volatile int propagate_sigwinch = 0; - -/* sigwinch_handler - * propagate window size changes from input file descriptor to - * master side of pty. - */ -void sigwinch_handler(int signal) { - propagate_sigwinch = 1; -} - -/* get_master_pty() takes a double-indirect character pointer in which - * to put a slave name, and returns an integer file descriptor. - * If it returns < 0, an error has occurred. - * Otherwise, it has returned the master pty file descriptor, and fills - * in *name with the name of the corresponding slave pty. - * Once the slave pty has been opened, you are responsible to free *name. - */ - -int get_master_pty(char **name) { - int i, j; - /* default to returning error */ - int master = -1; - - /* create a dummy name to fill in */ - *name = strdup("/dev/ptyXX"); - - /* search for an unused pty */ - for (i=0; i<16 && master <= 0; i++) { - for (j=0; j<16 && master <= 0; j++) { - (*name)[5] = 'p'; - (*name)[8] = "pqrstuvwxyzPQRST"[i]; - (*name)[9] = "0123456789abcdef"[j]; - /* open the master pty */ - if ((master = open(*name, O_RDWR)) < 0) { - if (errno == ENOENT) { - /* we are out of pty devices */ - free (*name); - return (master); - } - } - else { - /* By substituting a letter, we change the master pty - * name into the slave pty name. - */ - (*name)[5] = 't'; - if (access(*name, R_OK|W_OK) != 0) - { - close(master); - master = -1; - } - } - } - } - if ((master < 0) && (i == 16) && (j == 16)) { - /* must have tried every pty unsuccessfully */ - free (*name); - return (master); - } - - (*name)[5] = 't'; - - return (master); -} - -/* get_slave_pty() returns an integer file descriptor. - * If it returns < 0, an error has occurred. - * Otherwise, it has returned the slave file descriptor. - */ - -int get_slave_pty(char *name) { - struct group *gptr; - gid_t gid; - int slave = -1; - - /* chown/chmod the corresponding pty, if possible. - * This will only work if the process has root permissions. - * Alternatively, write and exec a small setuid program that - * does just this. - */ - if ((gptr = getgrnam("tty")) != 0) { - gid = gptr->gr_gid; - } else { - /* if the tty group does not exist, don't change the - * group on the slave pty, only the owner - */ - gid = -1; - } - - /* Note that we do not check for errors here. If this is code - * where these actions are critical, check for errors! - */ - chown(name, getuid(), gid); - /* This code only makes the slave read/writeable for the user. - * If this is for an interactive shell that will want to - * receive "write" and "wall" messages, OR S_IWGRP into the - * second argument below. - */ - chmod(name, S_IRUSR|S_IWUSR); - - /* open the corresponding slave pty */ - slave = open(name, O_RDWR); - return (slave); -} - -/* Certain special characters, such as ctrl/C, we want to pass directly - to the inferior, rather than letting readline handle them. */ - -static char special_chars[20]; -static int special_chars_count; - -static void -add_special_char(int ch) -{ - if (ch != 0) - special_chars[special_chars_count++] = ch; -} - -static int eof_char; - -static int -is_special_char(int ch) -{ - int i; -#if 0 - if (ch == eof_char && rl_point == rl_end) - return 1; -#endif - for (i = special_chars_count; --i >= 0; ) - if (special_chars[i] == ch) - return 1; - return 0; -} - -static char buf[1024]; -/* buf[0 .. buf_count-1] is the what has been emitted on the current line. - It is used as the readline prompt. */ -static int buf_count = 0; - -int num_keys = 0; - -static void -null_prep_terminal (int meta) -{ -} - -static void -null_deprep_terminal () -{ -} - -char pending_special_char; - -static void -line_handler (char *line) -{ - if (line == NULL) - { - char buf[1]; - DPRINT0("saw eof!\n"); - buf[0] = '\004'; /* ctrl/d */ - write (out_to_inferior_fd, buf, 1); - } - else - { - static char enter[] = "\r"; - /* Send line to inferior: */ - int length = strlen (line); - if (length > ECHO_SUPPRESS_MAX-2) - { - echo_suppress_start = 0; - echo_suppress_limit = 0; - } - else - { - if (echo_suppress_limit + length > ECHO_SUPPRESS_MAX - 2) - { - if (echo_suppress_limit - echo_suppress_start + length - <= ECHO_SUPPRESS_MAX - 2) - { - memmove (echo_suppress_buffer, - echo_suppress_buffer + echo_suppress_start, - echo_suppress_limit - echo_suppress_start); - echo_suppress_limit -= echo_suppress_start; - echo_suppress_start = 0; - } - else - { - echo_suppress_limit = 0; - } - echo_suppress_start = 0; - } - memcpy (echo_suppress_buffer + echo_suppress_limit, - line, length); - echo_suppress_limit += length; - echo_suppress_buffer[echo_suppress_limit++] = '\r'; - echo_suppress_buffer[echo_suppress_limit++] = '\n'; - } - write (out_to_inferior_fd, line, length); - if (pending_special_char == 0) - { - write (out_to_inferior_fd, enter, sizeof(enter)-1); - if (*line) - add_history (line); - } - free (line); - } - rl_callback_handler_remove (); - buf_count = 0; - num_keys = 0; - if (pending_special_char != 0) - { - write (out_to_inferior_fd, &pending_special_char, 1); - pending_special_char = 0; - } -} - -/* Value of rl_getc_function. - Use this because readline should read from stdin, not rl_instream, - points to the pty (so readline has monitor its terminal modes). */ - -int -my_rl_getc (FILE *dummy) -{ - int ch = rl_getc (stdin); - if (is_special_char (ch)) - { - pending_special_char = ch; - return '\r'; - } - return ch; -} - -static void -usage() -{ - fprintf (stderr, "%s: usage: %s [-l filename] [-a] [-n appname] [-hv] [command [arguments...]]\n", - progname, progname); -} - -int -main(int argc, char** argv) -{ - char *path; - int i, append; - int master; - char *name, *logfname, *appname; - int in_from_tty_fd; - struct sigaction act; - struct winsize ws; - struct termios t; - int maxfd; - fd_set in_set; - static char empty_string[1] = ""; - char *prompt = empty_string; - int ioctl_err = 0; - - if ((progname = strrchr (argv[0], '/')) == 0) - progname = argv[0]; - else - progname++; - progversion = RL_LIBRARY_VERSION; - - append = 0; - appname = APPLICATION_NAME; - logfname = (char *)NULL; - - while ((i = getopt (argc, argv, "ahl:n:v")) != EOF) - { - switch (i) - { - case 'l': - logfname = optarg; - break; - case 'n': - appname = optarg; - break; - case 'a': - append = 1; - break; - case 'h': - usage (); - exit (0); - case 'v': - fprintf (stderr, "%s version %s\n", progname, progversion); - exit (0); - default: - usage (); - exit (2); - } - } - - argc -= optind; - argv += optind; - - if (logfname) - { - logfile = fopen (logfname, append ? "a" : "w"); - if (logfile == 0) - fprintf (stderr, "%s: warning: could not open log file %s: %s\n", - progname, logfname, strerror (errno)); - } - - rl_readline_name = appname; - -#ifdef DEBUG - debugfile = fopen("LOG", "w"); -#endif - - if ((master = get_master_pty(&name)) < 0) - { - perror("ptypair: could not open master pty"); - exit(1); - } - - DPRINT1("pty name: '%s'\n", name); - - /* set up SIGWINCH handler */ - act.sa_handler = sigwinch_handler; - sigemptyset(&(act.sa_mask)); - act.sa_flags = 0; - if (sigaction(SIGWINCH, &act, NULL) < 0) - { - perror("ptypair: could not handle SIGWINCH "); - exit(1); - } - - if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) < 0) - { - perror("ptypair: could not get window size"); - exit(1); - } - - if ((child = fork()) < 0) - { - perror("cannot fork"); - exit(1); - } - - if (child == 0) - { - int slave; /* file descriptor for slave pty */ - - /* We are in the child process */ - close(master); - -#ifdef TIOCSCTTY - if ((slave = get_slave_pty(name)) < 0) - { - perror("ptypair: could not open slave pty"); - exit(1); - } - free(name); -#endif - - /* We need to make this process a session group leader, because - * it is on a new PTY, and things like job control simply will - * not work correctly unless there is a session group leader - * and process group leader (which a session group leader - * automatically is). This also disassociates us from our old - * controlling tty. - */ - if (setsid() < 0) - { - perror("could not set session leader"); - } - - /* Tie us to our new controlling tty. */ -#ifdef TIOCSCTTY - if (ioctl(slave, TIOCSCTTY, NULL)) - { - perror("could not set new controlling tty"); - } -#else - if ((slave = get_slave_pty(name)) < 0) - { - perror("ptypair: could not open slave pty"); - exit(1); - } - free(name); -#endif - - /* make slave pty be standard in, out, and error */ - dup2(slave, STDIN_FILENO); - dup2(slave, STDOUT_FILENO); - dup2(slave, STDERR_FILENO); - - /* at this point the slave pty should be standard input */ - if (slave > 2) - { - close(slave); - } - - /* Try to restore window size; failure isn't critical */ - if (ioctl(STDOUT_FILENO, TIOCSWINSZ, &ws) < 0) - { - perror("could not restore window size"); - } - - /* now start the shell */ - { - static char* command_args[] = { COMMAND_ARGS, NULL }; - if (argc < 1) - execvp(COMMAND, command_args); - else - execvp(argv[0], &argv[0]); - } - - /* should never be reached */ - exit(1); - } - - /* parent */ - signal (SIGCHLD, sig_child); - free(name); - - /* Note that we only set termios settings for standard input; - * the master side of a pty is NOT a tty. - */ - tcgetattr(STDIN_FILENO, &orig_term); - - t = orig_term; - eof_char = t.c_cc[VEOF]; - /* add_special_char(t.c_cc[VEOF]);*/ - add_special_char(t.c_cc[VINTR]); - add_special_char(t.c_cc[VQUIT]); - add_special_char(t.c_cc[VSUSP]); -#if defined (VDISCARD) - add_special_char(t.c_cc[VDISCARD]); -#endif - -#if 0 - t.c_lflag |= (ICANON | ISIG | ECHO | ECHOCTL | ECHOE | \ - ECHOK | ECHOKE | ECHONL | ECHOPRT ); -#else - t.c_lflag &= ~(ICANON | ISIG | ECHO | ECHOCTL | ECHOE | \ - ECHOK | ECHOKE | ECHONL | ECHOPRT ); -#endif - t.c_iflag |= IGNBRK; - t.c_cc[VMIN] = 1; - t.c_cc[VTIME] = 0; - tcsetattr(STDIN_FILENO, TCSANOW, &t); - in_from_inferior_fd = master; - out_to_inferior_fd = master; - rl_instream = fdopen (master, "r"); - rl_getc_function = my_rl_getc; - - rl_prep_term_function = null_prep_terminal; - rl_deprep_term_function = null_deprep_terminal; - rl_callback_handler_install (prompt, line_handler); - -#if 1 - rl_directory_completion_hook = rlfe_directory_completion_hook; - rl_completion_entry_function = rlfe_filename_completion_function; -#else - rl_directory_rewrite_hook = rlfe_directory_rewrite_hook; -#endif - - in_from_tty_fd = STDIN_FILENO; - FD_ZERO (&in_set); - maxfd = in_from_inferior_fd > in_from_tty_fd ? in_from_inferior_fd - : in_from_tty_fd; - for (;;) - { - int num; - FD_SET (in_from_inferior_fd, &in_set); - FD_SET (in_from_tty_fd, &in_set); - - num = select(maxfd+1, &in_set, NULL, NULL, NULL); - - if (propagate_sigwinch) - { - struct winsize ws; - if (ioctl (STDIN_FILENO, TIOCGWINSZ, &ws) >= 0) - { - ioctl (master, TIOCSWINSZ, &ws); - } - propagate_sigwinch = 0; - continue; - } - - if (num <= 0) - { - perror ("select"); - exit (-1); - } - if (FD_ISSET (in_from_tty_fd, &in_set)) - { - extern int readline_echoing_p; - struct termios term_master; - int do_canon = 1; - int ioctl_ret; - - DPRINT1("[tty avail num_keys:%d]\n", num_keys); - - /* If we can't get tty modes for the master side of the pty, we - can't handle non-canonical-mode programs. Always assume the - master is in canonical echo mode if we can't tell. */ - ioctl_ret = tcgetattr(master, &term_master); - - if (ioctl_ret >= 0) - { - DPRINT2 ("echo:%d, canon:%d\n", - (term_master.c_lflag & ECHO) != 0, - (term_master.c_lflag & ICANON) != 0); - do_canon = (term_master.c_lflag & ICANON) != 0; - readline_echoing_p = (term_master.c_lflag & ECHO) != 0; - } - else - { - if (ioctl_err == 0) - DPRINT1("tcgetattr on master fd failed: errno = %d\n", errno); - ioctl_err = 1; - } - - if (do_canon == 0 && num_keys == 0) - { - char ch[10]; - int count = read (STDIN_FILENO, ch, sizeof(ch)); - write (out_to_inferior_fd, ch, count); - } - else - { - if (num_keys == 0) - { - int i; - /* Re-install callback handler for new prompt. */ - if (prompt != empty_string) - free (prompt); - prompt = malloc (buf_count + 1); - if (prompt == NULL) - prompt = empty_string; - else - { - memcpy (prompt, buf, buf_count); - prompt[buf_count] = '\0'; - DPRINT1("New prompt '%s'\n", prompt); -#if 0 /* ifdef HAVE_RL_ALREADY_PROMPTED -- doesn't work */ - rl_already_prompted = buf_count > 0; -#else - if (buf_count > 0) - write (1, "\r", 1); -#endif - } - rl_callback_handler_install (prompt, line_handler); - } - num_keys++; - rl_callback_read_char (); - } - } - else /* input from inferior. */ - { - int i; - int count; - int old_count; - if (buf_count > (sizeof(buf) >> 2)) - buf_count = 0; - count = read (in_from_inferior_fd, buf+buf_count, - sizeof(buf) - buf_count); - if (count <= 0) - { - DPRINT0 ("(Connection closed by foreign host.)\n"); - tcsetattr(STDIN_FILENO, TCSANOW, &orig_term); - exit (0); - } - old_count = buf_count; - - /* Do some minimal carriage return translation and backspace - processing before logging the input line. */ - if (logfile) - { -#ifndef __GNUC__ - char *b; -#else - char b[count + 1]; -#endif - int i, j; - -#ifndef __GNUC__ - b = malloc (count + 1); - if (b) { -#endif - for (i = 0; i < count; i++) - b[i] = buf[buf_count + i]; - b[i] = '\0'; - for (i = j = 0; i <= count; i++) - { - if (b[i] == '\r') - { - if (b[i+1] != '\n') - b[j++] = '\n'; - } - else if (b[i] == '\b') - { - if (i) - j--; - } - else - b[j++] = b[i]; - } - fprintf (logfile, "%s", b); - -#ifndef __GNUC__ - free (b); - } -#endif - } - - /* Look for any pending echo that we need to suppress. */ - while (echo_suppress_start < echo_suppress_limit - && count > 0 - && buf[buf_count] == echo_suppress_buffer[echo_suppress_start]) - { - count--; - buf_count++; - echo_suppress_start++; - } - - /* Write to the terminal anything that was not suppressed. */ - if (count > 0) - write (1, buf + buf_count, count); - - /* Finally, look for a prompt candidate. - * When we get around to going input (from the keyboard), - * we will consider the prompt to be anything since the last - * line terminator. So we need to save that text in the - * initial part of buf. However, anything before the - * most recent end-of-line is not interesting. */ - buf_count += count; -#if 1 - for (i = buf_count; --i >= old_count; ) -#else - for (i = buf_count - 1; i-- >= buf_count - count; ) -#endif - { - if (buf[i] == '\n' || buf[i] == '\r') - { - i++; - memmove (buf, buf+i, buf_count - i); - buf_count -= i; - break; - } - } - DPRINT2("-> i: %d, buf_count: %d\n", i, buf_count); - } - } -} - -/* - * - * FILENAME COMPLETION FOR RLFE - * - */ - -#ifndef PATH_MAX -# define PATH_MAX 1024 -#endif - -#define DIRSEP '/' -#define ISDIRSEP(x) ((x) == '/') -#define PATHSEP(x) (ISDIRSEP(x) || (x) == 0) - -#define DOT_OR_DOTDOT(x) \ - ((x)[0] == '.' && (PATHSEP((x)[1]) || \ - ((x)[1] == '.' && PATHSEP((x)[2])))) - -#define FREE(x) if (x) free(x) - -#define STRDUP(s, x) do { \ - s = strdup (x);\ - if (s == 0) \ - return ((char *)NULL); \ - } while (0) - -static int -get_inferior_cwd (path, psize) - char *path; - size_t psize; -{ - int n; - static char procfsbuf[PATH_MAX] = { '\0' }; - - if (procfsbuf[0] == '\0') - sprintf (procfsbuf, "/proc/%d/cwd", (int)child); - n = readlink (procfsbuf, path, psize); - if (n < 0) - return n; - if (n > psize) - return -1; - path[n] = '\0'; - return n; -} - -static int -rlfe_directory_rewrite_hook (dirnamep) - char **dirnamep; -{ - char *ldirname, cwd[PATH_MAX], *retdir, *ld; - int n, ldlen; - - ldirname = *dirnamep; - - if (*ldirname == '/') - return 0; - - n = get_inferior_cwd (cwd, sizeof(cwd) - 1); - if (n < 0) - return 0; - if (n == 0) /* current directory */ - { - cwd[0] = '.'; - cwd[1] = '\0'; - n = 1; - } - - /* Minimally canonicalize ldirname by removing leading `./' */ - for (ld = ldirname; *ld; ) - { - if (ISDIRSEP (ld[0])) - ld++; - else if (ld[0] == '.' && PATHSEP(ld[1])) - ld++; - else - break; - } - ldlen = (ld && *ld) ? strlen (ld) : 0; - - retdir = (char *)malloc (n + ldlen + 3); - if (retdir == 0) - return 0; - if (ldlen) - sprintf (retdir, "%s/%s", cwd, ld); - else - strcpy (retdir, cwd); - free (ldirname); - - *dirnamep = retdir; - - DPRINT1("rl_directory_rewrite_hook returns %s\n", retdir); - return 1; -} - -/* Translate *DIRNAMEP to be relative to the inferior's CWD. Leave a trailing - slash on the result. */ -static int -rlfe_directory_completion_hook (dirnamep) - char **dirnamep; -{ - char *ldirname, *retdir; - int n, ldlen; - - ldirname = *dirnamep; - - if (*ldirname == '/') - return 0; - - n = rlfe_directory_rewrite_hook (dirnamep); - if (n == 0) - return 0; - - ldirname = *dirnamep; - ldlen = (ldirname && *ldirname) ? strlen (ldirname) : 0; - - if (ldlen == 0 || ldirname[ldlen - 1] != '/') - { - retdir = (char *)malloc (ldlen + 3); - if (retdir == 0) - return 0; - if (ldlen) - strcpy (retdir, ldirname); - else - retdir[ldlen++] = '.'; - retdir[ldlen] = '/'; - retdir[ldlen+1] = '\0'; - free (ldirname); - - *dirnamep = retdir; - } - - DPRINT1("rl_directory_completion_hook returns %s\n", retdir); - return 1; -} - -static char * -rlfe_filename_completion_function (text, state) - const char *text; - int state; -{ - static DIR *directory; - static char *filename = (char *)NULL; - static char *dirname = (char *)NULL, *ud = (char *)NULL; - static int flen, udlen; - char *temp; - struct dirent *dentry; - - if (state == 0) - { - if (directory) - { - closedir (directory); - directory = 0; - } - FREE (dirname); - FREE (filename); - FREE (ud); - - if (text && *text) - STRDUP (filename, text); - else - { - filename = malloc(1); - if (filename == 0) - return ((char *)NULL); - filename[0] = '\0'; - } - dirname = (text && *text) ? strdup (text) : strdup ("."); - if (dirname == 0) - return ((char *)NULL); - - temp = strrchr (dirname, '/'); - if (temp) - { - strcpy (filename, ++temp); - *temp = '\0'; - } - else - { - dirname[0] = '.'; - dirname[1] = '\0'; - } - - STRDUP (ud, dirname); - udlen = strlen (ud); - - rlfe_directory_completion_hook (&dirname); - - directory = opendir (dirname); - flen = strlen (filename); - - rl_filename_completion_desired = 1; - } - - dentry = 0; - while (directory && (dentry = readdir (directory))) - { - if (flen == 0) - { - if (DOT_OR_DOTDOT(dentry->d_name) == 0) - break; - } - else - { - if ((dentry->d_name[0] == filename[0]) && - (strlen (dentry->d_name) >= flen) && - (strncmp (filename, dentry->d_name, flen) == 0)) - break; - } - } - - if (dentry == 0) - { - if (directory) - { - closedir (directory); - directory = 0; - } - FREE (dirname); - FREE (filename); - FREE (ud); - dirname = filename = ud = 0; - return ((char *)NULL); - } - - if (ud == 0 || (ud[0] == '.' && ud[1] == '\0')) - temp = strdup (dentry->d_name); - else - { - temp = malloc (1 + udlen + strlen (dentry->d_name)); - strcpy (temp, ud); - strcpy (temp + udlen, dentry->d_name); - } - return (temp); -} diff --git a/readline/examples/rltest.c b/readline/examples/rltest.c index 99f083b..cb67bab 100644 --- a/readline/examples/rltest.c +++ b/readline/examples/rltest.c @@ -31,6 +31,12 @@ #include <stdio.h> #include <sys/types.h> +#ifdef HAVE_STDLIB_H +# include <stdlib.h> +#else +extern void exit(); +#endif + #ifdef READLINE_LIBRARY # include "readline.h" # include "history.h" diff --git a/readline/examples/rlversion.c b/readline/examples/rlversion.c index 53949d1..6c86874 100644 --- a/readline/examples/rlversion.c +++ b/readline/examples/rlversion.c @@ -30,6 +30,12 @@ #include <sys/types.h> #include "posixstat.h" +#ifdef HAVE_STDLIB_H +# include <stdlib.h> +#else +extern void exit(); +#endif + #ifdef READLINE_LIBRARY # include "readline.h" #else diff --git a/readline/funmap.c b/readline/funmap.c index fe9a1da..9c760cc 100644 --- a/readline/funmap.c +++ b/readline/funmap.c @@ -131,6 +131,7 @@ static FUNMAP default_funmap[] = { { "tty-status", rl_tty_status }, { "undo", rl_undo_command }, { "universal-argument", rl_universal_argument }, + { "unix-filename-rubout", rl_unix_filename_rubout }, { "unix-line-discard", rl_unix_line_discard }, { "unix-word-rubout", rl_unix_word_rubout }, { "upcase-word", rl_upcase_word }, @@ -175,6 +176,7 @@ static FUNMAP default_funmap[] = { { "vi-put", rl_vi_put }, { "vi-redo", rl_vi_redo }, { "vi-replace", rl_vi_replace }, + { "vi-rubout", rl_vi_rubout }, { "vi-search", rl_vi_search }, { "vi-search-again", rl_vi_search_again }, { "vi-set-mark", rl_vi_set_mark }, diff --git a/readline/histexpand.c b/readline/histexpand.c index 6c81196..6847014 100644 --- a/readline/histexpand.c +++ b/readline/histexpand.c @@ -1,6 +1,6 @@ /* histexpand.c -- history expansion. */ -/* Copyright (C) 1989, 1992 Free Software Foundation, Inc. +/* Copyright (C) 1989-2004 Free Software Foundation, Inc. This file contains the GNU History Library (the Library), a set of routines for managing the text of previously typed lines. @@ -52,6 +52,8 @@ #define HISTORY_WORD_DELIMITERS " \t\n;&()|<>" #define HISTORY_QUOTE_CHARACTERS "\"'`" +#define slashify_in_quotes "\\`\"$" + typedef int _hist_search_func_t PARAMS((const char *, int)); extern int rl_byte_oriented; /* declared in mbutil.c */ @@ -65,6 +67,8 @@ static int subst_rhs_len; static char *get_history_word_specifier PARAMS((char *, char *, int *)); static char *history_find_word PARAMS((char *, int)); +static int history_tokenize_word PARAMS((const char *, int)); +static char *history_substring PARAMS((const char *, int, int)); static char *quote_breaks PARAMS((char *)); @@ -202,23 +206,24 @@ get_history_event (string, caller_index, delimiting_quote) /* Only a closing `?' or a newline delimit a substring search string. */ for (local_index = i; c = string[i]; i++) + { #if defined (HANDLE_MULTIBYTE) - if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - { - int v; - mbstate_t ps; + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + int v; + mbstate_t ps; + + memset (&ps, 0, sizeof (mbstate_t)); + /* These produce warnings because we're passing a const string to a + function that takes a non-const string. */ + _rl_adjust_point ((char *)string, i, &ps); + if ((v = _rl_get_char_len ((char *)string + i, &ps)) > 1) + { + i += v - 1; + continue; + } + } - memset (&ps, 0, sizeof (mbstate_t)); - /* These produce warnings because we're passing a const string to a - function that takes a non-const string. */ - _rl_adjust_point (string, i, &ps); - if ((v = _rl_get_char_len (string + i, &ps)) > 1) - { - i += v - 1; - continue; - } - } - else #endif /* HANDLE_MULTIBYTE */ if ((!substring_okay && (whitespace (c) || c == ':' || (history_search_delimiter_chars && member (c, history_search_delimiter_chars)) || @@ -226,6 +231,7 @@ get_history_event (string, caller_index, delimiting_quote) string[i] == '\n' || (substring_okay && string[i] == '?')) break; + } which = i - local_index; temp = (char *)xmalloc (1 + which); @@ -517,7 +523,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line) char *current_line; /* for !# */ { int i, n, starting_index; - int substitute_globally, want_quotes, print_only; + int substitute_globally, subst_bywords, want_quotes, print_only; char *event, *temp, *result, *tstr, *t, c, *word_spec; int result_len; #if defined (HANDLE_MULTIBYTE) @@ -599,19 +605,25 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line) FREE (word_spec); /* Perhaps there are other modifiers involved. Do what they say. */ - want_quotes = substitute_globally = print_only = 0; + want_quotes = substitute_globally = subst_bywords = print_only = 0; starting_index = i; while (string[i] == ':') { c = string[i + 1]; - if (c == 'g') + if (c == 'g' || c == 'a') { substitute_globally = 1; i++; c = string[i + 1]; } + else if (c == 'G') + { + subst_bywords = 1; + i++; + c = string[i + 1]; + } switch (c) { @@ -683,7 +695,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line) case 's': { char *new_event; - int delimiter, failed, si, l_temp; + int delimiter, failed, si, l_temp, ws, we; if (c == 's') { @@ -760,33 +772,67 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line) } /* Find the first occurrence of THIS in TEMP. */ - si = 0; + /* Substitute SUBST_RHS for SUBST_LHS in TEMP. There are three + cases to consider: + + 1. substitute_globally == subst_bywords == 0 + 2. substitute_globally == 1 && subst_bywords == 0 + 3. substitute_globally == 0 && subst_bywords == 1 + + In the first case, we substitute for the first occurrence only. + In the second case, we substitute for every occurrence. + In the third case, we tokenize into words and substitute the + first occurrence of each word. */ + + si = we = 0; for (failed = 1; (si + subst_lhs_len) <= l_temp; si++) - if (STREQN (temp+si, subst_lhs, subst_lhs_len)) - { - int len = subst_rhs_len - subst_lhs_len + l_temp; - new_event = (char *)xmalloc (1 + len); - strncpy (new_event, temp, si); - strncpy (new_event + si, subst_rhs, subst_rhs_len); - strncpy (new_event + si + subst_rhs_len, - temp + si + subst_lhs_len, - l_temp - (si + subst_lhs_len)); - new_event[len] = '\0'; - free (temp); - temp = new_event; - - failed = 0; - - if (substitute_globally) - { - si += subst_rhs_len; - l_temp = strlen (temp); - substitute_globally++; - continue; - } - else - break; - } + { + /* First skip whitespace and find word boundaries if + we're past the end of the word boundary we found + the last time. */ + if (subst_bywords && si > we) + { + for (; temp[si] && whitespace (temp[si]); si++) + ; + ws = si; + we = history_tokenize_word (temp, si); + } + + if (STREQN (temp+si, subst_lhs, subst_lhs_len)) + { + int len = subst_rhs_len - subst_lhs_len + l_temp; + new_event = (char *)xmalloc (1 + len); + strncpy (new_event, temp, si); + strncpy (new_event + si, subst_rhs, subst_rhs_len); + strncpy (new_event + si + subst_rhs_len, + temp + si + subst_lhs_len, + l_temp - (si + subst_lhs_len)); + new_event[len] = '\0'; + free (temp); + temp = new_event; + + failed = 0; + + if (substitute_globally) + { + /* Reported to fix a bug that causes it to skip every + other match when matching a single character. Was + si += subst_rhs_len previously. */ + si += subst_rhs_len - 1; + l_temp = strlen (temp); + substitute_globally++; + continue; + } + else if (subst_bywords) + { + si = we; + l_temp = strlen (temp); + continue; + } + else + break; + } + } if (substitute_globally > 1) { @@ -879,7 +925,7 @@ history_expand (hstring, output) char **output; { register int j; - int i, r, l, passc, cc, modified, eindex, only_printing; + int i, r, l, passc, cc, modified, eindex, only_printing, dquote; char *string; /* The output string, and its length. */ @@ -942,7 +988,7 @@ history_expand (hstring, output) /* `!' followed by one of the characters in history_no_expand_chars is NOT an expansion. */ - for (i = 0; string[i]; i++) + for (i = dquote = 0; string[i]; i++) { #if defined (HANDLE_MULTIBYTE) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) @@ -984,9 +1030,19 @@ history_expand (hstring, output) else break; } - /* XXX - at some point, might want to extend this to handle - double quotes as well. */ - else if (history_quotes_inhibit_expansion && string[i] == '\'') + /* Shell-like quoting: allow backslashes to quote double quotes + inside a double-quoted string. */ + else if (dquote && string[i] == '\\' && cc == '"') + i++; + /* More shell-like quoting: if we're paying attention to single + quotes and letting them quote the history expansion character, + then we need to pay attention to double quotes, because single + quotes are not special inside double-quoted strings. */ + else if (history_quotes_inhibit_expansion && string[i] == '"') + { + dquote = 1 - dquote; + } + else if (dquote == 0 && history_quotes_inhibit_expansion && string[i] == '\'') { /* If this is bash, single quotes inhibit history expansion. */ i++; @@ -999,6 +1055,7 @@ history_expand (hstring, output) if (cc == '\'' || cc == history_expansion_char) i++; } + } if (string[i] != history_expansion_char) @@ -1010,7 +1067,7 @@ history_expand (hstring, output) } /* Extract and perform the substitution. */ - for (passc = i = j = 0; i < l; i++) + for (passc = dquote = i = j = 0; i < l; i++) { int tchar = string[i]; @@ -1061,11 +1118,16 @@ history_expand (hstring, output) ADD_CHAR (tchar); break; + case '"': + dquote = 1 - dquote; + ADD_CHAR (tchar); + break; + case '\'': { /* If history_quotes_inhibit_expansion is set, single quotes inhibit history expansion. */ - if (history_quotes_inhibit_expansion) + if (dquote == 0 && history_quotes_inhibit_expansion) { int quote, slen; @@ -1160,7 +1222,9 @@ history_expand (hstring, output) if (only_printing) { +#if 0 add_history (result); +#endif return (2); } @@ -1223,7 +1287,10 @@ get_history_word_specifier (spec, from, caller_index) if (spec[i] == '-') first = 0; else if (spec[i] == '^') - first = 1; + { + first = 1; + i++; + } else if (_rl_digit_p (spec[i]) && expecting_word_spec) { for (first = 0; _rl_digit_p (spec[i]); i++) @@ -1338,7 +1405,103 @@ history_arg_extract (first, last, string) return (result); } -#define slashify_in_quotes "\\`\"$" +static int +history_tokenize_word (string, ind) + const char *string; + int ind; +{ + register int i; + int delimiter; + + i = ind; + delimiter = 0; + + if (member (string[i], "()\n")) + { + i++; + return i; + } + + if (member (string[i], "<>;&|$")) + { + int peek = string[i + 1]; + + if (peek == string[i] && peek != '$') + { + if (peek == '<' && string[i + 2] == '-') + i++; + i += 2; + return i; + } + else + { + if ((peek == '&' && (string[i] == '>' || string[i] == '<')) || + (peek == '>' && string[i] == '&') || + (peek == '(' && (string[i] == '>' || string[i] == '<')) || /* ) */ + (peek == '(' && string[i] == '$')) /* ) */ + { + i += 2; + return i; + } + } + + if (string[i] != '$') + { + i++; + return i; + } + } + + /* Get word from string + i; */ + + if (member (string[i], HISTORY_QUOTE_CHARACTERS)) + delimiter = string[i++]; + + for (; string[i]; i++) + { + if (string[i] == '\\' && string[i + 1] == '\n') + { + i++; + continue; + } + + if (string[i] == '\\' && delimiter != '\'' && + (delimiter != '"' || member (string[i], slashify_in_quotes))) + { + i++; + continue; + } + + if (delimiter && string[i] == delimiter) + { + delimiter = 0; + continue; + } + + if (!delimiter && (member (string[i], history_word_delimiters))) + break; + + if (!delimiter && member (string[i], HISTORY_QUOTE_CHARACTERS)) + delimiter = string[i]; + } + + return i; +} + +static char * +history_substring (string, start, end) + const char *string; + int start, end; +{ + register int len; + register char *result; + + len = end - start; + result = (char *)xmalloc (len + 1); + strncpy (result, string + start, len); + result[len] = '\0'; + return result; +} /* Parse STRING into tokens and return an array of strings. If WIND is not -1 and INDP is not null, we also want the word surrounding index @@ -1351,7 +1514,6 @@ history_tokenize_internal (string, wind, indp) { char **result; register int i, start, result_index, size; - int len, delimiter; /* If we're searching for a string that's not part of a word (e.g., " "), make sure we set *INDP to a reasonable value. */ @@ -1362,8 +1524,6 @@ history_tokenize_internal (string, wind, indp) exactly where the shell would split them. */ for (i = result_index = size = 0, result = (char **)NULL; string[i]; ) { - delimiter = 0; - /* Skip leading whitespace. */ for (; string[i] && whitespace (string[i]); i++) ; @@ -1371,88 +1531,30 @@ history_tokenize_internal (string, wind, indp) return (result); start = i; - - if (member (string[i], "()\n")) - { - i++; - goto got_token; - } - if (member (string[i], "<>;&|$")) - { - int peek = string[i + 1]; + i = history_tokenize_word (string, start); - if (peek == string[i] && peek != '$') - { - if (peek == '<' && string[i + 2] == '-') - i++; - i += 2; - goto got_token; - } - else - { - if ((peek == '&' && (string[i] == '>' || string[i] == '<')) || - ((peek == '>') && (string[i] == '&')) || - ((peek == '(') && (string[i] == '$'))) - { - i += 2; - goto got_token; - } - } - if (string[i] != '$') - { - i++; - goto got_token; - } - } - - /* Get word from string + i; */ - - if (member (string[i], HISTORY_QUOTE_CHARACTERS)) - delimiter = string[i++]; - - for (; string[i]; i++) + /* If we have a non-whitespace delimiter character (which would not be + skipped by the loop above), use it and any adjacent delimiters to + make a separate field. Any adjacent white space will be skipped the + next time through the loop. */ + if (i == start && history_word_delimiters) { - if (string[i] == '\\' && string[i + 1] == '\n') - { - i++; - continue; - } - - if (string[i] == '\\' && delimiter != '\'' && - (delimiter != '"' || member (string[i], slashify_in_quotes))) - { - i++; - continue; - } - - if (delimiter && string[i] == delimiter) - { - delimiter = 0; - continue; - } - - if (!delimiter && (member (string[i], history_word_delimiters))) - break; - - if (!delimiter && member (string[i], HISTORY_QUOTE_CHARACTERS)) - delimiter = string[i]; + i++; + while (string[i] && member (string[i], history_word_delimiters)) + i++; } - got_token: - /* If we are looking for the word in which the character at a particular index falls, remember it. */ if (indp && wind != -1 && wind >= start && wind < i) *indp = result_index; - len = i - start; if (result_index + 2 >= size) result = (char **)xrealloc (result, ((size += 10) * sizeof (char *))); - result[result_index] = (char *)xmalloc (1 + len); - strncpy (result[result_index], string + start, len); - result[result_index][len] = '\0'; - result[++result_index] = (char *)NULL; + + result[result_index++] = history_substring (string, start, i); + result[result_index] = (char *)NULL; } return (result); diff --git a/readline/histfile.c b/readline/histfile.c index c19630d..d1e54cc 100644 --- a/readline/histfile.c +++ b/readline/histfile.c @@ -1,6 +1,6 @@ /* histfile.c - functions to manipulate the history file. */ -/* Copyright (C) 1989, 1992 Free Software Foundation, Inc. +/* Copyright (C) 1989-2003 Free Software Foundation, Inc. This file contains the GNU History Library (the Library), a set of routines for managing the text of previously typed lines. @@ -23,8 +23,13 @@ /* The goal is to make the implementation transparent, so that you don't have to know what data types are used, just what functions you can call. I think I have done that. */ + #define READLINE_LIBRARY +#if defined (__TANDEM) +# include <floss.h> +#endif + #if defined (HAVE_CONFIG_H) # include <config.h> #endif @@ -32,7 +37,7 @@ #include <stdio.h> #include <sys/types.h> -#ifndef _MINIX +#if ! defined (_MINIX) && defined (HAVE_SYS_FILE_H) # include <sys/file.h> #endif #include "posixstat.h" @@ -52,7 +57,7 @@ # undef HAVE_MMAP #endif -#ifdef HAVE_MMAP +#ifdef HISTORY_USE_MMAP # include <sys/mman.h> # ifdef MAP_FILE @@ -67,7 +72,7 @@ # define MAP_FAILED ((void *)-1) # endif -#endif /* HAVE_MMAP */ +#endif /* HISTORY_USE_MMAP */ /* If we're compiling for __EMX__ (OS/2) or __CYGWIN__ (cygwin32 environment on win 95/98/nt), we want to open files with O_BINARY mode so that there @@ -93,6 +98,13 @@ extern int errno; #include "rlshell.h" #include "xmalloc.h" +/* If non-zero, we write timestamps to the history file in history_do_write() */ +int history_write_timestamps = 0; + +/* Does S look like the beginning of a history timestamp entry? Placeholder + for more extensive tests. */ +#define HIST_TIMESTAMP_START(s) (*(s) == history_comment_char) + /* Return the string that should be used in the place of this filename. This only matters when you don't specify the filename to read_history (), or write_history (). */ @@ -151,13 +163,20 @@ read_history_range (filename, from, to) const char *filename; int from, to; { - register char *line_start, *line_end; - char *input, *buffer, *bufend; + register char *line_start, *line_end, *p; + char *input, *buffer, *bufend, *last_ts; int file, current_line, chars_read; struct stat finfo; size_t file_size; +#if defined (EFBIG) + int overflow_errno = EFBIG; +#elif defined (EOVERFLOW) + int overflow_errno = EOVERFLOW; +#else + int overflow_errno = EIO; +#endif - buffer = (char *)NULL; + buffer = last_ts = (char *)NULL; input = history_filename (filename); file = open (input, O_RDONLY|O_BINARY, 0666); @@ -169,37 +188,42 @@ read_history_range (filename, from, to) /* check for overflow on very large files */ if (file_size != finfo.st_size || file_size + 1 < file_size) { -#if defined (EFBIG) - errno = EFBIG; -#elif defined (EOVERFLOW) - errno = EOVERFLOW; -#endif + errno = overflow_errno; goto error_and_exit; } -#ifdef HAVE_MMAP +#ifdef HISTORY_USE_MMAP /* We map read/write and private so we can change newlines to NULs without affecting the underlying object. */ buffer = (char *)mmap (0, file_size, PROT_READ|PROT_WRITE, MAP_RFLAGS, file, 0); if ((void *)buffer == MAP_FAILED) - goto error_and_exit; + { + errno = overflow_errno; + goto error_and_exit; + } chars_read = file_size; #else buffer = (char *)malloc (file_size + 1); if (buffer == 0) - goto error_and_exit; + { + errno = overflow_errno; + goto error_and_exit; + } chars_read = read (file, buffer, file_size); #endif if (chars_read < 0) { error_and_exit: - chars_read = errno; + if (errno != 0) + chars_read = errno; + else + chars_read = EIO; if (file >= 0) close (file); FREE (input); -#ifndef HAVE_MMAP +#ifndef HISTORY_USE_MMAP FREE (buffer); #endif @@ -220,8 +244,12 @@ read_history_range (filename, from, to) for (line_start = line_end = buffer; line_end < bufend && current_line < from; line_end++) if (*line_end == '\n') { - current_line++; - line_start = line_end + 1; + p = line_end + 1; + /* If we see something we think is a timestamp, continue with this + line. We should check more extensively here... */ + if (HIST_TIMESTAMP_START(p) == 0) + current_line++; + line_start = p; } /* If there are lines left to gobble, then gobble them now. */ @@ -234,7 +262,22 @@ read_history_range (filename, from, to) *line_end = '\0'; if (*line_start) - add_history (line_start); + { + if (HIST_TIMESTAMP_START(line_start) == 0) + { + add_history (line_start); + if (last_ts) + { + add_history_time (last_ts); + last_ts = NULL; + } + } + else + { + last_ts = line_start; + current_line--; + } + } current_line++; @@ -245,7 +288,7 @@ read_history_range (filename, from, to) } FREE (input); -#ifndef HAVE_MMAP +#ifndef HISTORY_USE_MMAP FREE (buffer); #else munmap (buffer, file_size); @@ -262,7 +305,7 @@ history_truncate_file (fname, lines) const char *fname; int lines; { - char *buffer, *filename, *bp; + char *buffer, *filename, *bp, *bp1; /* bp1 == bp+1 */ int file, chars_read, rv; struct stat finfo; size_t file_size; @@ -325,11 +368,14 @@ history_truncate_file (fname, lines) } /* Count backwards from the end of buffer until we have passed - LINES lines. */ - for (bp = buffer + chars_read - 1; lines && bp > buffer; bp--) + LINES lines. bp1 is set funny initially. But since bp[1] can't + be a comment character (since it's off the end) and *bp can't be + both a newline and the history comment character, it should be OK. */ + for (bp1 = bp = buffer + chars_read - 1; lines && bp > buffer; bp--) { - if (*bp == '\n') + if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0) lines--; + bp1 = bp; } /* If this is the first line, then the file contains exactly the @@ -338,11 +384,14 @@ history_truncate_file (fname, lines) the current value of i and 0. Otherwise, write from the start of this line until the end of the buffer. */ for ( ; bp > buffer; bp--) - if (*bp == '\n') - { - bp++; - break; - } + { + if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0) + { + bp++; + break; + } + bp1 = bp; + } /* Write only if there are more lines in the file than we want to truncate to. */ @@ -377,9 +426,9 @@ history_do_write (filename, nelements, overwrite) register int i; char *output; int file, mode, rv; +#ifdef HISTORY_USE_MMAP size_t cursize; -#ifdef HAVE_MMAP mode = overwrite ? O_RDWR|O_CREAT|O_TRUNC|O_BINARY : O_RDWR|O_APPEND|O_BINARY; #else mode = overwrite ? O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY; @@ -393,7 +442,7 @@ history_do_write (filename, nelements, overwrite) return (errno); } -#ifdef HAVE_MMAP +#ifdef HISTORY_USE_MMAP cursize = overwrite ? 0 : lseek (file, 0, SEEK_END); #endif @@ -411,10 +460,18 @@ history_do_write (filename, nelements, overwrite) the_history = history_list (); /* Calculate the total number of bytes to write. */ for (buffer_size = 0, i = history_length - nelements; i < history_length; i++) - buffer_size += 1 + strlen (the_history[i]->line); +#if 0 + buffer_size += 2 + HISTENT_BYTES (the_history[i]); +#else + { + if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0]) + buffer_size += strlen (the_history[i]->timestamp) + 1; + buffer_size += strlen (the_history[i]->line) + 1; + } +#endif /* Allocate the buffer, and fill it. */ -#ifdef HAVE_MMAP +#ifdef HISTORY_USE_MMAP if (ftruncate (file, buffer_size+cursize) == -1) goto mmap_error; buffer = (char *)mmap (0, buffer_size, PROT_READ|PROT_WRITE, MAP_WFLAGS, file, cursize); @@ -439,12 +496,18 @@ mmap_error: for (j = 0, i = history_length - nelements; i < history_length; i++) { + if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0]) + { + strcpy (buffer + j, the_history[i]->timestamp); + j += strlen (the_history[i]->timestamp); + buffer[j++] = '\n'; + } strcpy (buffer + j, the_history[i]->line); j += strlen (the_history[i]->line); buffer[j++] = '\n'; } -#ifdef HAVE_MMAP +#ifdef HISTORY_USE_MMAP if (msync (buffer, buffer_size, 0) != 0 || munmap (buffer, buffer_size) != 0) rv = errno; #else diff --git a/readline/history.c b/readline/history.c index 4242f33..a538f91 100644 --- a/readline/history.c +++ b/readline/history.c @@ -1,6 +1,6 @@ -/* History.c -- standalone history library */ +/* history.c -- standalone history library */ -/* Copyright (C) 1989, 1992 Free Software Foundation, Inc. +/* Copyright (C) 1989-2005 Free Software Foundation, Inc. This file contains the GNU History Library (the Library), a set of routines for managing the text of previously typed lines. @@ -52,6 +52,8 @@ /* The number of slots to increase the_history by. */ #define DEFAULT_HISTORY_GROW_SIZE 50 +static char *hist_inittime PARAMS((void)); + /* **************************************************************** */ /* */ /* History Functions */ @@ -123,14 +125,15 @@ using_history () } /* Return the number of bytes that the primary history entries are using. - This just adds up the lengths of the_history->lines. */ + This just adds up the lengths of the_history->lines and the associated + timestamps. */ int history_total_bytes () { register int i, result; for (i = result = 0; the_history && the_history[i]; i++) - result += strlen (the_history[i]->line); + result += HISTENT_BYTES (the_history[i]); return (result); } @@ -201,11 +204,45 @@ history_get (offset) int local_index; local_index = offset - history_base; - return (local_index >= history_length || local_index < 0 || !the_history) + return (local_index >= history_length || local_index < 0 || the_history == 0) ? (HIST_ENTRY *)NULL : the_history[local_index]; } +time_t +history_get_time (hist) + HIST_ENTRY *hist; +{ + char *ts; + time_t t; + + if (hist == 0 || hist->timestamp == 0) + return 0; + ts = hist->timestamp; + if (ts[0] != history_comment_char) + return 0; + t = (time_t) atol (ts + 1); /* XXX - should use strtol() here */ + return t; +} + +static char * +hist_inittime () +{ + time_t t; + char ts[64], *ret; + + t = (time_t) time ((time_t *)0); +#if defined (HAVE_VSNPRINTF) /* assume snprintf if vsnprintf exists */ + snprintf (ts, sizeof (ts) - 1, "X%lu", (unsigned long) t); +#else + sprintf (ts, "X%lu", (unsigned long) t); +#endif + ret = savestring (ts); + ret[0] = history_comment_char; + + return ret; +} + /* Place STRING at the end of the history list. The data field is set to NULL. */ void @@ -225,10 +262,7 @@ add_history (string) /* If there is something in the slot, then remove it. */ if (the_history[0]) - { - free (the_history[0]->line); - free (the_history[0]); - } + (void) free_history_entry (the_history[0]); /* Copy the rest of the entries, moving down one slot. */ for (i = 0; i < history_length; i++) @@ -260,10 +294,41 @@ add_history (string) temp->line = savestring (string); temp->data = (char *)NULL; + temp->timestamp = hist_inittime (); + the_history[history_length] = (HIST_ENTRY *)NULL; the_history[history_length - 1] = temp; } +/* Change the time stamp of the most recent history entry to STRING. */ +void +add_history_time (string) + const char *string; +{ + HIST_ENTRY *hs; + + hs = the_history[history_length - 1]; + FREE (hs->timestamp); + hs->timestamp = savestring (string); +} + +/* Free HIST and return the data so the calling application can free it + if necessary and desired. */ +histdata_t +free_history_entry (hist) + HIST_ENTRY *hist; +{ + histdata_t x; + + if (hist == 0) + return ((histdata_t) 0); + FREE (hist->line); + FREE (hist->timestamp); + x = hist->data; + free (hist); + return (x); +} + /* Make the history entry at WHICH have LINE and DATA. This returns the old entry so you can dispose of the data. In the case of an invalid WHICH, a NULL pointer is returned. */ @@ -275,7 +340,7 @@ replace_history_entry (which, line, data) { HIST_ENTRY *temp, *old_value; - if (which >= history_length) + if (which < 0 || which >= history_length) return ((HIST_ENTRY *)NULL); temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY)); @@ -283,6 +348,7 @@ replace_history_entry (which, line, data) temp->line = savestring (line); temp->data = data; + temp->timestamp = savestring (old_value->timestamp); the_history[which] = temp; return (old_value); @@ -298,17 +364,15 @@ remove_history (which) HIST_ENTRY *return_value; register int i; - if (which >= history_length || !history_length) - return_value = (HIST_ENTRY *)NULL; - else - { - return_value = the_history[which]; + if (which < 0 || which >= history_length || history_length == 0 || the_history == 0) + return ((HIST_ENTRY *)NULL); - for (i = which; i < history_length; i++) - the_history[i] = the_history[i + 1]; + return_value = the_history[which]; - history_length--; - } + for (i = which; i < history_length; i++) + the_history[i] = the_history[i + 1]; + + history_length--; return (return_value); } @@ -327,10 +391,7 @@ stifle_history (max) { /* This loses because we cannot free the data. */ for (i = 0, j = history_length - max; i < j; i++) - { - free (the_history[i]->line); - free (the_history[i]); - } + free_history_entry (the_history[i]); history_base = i; for (j = 0, i = history_length - max; j < max; i++, j++) @@ -372,8 +433,7 @@ clear_history () /* This loses because we cannot free the data. */ for (i = 0; i < history_length; i++) { - free (the_history[i]->line); - free (the_history[i]); + free_history_entry (the_history[i]); the_history[i] = (HIST_ENTRY *)NULL; } diff --git a/readline/history.h b/readline/history.h index 58b5de4..14ca2a9 100644 --- a/readline/history.h +++ b/readline/history.h @@ -1,5 +1,5 @@ -/* History.h -- the names of functions that you can call in history. */ -/* Copyright (C) 1989, 1992 Free Software Foundation, Inc. +/* history.h -- the names of functions that you can call in history. */ +/* Copyright (C) 1989-2003 Free Software Foundation, Inc. This file contains the GNU History Library (the Library), a set of routines for managing the text of previously typed lines. @@ -26,6 +26,8 @@ extern "C" { #endif +#include <time.h> /* XXX - for history timestamp code */ + #if defined READLINE_LIBRARY # include "rlstdc.h" # include "rltypedefs.h" @@ -43,9 +45,13 @@ typedef char *histdata_t; /* The structure used to store a history entry. */ typedef struct _hist_entry { char *line; + char *timestamp; /* char * rather than time_t for read/write */ histdata_t data; } HIST_ENTRY; +/* Size of the history-library-managed space in history entry HS. */ +#define HISTENT_BYTES(hs) (strlen ((hs)->line) + strlen ((hs)->timestamp)) + /* A structure used to pass the current state of the history stuff around. */ typedef struct _hist_state { HIST_ENTRY **entries; /* Pointer to the entries themselves. */ @@ -76,11 +82,19 @@ extern void history_set_history_state PARAMS((HISTORY_STATE *)); The associated data field (if any) is set to NULL. */ extern void add_history PARAMS((const char *)); +/* Change the timestamp associated with the most recent history entry to + STRING. */ +extern void add_history_time PARAMS((const char *)); + /* A reasonably useless function, only here for completeness. WHICH is the magic number that tells us which element to delete. The elements are numbered from 0. */ extern HIST_ENTRY *remove_history PARAMS((int)); +/* Free the history entry H and return any application-specific data + associated with it. */ +extern histdata_t free_history_entry PARAMS((HIST_ENTRY *)); + /* Make the history entry at WHICH have LINE and DATA. This returns the old entry so you can dispose of the data. In the case of an invalid WHICH, a NULL pointer is returned. */ @@ -119,6 +133,10 @@ extern HIST_ENTRY *current_history PARAMS((void)); array. OFFSET is relative to history_base. */ extern HIST_ENTRY *history_get PARAMS((int)); +/* Return the timestamp associated with the HIST_ENTRY * passed as an + argument */ +extern time_t history_get_time PARAMS((HIST_ENTRY *)); + /* Return the number of bytes that the primary history entries are using. This just adds up the lengths of the_history->lines. */ extern int history_total_bytes PARAMS((void)); @@ -231,6 +249,8 @@ extern char *history_no_expand_chars; extern char *history_search_delimiter_chars; extern int history_quotes_inhibit_expansion; +extern int history_write_timestamps; + /* Backwards compatibility */ extern int max_input_history; diff --git a/readline/histsearch.c b/readline/histsearch.c index d94fd6c..1cc5875 100644 --- a/readline/histsearch.c +++ b/readline/histsearch.c @@ -77,11 +77,11 @@ history_search_internal (string, direction, anchored) if (string == 0 || *string == '\0') return (-1); - if (!history_length || ((i == history_length) && !reverse)) + if (!history_length || ((i >= history_length) && !reverse)) return (-1); - if (reverse && (i == history_length)) - i--; + if (reverse && (i >= history_length)) + i = history_length - 1; #define NEXT_LINE() do { if (reverse) i--; else i++; } while (0) diff --git a/readline/input.c b/readline/input.c index 9120dfa..9f89053 100644 --- a/readline/input.c +++ b/readline/input.c @@ -1,6 +1,6 @@ /* input.c -- character input functions for readline. */ -/* Copyright (C) 1994 Free Software Foundation, Inc. +/* Copyright (C) 1994-2005 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -21,6 +21,10 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY +#if defined (__TANDEM) +# include <floss.h> +#endif + #if defined (HAVE_CONFIG_H) # include <config.h> #endif @@ -154,6 +158,12 @@ _rl_unget_char (key) return (0); } +int +_rl_pushed_input_available () +{ + return (push_index != pop_index); +} + /* If a character is available to be read, then read it and stuff it into IBUFFER. Otherwise, just return. Returns number of characters read (0 if none available) and -1 on error (EIO). */ @@ -162,7 +172,7 @@ rl_gather_tyi () { int tty; register int tem, result; - int chars_avail; + int chars_avail, k; char input; #if defined(HAVE_SELECT) fd_set readfds, exceptfds; @@ -202,9 +212,24 @@ rl_gather_tyi () fcntl (tty, F_SETFL, tem); if (chars_avail == -1 && errno == EAGAIN) return 0; + if (chars_avail == 0) /* EOF */ + { + rl_stuff_char (EOF); + return (0); + } } #endif /* O_NDELAY */ +#if defined (__MINGW32__) + /* We use getch to read console input, so use the same + mechanism to check for more. Otherwise, we don't know. */ + if (isatty (fileno (rl_instream))) + chars_avail = _kbhit (); + else + chars_avail = 0; + result = 0; +#endif + /* If there's nothing available, don't waste time trying to read something. */ if (chars_avail <= 0) @@ -225,7 +250,12 @@ rl_gather_tyi () if (result != -1) { while (chars_avail--) - rl_stuff_char ((*rl_getc_function) (rl_instream)); + { + k = (*rl_getc_function) (rl_instream); + rl_stuff_char (k); + if (k == NEWLINE || k == RETURN) + break; + } } else { @@ -285,6 +315,13 @@ _rl_input_available () #endif +#if defined (__MINGW32__) + /* We use getch to read console input, so use the same + mechanism to check for more. Otherwise, we don't know. */ + if (isatty (fileno (rl_instream))) + return _kbhit (); +#endif + return 0; } @@ -424,12 +461,9 @@ rl_getc (stream) while (1) { -#ifdef __MINGW32__ - /* On Windows, use a special routine to read a single character - from the console. (Otherwise, no characters are available - until the user hits the return key.) */ +#if defined (__MINGW32__) if (isatty (fileno (stream))) - return getch (); + return (getch ()); #endif result = read (fileno (stream), &c, sizeof (unsigned char)); @@ -506,6 +540,12 @@ _rl_read_mbchar (mbchar, size) ps = ps_back; continue; } + else if (mbchar_bytes_length == 0) + { + mbchar[0] = '\0'; /* null wide character */ + mb_len = 1; + break; + } else if (mbchar_bytes_length > (size_t)(0)) break; } diff --git a/readline/isearch.c b/readline/isearch.c index c1ea5b3..d7d8520 100644 --- a/readline/isearch.c +++ b/readline/isearch.c @@ -4,7 +4,7 @@ /* */ /* **************************************************************** */ -/* Copyright (C) 1987-2002 Free Software Foundation, Inc. +/* Copyright (C) 1987-2005 Free Software Foundation, Inc. This file contains the Readline Library (the Library), a set of routines for providing Emacs style line input to programs that ask @@ -56,12 +56,17 @@ /* Variables exported to other files in the readline library. */ char *_rl_isearch_terminators = (char *)NULL; +_rl_search_cxt *_rl_iscxt = 0; + /* Variables imported from other files in the readline library. */ extern HIST_ENTRY *_rl_saved_line_for_history; -/* Forward declarations */ static int rl_search_history PARAMS((int, int)); +static _rl_search_cxt *_rl_isearch_init PARAMS((int)); +static void _rl_isearch_fini PARAMS((_rl_search_cxt *)); +static int _rl_isearch_cleanup PARAMS((_rl_search_cxt *, int)); + /* Last line found by the current incremental search, so we don't `find' identical lines many times in a row. */ static char *prev_line_found; @@ -72,6 +77,57 @@ static int last_isearch_string_len; static char *default_isearch_terminators = "\033\012"; +_rl_search_cxt * +_rl_scxt_alloc (type, flags) + int type, flags; +{ + _rl_search_cxt *cxt; + + cxt = (_rl_search_cxt *)xmalloc (sizeof (_rl_search_cxt)); + + cxt->type = type; + cxt->sflags = flags; + + cxt->search_string = 0; + cxt->search_string_size = cxt->search_string_index = 0; + + cxt->lines = 0; + cxt->allocated_line = 0; + cxt->hlen = cxt->hindex = 0; + + cxt->save_point = rl_point; + cxt->save_mark = rl_mark; + cxt->save_line = where_history (); + cxt->last_found_line = cxt->save_line; + cxt->prev_line_found = 0; + + cxt->save_undo_list = 0; + + cxt->history_pos = 0; + cxt->direction = 0; + + cxt->lastc = 0; + + cxt->sline = 0; + cxt->sline_len = cxt->sline_index = 0; + + cxt->search_terminators = 0; + + return cxt; +} + +void +_rl_scxt_dispose (cxt, flags) + _rl_search_cxt *cxt; + int flags; +{ + FREE (cxt->search_string); + FREE (cxt->allocated_line); + FREE (cxt->lines); + + free (cxt); +} + /* Search backwards through the history looking for a string which is typed interactively. Start with the current line. */ int @@ -92,7 +148,7 @@ rl_forward_search_history (sign, key) /* Display the current state of the search in the echo-area. SEARCH_STRING contains the string that is being searched for, - DIRECTION is zero for forward, or 1 for reverse, + DIRECTION is zero for forward, or non-zero for reverse, WHERE is the history list number of the current line. If it is -1, then this line is the starting one. */ static void @@ -140,66 +196,23 @@ rl_display_search (search_string, reverse_p, where) (*rl_redisplay_function) (); } -/* Search through the history looking for an interactively typed string. - This is analogous to i-search. We start the search in the current line. - DIRECTION is which direction to search; >= 0 means forward, < 0 means - backwards. */ -static int -rl_search_history (direction, invoking_key) - int direction, invoking_key; +static _rl_search_cxt * +_rl_isearch_init (direction) + int direction; { - /* The string that the user types in to search for. */ - char *search_string; - - /* The current length of SEARCH_STRING. */ - int search_string_index; - - /* The amount of space that SEARCH_STRING has allocated to it. */ - int search_string_size; - - /* The list of lines to search through. */ - char **lines, *allocated_line; - - /* The length of LINES. */ - int hlen; - - /* Where we get LINES from. */ - HIST_ENTRY **hlist; - + _rl_search_cxt *cxt; register int i; - int orig_point, orig_mark, orig_line, last_found_line; - int c, found, failed, sline_len; - int n, wstart, wlen; -#if defined (HANDLE_MULTIBYTE) - char mb[MB_LEN_MAX]; -#endif - - /* The line currently being searched. */ - char *sline; - - /* Offset in that line. */ - int line_index; - - /* Non-zero if we are doing a reverse search. */ - int reverse; + HIST_ENTRY **hlist; - /* The list of characters which terminate the search, but are not - subsequently executed. If the variable isearch-terminators has - been set, we use that value, otherwise we use ESC and C-J. */ - char *isearch_terminators; + cxt = _rl_scxt_alloc (RL_SEARCH_ISEARCH, 0); + if (direction < 0) + cxt->sflags |= SF_REVERSE; - RL_SETSTATE(RL_STATE_ISEARCH); - orig_point = rl_point; - orig_mark = rl_mark; - last_found_line = orig_line = where_history (); - reverse = direction < 0; - hlist = history_list (); - allocated_line = (char *)NULL; - - isearch_terminators = _rl_isearch_terminators ? _rl_isearch_terminators + cxt->search_terminators = _rl_isearch_terminators ? _rl_isearch_terminators : default_isearch_terminators; /* Create an arrary of pointers to the lines that we want to search. */ + hlist = history_list (); rl_maybe_replace_line (); i = 0; if (hlist) @@ -207,354 +220,447 @@ rl_search_history (direction, invoking_key) /* Allocate space for this many lines, +1 for the current input line, and remember those lines. */ - lines = (char **)xmalloc ((1 + (hlen = i)) * sizeof (char *)); - for (i = 0; i < hlen; i++) - lines[i] = hlist[i]->line; + cxt->lines = (char **)xmalloc ((1 + (cxt->hlen = i)) * sizeof (char *)); + for (i = 0; i < cxt->hlen; i++) + cxt->lines[i] = hlist[i]->line; if (_rl_saved_line_for_history) - lines[i] = _rl_saved_line_for_history->line; + cxt->lines[i] = _rl_saved_line_for_history->line; else { /* Keep track of this so we can free it. */ - allocated_line = (char *)xmalloc (1 + strlen (rl_line_buffer)); - strcpy (allocated_line, &rl_line_buffer[0]); - lines[i] = allocated_line; + cxt->allocated_line = (char *)xmalloc (1 + strlen (rl_line_buffer)); + strcpy (cxt->allocated_line, &rl_line_buffer[0]); + cxt->lines[i] = cxt->allocated_line; } - hlen++; + cxt->hlen++; /* The line where we start the search. */ - i = orig_line; + cxt->history_pos = cxt->save_line; rl_save_prompt (); /* Initialize search parameters. */ - search_string = (char *)xmalloc (search_string_size = 128); - *search_string = '\0'; - search_string_index = 0; - prev_line_found = (char *)0; /* XXX */ + cxt->search_string = (char *)xmalloc (cxt->search_string_size = 128); + cxt->search_string[cxt->search_string_index = 0] = '\0'; /* Normalize DIRECTION into 1 or -1. */ - direction = (direction >= 0) ? 1 : -1; + cxt->direction = (direction >= 0) ? 1 : -1; - rl_display_search (search_string, reverse, -1); + cxt->sline = rl_line_buffer; + cxt->sline_len = strlen (cxt->sline); + cxt->sline_index = rl_point; - sline = rl_line_buffer; - sline_len = strlen (sline); - line_index = rl_point; + _rl_iscxt = cxt; /* save globally */ - found = failed = 0; - for (;;) + return cxt; +} + +static void +_rl_isearch_fini (cxt) + _rl_search_cxt *cxt; +{ + /* First put back the original state. */ + strcpy (rl_line_buffer, cxt->lines[cxt->save_line]); + + rl_restore_prompt (); + + /* Save the search string for possible later use. */ + FREE (last_isearch_string); + last_isearch_string = cxt->search_string; + last_isearch_string_len = cxt->search_string_index; + cxt->search_string = 0; + + if (cxt->last_found_line < cxt->save_line) + rl_get_previous_history (cxt->save_line - cxt->last_found_line, 0); + else + rl_get_next_history (cxt->last_found_line - cxt->save_line, 0); + + /* If the string was not found, put point at the end of the last matching + line. If last_found_line == orig_line, we didn't find any matching + history lines at all, so put point back in its original position. */ + if (cxt->sline_index < 0) { - rl_command_func_t *f = (rl_command_func_t *)NULL; + if (cxt->last_found_line == cxt->save_line) + cxt->sline_index = cxt->save_point; + else + cxt->sline_index = strlen (rl_line_buffer); + rl_mark = cxt->save_mark; + } - /* Read a key and decide how to proceed. */ - RL_SETSTATE(RL_STATE_MOREINPUT); - c = rl_read_key (); - RL_UNSETSTATE(RL_STATE_MOREINPUT); + rl_point = cxt->sline_index; + /* Don't worry about where to put the mark here; rl_get_previous_history + and rl_get_next_history take care of it. */ + + rl_clear_message (); +} + +int +_rl_search_getchar (cxt) + _rl_search_cxt *cxt; +{ + int c; + + /* Read a key and decide how to proceed. */ + RL_SETSTATE(RL_STATE_MOREINPUT); + c = cxt->lastc = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); #if defined (HANDLE_MULTIBYTE) - if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - c = _rl_read_mbstring (c, mb, MB_LEN_MAX); + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + c = cxt->lastc = _rl_read_mbstring (cxt->lastc, cxt->mb, MB_LEN_MAX); #endif - /* Translate the keys we do something with to opcodes. */ - if (c >= 0 && _rl_keymap[c].type == ISFUNC) - { - f = _rl_keymap[c].function; - - if (f == rl_reverse_search_history) - c = reverse ? -1 : -2; - else if (f == rl_forward_search_history) - c = !reverse ? -1 : -2; - else if (f == rl_rubout) - c = -3; - else if (c == CTRL ('G')) - c = -4; - else if (c == CTRL ('W')) /* XXX */ - c = -5; - else if (c == CTRL ('Y')) /* XXX */ - c = -6; - } + return c; +} - /* The characters in isearch_terminators (set from the user-settable - variable isearch-terminators) are used to terminate the search but - not subsequently execute the character as a command. The default - value is "\033\012" (ESC and C-J). */ - if (strchr (isearch_terminators, c)) - { - /* ESC still terminates the search, but if there is pending - input or if input arrives within 0.1 seconds (on systems - with select(2)) it is used as a prefix character - with rl_execute_next. WATCH OUT FOR THIS! This is intended - to allow the arrow keys to be used like ^F and ^B are used - to terminate the search and execute the movement command. - XXX - since _rl_input_available depends on the application- - settable keyboard timeout value, this could alternatively - use _rl_input_queued(100000) */ - if (c == ESC && _rl_input_available ()) - rl_execute_next (ESC); - break; - } +/* Process just-read character C according to isearch context CXT. Return + -1 if the caller should just free the context and return, 0 if we should + break out of the loop, and 1 if we should continue to read characters. */ +int +_rl_isearch_dispatch (cxt, c) + _rl_search_cxt *cxt; + int c; +{ + int n, wstart, wlen, limit, cval; + rl_command_func_t *f; + + f = (rl_command_func_t *)NULL; + + /* Translate the keys we do something with to opcodes. */ + if (c >= 0 && _rl_keymap[c].type == ISFUNC) + { + f = _rl_keymap[c].function; + + if (f == rl_reverse_search_history) + cxt->lastc = (cxt->sflags & SF_REVERSE) ? -1 : -2; + else if (f == rl_forward_search_history) + cxt->lastc = (cxt->sflags & SF_REVERSE) ? -2 : -1; + else if (f == rl_rubout) + cxt->lastc = -3; + else if (c == CTRL ('G')) + cxt->lastc = -4; + else if (c == CTRL ('W')) /* XXX */ + cxt->lastc = -5; + else if (c == CTRL ('Y')) /* XXX */ + cxt->lastc = -6; + } + + /* The characters in isearch_terminators (set from the user-settable + variable isearch-terminators) are used to terminate the search but + not subsequently execute the character as a command. The default + value is "\033\012" (ESC and C-J). */ + if (strchr (cxt->search_terminators, cxt->lastc)) + { + /* ESC still terminates the search, but if there is pending + input or if input arrives within 0.1 seconds (on systems + with select(2)) it is used as a prefix character + with rl_execute_next. WATCH OUT FOR THIS! This is intended + to allow the arrow keys to be used like ^F and ^B are used + to terminate the search and execute the movement command. + XXX - since _rl_input_available depends on the application- + settable keyboard timeout value, this could alternatively + use _rl_input_queued(100000) */ + if (cxt->lastc == ESC && _rl_input_available ()) + rl_execute_next (ESC); + return (0); + } #define ENDSRCH_CHAR(c) \ ((CTRL_CHAR (c) || META_CHAR (c) || (c) == RUBOUT) && ((c) != CTRL ('G'))) #if defined (HANDLE_MULTIBYTE) - if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + if (cxt->lastc >= 0 && (cxt->mb[0] && cxt->mb[1] == '\0') && ENDSRCH_CHAR (cxt->lastc)) + { + /* This sets rl_pending_input to c; it will be picked up the next + time rl_read_key is called. */ + rl_execute_next (cxt->lastc); + return (0); + } + } + else +#endif + if (cxt->lastc >= 0 && ENDSRCH_CHAR (cxt->lastc)) + { + /* This sets rl_pending_input to LASTC; it will be picked up the next + time rl_read_key is called. */ + rl_execute_next (cxt->lastc); + return (0); + } + + /* Now dispatch on the character. `Opcodes' affect the search string or + state. Other characters are added to the string. */ + switch (cxt->lastc) + { + /* search again */ + case -1: + if (cxt->search_string_index == 0) { - if (c >= 0 && strlen (mb) == 1 && ENDSRCH_CHAR (c)) + if (last_isearch_string) { - /* This sets rl_pending_input to c; it will be picked up the next - time rl_read_key is called. */ - rl_execute_next (c); + cxt->search_string_size = 64 + last_isearch_string_len; + cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size); + strcpy (cxt->search_string, last_isearch_string); + cxt->search_string_index = last_isearch_string_len; + rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), -1); break; } + return (1); } + else if (cxt->sflags & SF_REVERSE) + cxt->sline_index--; + else if (cxt->sline_index != cxt->sline_len) + cxt->sline_index++; else -#endif - if (c >= 0 && ENDSRCH_CHAR (c)) + rl_ding (); + break; + + /* switch directions */ + case -2: + cxt->direction = -cxt->direction; + if (cxt->direction < 0) + cxt->sflags |= SF_REVERSE; + else + cxt->sflags &= ~SF_REVERSE; + break; + + /* delete character from search string. */ + case -3: /* C-H, DEL */ + /* This is tricky. To do this right, we need to keep a + stack of search positions for the current search, with + sentinels marking the beginning and end. But this will + do until we have a real isearch-undo. */ + if (cxt->search_string_index == 0) + rl_ding (); + else + cxt->search_string[--cxt->search_string_index] = '\0'; + break; + + case -4: /* C-G, abort */ + rl_replace_line (cxt->lines[cxt->save_line], 0); + rl_point = cxt->save_point; + rl_mark = cxt->save_mark; + rl_restore_prompt(); + rl_clear_message (); + + return -1; + + case -5: /* C-W */ + /* skip over portion of line we already matched and yank word */ + wstart = rl_point + cxt->search_string_index; + if (wstart >= rl_end) { - /* This sets rl_pending_input to c; it will be picked up the next - time rl_read_key is called. */ - rl_execute_next (c); + rl_ding (); break; } - switch (c) + /* if not in a word, move to one. */ + cval = _rl_char_value (rl_line_buffer, wstart); + if (_rl_walphabetic (cval) == 0) { - case -1: - if (search_string_index == 0) - { - if (last_isearch_string) - { - search_string_size = 64 + last_isearch_string_len; - search_string = (char *)xrealloc (search_string, search_string_size); - strcpy (search_string, last_isearch_string); - search_string_index = last_isearch_string_len; - rl_display_search (search_string, reverse, -1); - break; - } - continue; - } - else if (reverse) - --line_index; - else if (line_index != sline_len) - ++line_index; - else - rl_ding (); + rl_ding (); break; - - /* switch directions */ - case -2: - direction = -direction; - reverse = direction < 0; + } + n = MB_NEXTCHAR (rl_line_buffer, wstart, 1, MB_FIND_NONZERO);; + while (n < rl_end) + { + cval = _rl_char_value (rl_line_buffer, n); + if (_rl_walphabetic (cval) == 0) + break; + n = MB_NEXTCHAR (rl_line_buffer, n, 1, MB_FIND_NONZERO);; + } + wlen = n - wstart + 1; + if (cxt->search_string_index + wlen + 1 >= cxt->search_string_size) + { + cxt->search_string_size += wlen + 1; + cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size); + } + for (; wstart < n; wstart++) + cxt->search_string[cxt->search_string_index++] = rl_line_buffer[wstart]; + cxt->search_string[cxt->search_string_index] = '\0'; + break; + + case -6: /* C-Y */ + /* skip over portion of line we already matched and yank rest */ + wstart = rl_point + cxt->search_string_index; + if (wstart >= rl_end) + { + rl_ding (); break; + } + n = rl_end - wstart + 1; + if (cxt->search_string_index + n + 1 >= cxt->search_string_size) + { + cxt->search_string_size += n + 1; + cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size); + } + for (n = wstart; n < rl_end; n++) + cxt->search_string[cxt->search_string_index++] = rl_line_buffer[n]; + cxt->search_string[cxt->search_string_index] = '\0'; + break; + + /* Add character to search string and continue search. */ + default: + if (cxt->search_string_index + 2 >= cxt->search_string_size) + { + cxt->search_string_size += 128; + cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size); + } +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + int j, l; + for (j = 0, l = strlen (cxt->mb); j < l; ) + cxt->search_string[cxt->search_string_index++] = cxt->mb[j++]; + } + else +#endif + cxt->search_string[cxt->search_string_index++] = c; + cxt->search_string[cxt->search_string_index] = '\0'; + break; + } - /* delete character from search string. */ - case -3: /* C-H, DEL */ - /* This is tricky. To do this right, we need to keep a - stack of search positions for the current search, with - sentinels marking the beginning and end. But this will - do until we have a real isearch-undo. */ - if (search_string_index == 0) - rl_ding (); - else - search_string[--search_string_index] = '\0'; - - break; + for (cxt->sflags &= ~(SF_FOUND|SF_FAILED);; ) + { + limit = cxt->sline_len - cxt->search_string_index + 1; - case -4: /* C-G */ - rl_replace_line (lines[orig_line], 0); - rl_point = orig_point; - rl_mark = orig_mark; - rl_restore_prompt(); - rl_clear_message (); - if (allocated_line) - free (allocated_line); - free (lines); - RL_UNSETSTATE(RL_STATE_ISEARCH); - return 0; - - case -5: /* C-W */ - /* skip over portion of line we already matched */ - wstart = rl_point + search_string_index; - if (wstart >= rl_end) + /* Search the current line. */ + while ((cxt->sflags & SF_REVERSE) ? (cxt->sline_index >= 0) : (cxt->sline_index < limit)) + { + if (STREQN (cxt->search_string, cxt->sline + cxt->sline_index, cxt->search_string_index)) { - rl_ding (); + cxt->sflags |= SF_FOUND; break; } + else + cxt->sline_index += cxt->direction; + } + if (cxt->sflags & SF_FOUND) + break; - /* if not in a word, move to one. */ - if (rl_alphabetic(rl_line_buffer[wstart]) == 0) - { - rl_ding (); - break; - } - n = wstart; - while (n < rl_end && rl_alphabetic(rl_line_buffer[n])) - n++; - wlen = n - wstart + 1; - if (search_string_index + wlen + 1 >= search_string_size) - { - search_string_size += wlen + 1; - search_string = (char *)xrealloc (search_string, search_string_size); - } - for (; wstart < n; wstart++) - search_string[search_string_index++] = rl_line_buffer[wstart]; - search_string[search_string_index] = '\0'; - break; + /* Move to the next line, but skip new copies of the line + we just found and lines shorter than the string we're + searching for. */ + do + { + /* Move to the next line. */ + cxt->history_pos += cxt->direction; - case -6: /* C-Y */ - /* skip over portion of line we already matched */ - wstart = rl_point + search_string_index; - if (wstart >= rl_end) + /* At limit for direction? */ + if ((cxt->sflags & SF_REVERSE) ? (cxt->history_pos < 0) : (cxt->history_pos == cxt->hlen)) { - rl_ding (); + cxt->sflags |= SF_FAILED; break; } - n = rl_end - wstart + 1; - if (search_string_index + n + 1 >= search_string_size) - { - search_string_size += n + 1; - search_string = (char *)xrealloc (search_string, search_string_size); - } - for (n = wstart; n < rl_end; n++) - search_string[search_string_index++] = rl_line_buffer[n]; - search_string[search_string_index] = '\0'; - break; - default: - /* Add character to search string and continue search. */ - if (search_string_index + 2 >= search_string_size) - { - search_string_size += 128; - search_string = (char *)xrealloc (search_string, search_string_size); - } -#if defined (HANDLE_MULTIBYTE) - if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - { - int j, l; - for (j = 0, l = strlen (mb); j < l; ) - search_string[search_string_index++] = mb[j++]; - } - else -#endif - search_string[search_string_index++] = c; - search_string[search_string_index] = '\0'; - break; + /* We will need these later. */ + cxt->sline = cxt->lines[cxt->history_pos]; + cxt->sline_len = strlen (cxt->sline); } + while ((cxt->prev_line_found && STREQ (cxt->prev_line_found, cxt->lines[cxt->history_pos])) || + (cxt->search_string_index > cxt->sline_len)); - for (found = failed = 0;;) - { - int limit = sline_len - search_string_index + 1; + if (cxt->sflags & SF_FAILED) + break; - /* Search the current line. */ - while (reverse ? (line_index >= 0) : (line_index < limit)) - { - if (STREQN (search_string, sline + line_index, search_string_index)) - { - found++; - break; - } - else - line_index += direction; - } - if (found) - break; + /* Now set up the line for searching... */ + cxt->sline_index = (cxt->sflags & SF_REVERSE) ? cxt->sline_len - cxt->search_string_index : 0; + } - /* Move to the next line, but skip new copies of the line - we just found and lines shorter than the string we're - searching for. */ - do - { - /* Move to the next line. */ - i += direction; - - /* At limit for direction? */ - if (reverse ? (i < 0) : (i == hlen)) - { - failed++; - break; - } - - /* We will need these later. */ - sline = lines[i]; - sline_len = strlen (sline); - } - while ((prev_line_found && STREQ (prev_line_found, lines[i])) || - (search_string_index > sline_len)); + if (cxt->sflags & SF_FAILED) + { + /* We cannot find the search string. Ding the bell. */ + rl_ding (); + cxt->history_pos = cxt->last_found_line; + return 1; + } - if (failed) - break; + /* We have found the search string. Just display it. But don't + actually move there in the history list until the user accepts + the location. */ + if (cxt->sflags & SF_FOUND) + { + cxt->prev_line_found = cxt->lines[cxt->history_pos]; + rl_replace_line (cxt->lines[cxt->history_pos], 0); + rl_point = cxt->sline_index; + cxt->last_found_line = cxt->history_pos; + rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos); + } - /* Now set up the line for searching... */ - line_index = reverse ? sline_len - search_string_index : 0; - } + return 1; +} - if (failed) - { - /* We cannot find the search string. Ding the bell. */ - rl_ding (); - i = last_found_line; - continue; /* XXX - was break */ - } +static int +_rl_isearch_cleanup (cxt, r) + _rl_search_cxt *cxt; + int r; +{ + if (r >= 0) + _rl_isearch_fini (cxt); + _rl_scxt_dispose (cxt, 0); + _rl_iscxt = 0; - /* We have found the search string. Just display it. But don't - actually move there in the history list until the user accepts - the location. */ - if (found) - { - prev_line_found = lines[i]; - rl_replace_line (lines[i], 0); - rl_point = line_index; - last_found_line = i; - rl_display_search (search_string, reverse, (i == orig_line) ? -1 : i); - } - } + RL_UNSETSTATE(RL_STATE_ISEARCH); - /* The searching is over. The user may have found the string that she - was looking for, or else she may have exited a failing search. If - LINE_INDEX is -1, then that shows that the string searched for was - not found. We use this to determine where to place rl_point. */ + return (r != 0); +} - /* First put back the original state. */ - strcpy (rl_line_buffer, lines[orig_line]); +/* Search through the history looking for an interactively typed string. + This is analogous to i-search. We start the search in the current line. + DIRECTION is which direction to search; >= 0 means forward, < 0 means + backwards. */ +static int +rl_search_history (direction, invoking_key) + int direction, invoking_key; +{ + _rl_search_cxt *cxt; /* local for now, but saved globally */ + int c, r; - rl_restore_prompt (); + RL_SETSTATE(RL_STATE_ISEARCH); + cxt = _rl_isearch_init (direction); - /* Save the search string for possible later use. */ - FREE (last_isearch_string); - last_isearch_string = search_string; - last_isearch_string_len = search_string_index; + rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), -1); - if (last_found_line < orig_line) - rl_get_previous_history (orig_line - last_found_line, 0); - else - rl_get_next_history (last_found_line - orig_line, 0); + /* If we are using the callback interface, all we do is set up here and + return. The key is that we leave RL_STATE_ISEARCH set. */ + if (RL_ISSTATE (RL_STATE_CALLBACK)) + return (0); - /* If the string was not found, put point at the end of the last matching - line. If last_found_line == orig_line, we didn't find any matching - history lines at all, so put point back in its original position. */ - if (line_index < 0) + r = -1; + for (;;) { - if (last_found_line == orig_line) - line_index = orig_point; - else - line_index = strlen (rl_line_buffer); - rl_mark = orig_mark; + c = _rl_search_getchar (cxt); + /* We might want to handle EOF here (c == 0) */ + r = _rl_isearch_dispatch (cxt, cxt->lastc); + if (r <= 0) + break; } - rl_point = line_index; - /* Don't worry about where to put the mark here; rl_get_previous_history - and rl_get_next_history take care of it. */ - - rl_clear_message (); + /* The searching is over. The user may have found the string that she + was looking for, or else she may have exited a failing search. If + LINE_INDEX is -1, then that shows that the string searched for was + not found. We use this to determine where to place rl_point. */ + return (_rl_isearch_cleanup (cxt, r)); +} - FREE (allocated_line); - free (lines); +#if defined (READLINE_CALLBACKS) +/* Called from the callback functions when we are ready to read a key. The + callback functions know to call this because RL_ISSTATE(RL_STATE_ISEARCH). + If _rl_isearch_dispatch finishes searching, this function is responsible + for turning off RL_STATE_ISEARCH, which it does using _rl_isearch_cleanup. */ +int +_rl_isearch_callback (cxt) + _rl_search_cxt *cxt; +{ + int c, r; - RL_UNSETSTATE(RL_STATE_ISEARCH); + c = _rl_search_getchar (cxt); + /* We might want to handle EOF here */ + r = _rl_isearch_dispatch (cxt, cxt->lastc); - return 0; + return (r <= 0) ? _rl_isearch_cleanup (cxt, r) : 0; } +#endif diff --git a/readline/keymaps.c b/readline/keymaps.c index 12506d3..70d0cc0 100644 --- a/readline/keymaps.c +++ b/readline/keymaps.c @@ -64,11 +64,13 @@ rl_make_bare_keymap () keymap[i].function = (rl_command_func_t *)NULL; } +#if 0 for (i = 'A'; i < ('Z' + 1); i++) { keymap[i].type = ISFUNC; keymap[i].function = rl_do_lowercase_version; } +#endif return (keymap); } @@ -79,8 +81,9 @@ rl_copy_keymap (map) Keymap map; { register int i; - Keymap temp = rl_make_bare_keymap (); + Keymap temp; + temp = rl_make_bare_keymap (); for (i = 0; i < KEYMAP_SIZE; i++) { temp[i].type = map[i].type; @@ -109,12 +112,8 @@ rl_make_keymap () newmap[CTRL('H')].function = rl_rubout; #if KEYMAP_SIZE > 128 - /* Printing characters in some 8-bit character sets. */ - for (i = 128; i < 160; i++) - newmap[i].function = rl_insert; - - /* ISO Latin-1 printing characters should self-insert. */ - for (i = 160; i < 256; i++) + /* Printing characters in ISO Latin-1 and some 8-bit character sets. */ + for (i = 128; i < 256; i++) newmap[i].function = rl_insert; #endif /* KEYMAP_SIZE > 128 */ diff --git a/readline/kill.c b/readline/kill.c index a616b92..1d3254c 100644 --- a/readline/kill.c +++ b/readline/kill.c @@ -339,6 +339,47 @@ rl_unix_word_rubout (count, key) if (rl_editing_mode == emacs_mode) rl_mark = rl_point; } + + return 0; +} + +/* This deletes one filename component in a Unix pathname. That is, it + deletes backward to directory separator (`/') or whitespace. */ +int +rl_unix_filename_rubout (count, key) + int count, key; +{ + int orig_point, c; + + if (rl_point == 0) + rl_ding (); + else + { + orig_point = rl_point; + if (count <= 0) + count = 1; + + while (count--) + { + c = rl_line_buffer[rl_point - 1]; + while (rl_point && (whitespace (c) || c == '/')) + { + rl_point--; + c = rl_line_buffer[rl_point - 1]; + } + + while (rl_point && (whitespace (c) == 0) && c != '/') + { + rl_point--; + c = rl_line_buffer[rl_point - 1]; + } + } + + rl_kill_text (orig_point, rl_point); + if (rl_editing_mode == emacs_mode) + rl_mark = rl_point; + } + return 0; } diff --git a/readline/macro.c b/readline/macro.c index b73c3af..2975bf1 100644 --- a/readline/macro.c +++ b/readline/macro.c @@ -100,6 +100,8 @@ _rl_with_macro_input (string) int _rl_next_macro_key () { + int c; + if (rl_executing_macro == 0) return (0); @@ -109,7 +111,14 @@ _rl_next_macro_key () return (_rl_next_macro_key ()); } +#if defined (READLINE_CALLBACKS) + c = rl_executing_macro[executing_macro_index++]; + if (RL_ISSTATE (RL_STATE_CALLBACK) && RL_ISSTATE (RL_STATE_READCMD) && rl_executing_macro[executing_macro_index] == 0) + _rl_pop_executing_macro (); + return c; +#else return (rl_executing_macro[executing_macro_index++]); +#endif } /* Save the currently executing macro on a stack of saved macros. */ diff --git a/readline/mbutil.c b/readline/mbutil.c index 8794d02..17dde53 100644 --- a/readline/mbutil.c +++ b/readline/mbutil.c @@ -1,6 +1,6 @@ /* mbutil.c -- readline multibyte character utility functions */ -/* Copyright (C) 2001 Free Software Foundation, Inc. +/* Copyright (C) 2001-2005 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -77,27 +77,29 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero) char *string; int seed, count, find_non_zero; { - size_t tmp = 0; + size_t tmp; mbstate_t ps; - int point = 0; + int point; wchar_t wc; + tmp = 0; + memset(&ps, 0, sizeof (mbstate_t)); if (seed < 0) seed = 0; if (count <= 0) return seed; - point = seed + _rl_adjust_point(string, seed, &ps); + point = seed + _rl_adjust_point (string, seed, &ps); /* if this is true, means that seed was not pointed character started byte. So correct the point and consume count */ if (seed < point) - count --; + count--; while (count > 0) { tmp = mbrtowc (&wc, string+point, strlen(string + point), &ps); - if ((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2) + if (MB_INVALIDCH ((size_t)tmp)) { /* invalid bytes. asume a byte represents a character */ point++; @@ -105,9 +107,8 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero) /* reset states. */ memset(&ps, 0, sizeof(mbstate_t)); } - else if (tmp == (size_t)0) - /* found '\0' char */ - break; + else if (MB_NULLWCH (tmp)) + break; /* found wide '\0' */ else { /* valid bytes */ @@ -127,15 +128,16 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero) if (find_non_zero) { tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps); - while (wcwidth (wc) == 0) + while (tmp > 0 && wcwidth (wc) == 0) { point += tmp; tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps); - if (tmp == (size_t)(0) || tmp == (size_t)(-1) || tmp == (size_t)(-2)) + if (MB_NULLWCH (tmp) || MB_INVALIDCH (tmp)) break; } } - return point; + + return point; } static int @@ -160,7 +162,7 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero) while (point < seed) { tmp = mbrtowc (&wc, string + point, length - point, &ps); - if ((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2) + if (MB_INVALIDCH ((size_t)tmp)) { /* in this case, bytes are invalid or shorted to compose multibyte char, so assume that the first byte represents @@ -169,8 +171,12 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero) /* clear the state of the byte sequence, because in this case effect of mbstate is undefined */ memset(&ps, 0, sizeof (mbstate_t)); + + /* Since we're assuming that this byte represents a single + non-zero-width character, don't forget about it. */ + prev = point; } - else if (tmp == 0) + else if (MB_NULLWCH (tmp)) break; /* Found '\0' char. Can this happen? */ else { @@ -273,7 +279,7 @@ _rl_adjust_point(string, point, ps) while (pos < point) { tmp = mbrlen (string + pos, length - pos, ps); - if((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2) + if (MB_INVALIDCH ((size_t)tmp)) { /* in this case, bytes are invalid or shorted to compose multibyte char, so assume that the first byte represents @@ -284,7 +290,7 @@ _rl_adjust_point(string, point, ps) if (ps) memset (ps, 0, sizeof (mbstate_t)); } - else if (tmp == 0) + else if (MB_NULLWCH (tmp)) pos++; else pos += tmp; @@ -310,6 +316,28 @@ _rl_is_mbchar_matched (string, seed, end, mbchar, length) return 0; return 1; } + +wchar_t +_rl_char_value (buf, ind) + char *buf; + int ind; +{ + size_t tmp; + wchar_t wc; + mbstate_t ps; + int l; + + if (MB_LEN_MAX == 1 || rl_byte_oriented) + return ((wchar_t) buf[ind]); + l = strlen (buf); + if (ind >= l - 1) + return ((wchar_t) buf[ind]); + memset (&ps, 0, sizeof (mbstate_t)); + tmp = mbrtowc (&wc, buf + ind, l - ind, &ps); + if (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp)) + return ((wchar_t) buf[ind]); + return wc; +} #endif /* HANDLE_MULTIBYTE */ /* Find next `count' characters started byte point of the specified seed. diff --git a/readline/misc.c b/readline/misc.c index f3775d3..d455832 100644 --- a/readline/misc.c +++ b/readline/misc.c @@ -1,6 +1,6 @@ /* misc.c -- miscellaneous bindable readline functions. */ -/* Copyright (C) 1987-2002 Free Software Foundation, Inc. +/* Copyright (C) 1987-2005 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -63,6 +63,8 @@ void _rl_free_history_entry PARAMS((HIST_ENTRY *)); to preserve the value of rl_point from line to line. */ int _rl_history_preserve_point = 0; +_rl_arg_cxt _rl_argcxt; + /* Saved target point for when _rl_history_preserve_point is set. Special value of -1 means that point is at the end of the line. */ int _rl_history_saved_point = -1; @@ -73,77 +75,74 @@ int _rl_history_saved_point = -1; /* */ /* **************************************************************** */ -/* Handle C-u style numeric args, as well as M--, and M-digits. */ -static int -rl_digit_loop () +int +_rl_arg_overflow () { - int key, c, sawminus, sawdigits; + if (rl_numeric_arg > 1000000) + { + _rl_argcxt = 0; + rl_explicit_arg = rl_numeric_arg = 0; + rl_ding (); + rl_restore_prompt (); + rl_clear_message (); + RL_UNSETSTATE(RL_STATE_NUMERICARG); + return 1; + } + return 0; +} +void +_rl_arg_init () +{ rl_save_prompt (); - + _rl_argcxt = 0; RL_SETSTATE(RL_STATE_NUMERICARG); - sawminus = sawdigits = 0; - while (1) - { - if (rl_numeric_arg > 1000000) - { - sawdigits = rl_explicit_arg = rl_numeric_arg = 0; - rl_ding (); - rl_restore_prompt (); - rl_clear_message (); - RL_UNSETSTATE(RL_STATE_NUMERICARG); - return 1; - } - rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg); - RL_SETSTATE(RL_STATE_MOREINPUT); - key = c = rl_read_key (); - RL_UNSETSTATE(RL_STATE_MOREINPUT); +} - if (c < 0) - { - _rl_abort_internal (); - return -1; - } +int +_rl_arg_getchar () +{ + int c; - /* If we see a key bound to `universal-argument' after seeing digits, - it ends the argument but is otherwise ignored. */ - if (_rl_keymap[c].type == ISFUNC && - _rl_keymap[c].function == rl_universal_argument) - { - if (sawdigits == 0) - { - rl_numeric_arg *= 4; - continue; - } - else - { - RL_SETSTATE(RL_STATE_MOREINPUT); - key = rl_read_key (); - RL_UNSETSTATE(RL_STATE_MOREINPUT); - rl_restore_prompt (); - rl_clear_message (); - RL_UNSETSTATE(RL_STATE_NUMERICARG); - return (_rl_dispatch (key, _rl_keymap)); - } - } + rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg); + RL_SETSTATE(RL_STATE_MOREINPUT); + c = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); - c = UNMETA (c); + return c; +} - if (_rl_digit_p (c)) - { - rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + c - '0' : c - '0'; - sawdigits = rl_explicit_arg = 1; - } - else if (c == '-' && rl_explicit_arg == 0) +/* Process C as part of the current numeric argument. Return -1 if the + argument should be aborted, 0 if we should not read any more chars, and + 1 if we should continue to read chars. */ +int +_rl_arg_dispatch (cxt, c) + _rl_arg_cxt cxt; + int c; +{ + int key, r; + + key = c; + + /* If we see a key bound to `universal-argument' after seeing digits, + it ends the argument but is otherwise ignored. */ + if (_rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument) + { + if ((cxt & NUM_SAWDIGITS) == 0) { - rl_numeric_arg = sawminus = 1; - rl_arg_sign = -1; + rl_numeric_arg *= 4; + return 1; } + else if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + _rl_argcxt |= NUM_READONE; + return 0; /* XXX */ + } else { - /* Make M-- command equivalent to M--1 command. */ - if (sawminus && rl_numeric_arg == 1 && rl_explicit_arg == 0) - rl_explicit_arg = 1; + RL_SETSTATE(RL_STATE_MOREINPUT); + key = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); rl_restore_prompt (); rl_clear_message (); RL_UNSETSTATE(RL_STATE_NUMERICARG); @@ -151,35 +150,96 @@ rl_digit_loop () } } - /*NOTREACHED*/ -} + c = UNMETA (c); -/* Add the current digit to the argument in progress. */ -int -rl_digit_argument (ignore, key) - int ignore, key; -{ - rl_execute_next (key); - return (rl_digit_loop ()); + if (_rl_digit_p (c)) + { + r = _rl_digit_value (c); + rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + r : r; + rl_explicit_arg = 1; + _rl_argcxt |= NUM_SAWDIGITS; + } + else if (c == '-' && rl_explicit_arg == 0) + { + rl_numeric_arg = 1; + _rl_argcxt |= NUM_SAWMINUS; + rl_arg_sign = -1; + } + else + { + /* Make M-- command equivalent to M--1 command. */ + if ((_rl_argcxt & NUM_SAWMINUS) && rl_numeric_arg == 1 && rl_explicit_arg == 0) + rl_explicit_arg = 1; + rl_restore_prompt (); + rl_clear_message (); + RL_UNSETSTATE(RL_STATE_NUMERICARG); + + r = _rl_dispatch (key, _rl_keymap); + if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + /* At worst, this will cause an extra redisplay. Otherwise, + we have to wait until the next character comes in. */ + if (rl_done == 0) + (*rl_redisplay_function) (); + r = 0; + } + return r; + } + + return 1; } -/* What to do when you abort reading an argument. */ -int -rl_discard_argument () +/* Handle C-u style numeric args, as well as M--, and M-digits. */ +static int +rl_digit_loop () { - rl_ding (); - rl_clear_message (); - _rl_init_argument (); - return 0; + int c, r; + + while (1) + { + if (_rl_arg_overflow ()) + return 1; + + c = _rl_arg_getchar (); + + if (c < 0) + { + _rl_abort_internal (); + return -1; + } + + r = _rl_arg_dispatch (_rl_argcxt, c); + if (r <= 0 || (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)) + break; + } } /* Create a default argument. */ -int -_rl_init_argument () +void +_rl_reset_argument () { rl_numeric_arg = rl_arg_sign = 1; rl_explicit_arg = 0; - return 0; + _rl_argcxt = 0; +} + +/* Start a numeric argument with initial value KEY */ +int +rl_digit_argument (ignore, key) + int ignore, key; +{ + _rl_arg_init (); + if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + _rl_arg_dispatch (_rl_argcxt, key); + rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg); + return 0; + } + else + { + rl_execute_next (key); + return (rl_digit_loop ()); + } } /* C-u, universal argument. Multiply the current argument by 4. @@ -189,8 +249,43 @@ int rl_universal_argument (count, key) int count, key; { + _rl_arg_init (); rl_numeric_arg *= 4; - return (rl_digit_loop ()); + + return (RL_ISSTATE (RL_STATE_CALLBACK) ? 0 : rl_digit_loop ()); +} + +int +_rl_arg_callback (cxt) + _rl_arg_cxt cxt; +{ + int c, r; + + c = _rl_arg_getchar (); + + if (_rl_argcxt & NUM_READONE) + { + _rl_argcxt &= ~NUM_READONE; + rl_restore_prompt (); + rl_clear_message (); + RL_UNSETSTATE(RL_STATE_NUMERICARG); + rl_execute_next (c); + return 0; + } + + r = _rl_arg_dispatch (cxt, c); + return (r != 1); +} + +/* What to do when you abort reading an argument. */ +int +rl_discard_argument () +{ + rl_ding (); + rl_clear_message (); + _rl_reset_argument (); + + return 0; } /* **************************************************************** */ @@ -225,8 +320,10 @@ _rl_free_history_entry (entry) { if (entry == 0) return; - if (entry->line) - free (entry->line); + + FREE (entry->line); + FREE (entry->timestamp); + free (entry); } @@ -242,6 +339,7 @@ rl_maybe_replace_line () { temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list); free (temp->line); + FREE (temp->timestamp); free (temp); } return 0; @@ -253,6 +351,8 @@ rl_maybe_unsave_line () { if (_rl_saved_line_for_history) { + /* Can't call with `1' because rl_undo_list might point to an undo + list from a history entry, as in rl_replace_from_history() below. */ rl_replace_line (_rl_saved_line_for_history->line, 0); rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data; _rl_free_history_entry (_rl_saved_line_for_history); @@ -272,8 +372,10 @@ rl_maybe_save_line () { _rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY)); _rl_saved_line_for_history->line = savestring (rl_line_buffer); + _rl_saved_line_for_history->timestamp = (char *)NULL; _rl_saved_line_for_history->data = (char *)rl_undo_list; } + return 0; } @@ -298,7 +400,7 @@ _rl_history_set_point () rl_point = rl_end; #if defined (VI_MODE) - if (rl_editing_mode == vi_mode) + if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap) rl_point = 0; #endif /* VI_MODE */ @@ -311,6 +413,8 @@ rl_replace_from_history (entry, flags) HIST_ENTRY *entry; int flags; /* currently unused */ { + /* Can't call with `1' because rl_undo_list might point to an undo list + from a history entry, just like we're setting up here. */ rl_replace_line (entry->line, 0); rl_undo_list = (UNDO_LIST *)entry->data; rl_point = rl_end; @@ -435,6 +539,7 @@ rl_get_previous_history (count, key) rl_replace_from_history (temp, 0); _rl_history_set_point (); } + return 0; } diff --git a/readline/nls.c b/readline/nls.c index 706c819..bcee875 100644 --- a/readline/nls.c +++ b/readline/nls.c @@ -75,6 +75,23 @@ static char *normalize_codeset PARAMS((char *)); static char *find_codeset PARAMS((char *, size_t *)); #endif /* !HAVE_SETLOCALE */ +static char *_rl_get_locale_var PARAMS((const char *)); + +static char * +_rl_get_locale_var (v) + const char *v; +{ + char *lspec; + + lspec = sh_get_env_value ("LC_ALL"); + if (lspec == 0 || *lspec == 0) + lspec = sh_get_env_value (v); + if (lspec == 0 || *lspec == 0) + lspec = sh_get_env_value ("LANG"); + + return lspec; +} + /* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value to decide the defaults for 8-bit character input and output. Returns 1 if we set eight-bit mode. */ @@ -84,10 +101,21 @@ _rl_init_eightbit () /* If we have setlocale(3), just check the current LC_CTYPE category value, and go into eight-bit mode if it's not C or POSIX. */ #if defined (HAVE_SETLOCALE) - char *t; + char *lspec, *t; /* Set the LC_CTYPE locale category from environment variables. */ - t = setlocale (LC_CTYPE, ""); + lspec = _rl_get_locale_var ("LC_CTYPE"); + /* Since _rl_get_locale_var queries the right environment variables, + we query the current locale settings with setlocale(), and, if + that doesn't return anything, we set lspec to the empty string to + force the subsequent call to setlocale() to define the `native' + environment. */ + if (lspec == 0 || *lspec == 0) + lspec = setlocale (LC_CTYPE, (char *)NULL); + if (lspec == 0) + lspec = ""; + t = setlocale (LC_CTYPE, lspec); + if (t && *t && (t[0] != 'C' || t[1]) && (STREQ (t, "POSIX") == 0)) { _rl_meta_flag = 1; @@ -105,9 +133,8 @@ _rl_init_eightbit () /* We don't have setlocale. Finesse it. Check the environment for the appropriate variables and set eight-bit mode if they have the right values. */ - lspec = sh_get_env_value ("LC_ALL"); - if (lspec == 0) lspec = sh_get_env_value ("LC_CTYPE"); - if (lspec == 0) lspec = sh_get_env_value ("LANG"); + lspec = _rl_get_locale_var ("LC_CTYPE"); + if (lspec == 0 || (t = normalize_codeset (lspec)) == 0) return (0); for (i = 0; t && legal_lang_values[i]; i++) diff --git a/readline/parens.c b/readline/parens.c index 54ef1f3..737f767 100644 --- a/readline/parens.c +++ b/readline/parens.c @@ -21,6 +21,10 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY +#if defined (__TANDEM) +# include <floss.h> +#endif + #include "rlconf.h" #if defined (HAVE_CONFIG_H) diff --git a/readline/posixdir.h b/readline/posixdir.h index 505e279..91f6d96 100644 --- a/readline/posixdir.h +++ b/readline/posixdir.h @@ -25,7 +25,11 @@ #if defined (HAVE_DIRENT_H) # include <dirent.h> -# define D_NAMLEN(d) (strlen ((d)->d_name)) +# if defined (HAVE_STRUCT_DIRENT_D_NAMLEN) +# define D_NAMLEN(d) ((d)->d_namlen) +# else +# define D_NAMLEN(d) (strlen ((d)->d_name)) +# endif /* !HAVE_STRUCT_DIRENT_D_NAMLEN */ #else # if defined (HAVE_SYS_NDIR_H) # include <sys/ndir.h> @@ -42,11 +46,11 @@ # define D_NAMLEN(d) ((d)->d_namlen) #endif /* !HAVE_DIRENT_H */ -#if defined (STRUCT_DIRENT_HAS_D_INO) && !defined (STRUCT_DIRENT_HAS_D_FILENO) +#if defined (HAVE_STRUCT_DIRENT_D_INO) && !defined (HAVE_STRUCT_DIRENT_D_FILENO) # define d_fileno d_ino #endif -#if defined (_POSIX_SOURCE) && (!defined (STRUCT_DIRENT_HAS_D_INO) || defined (BROKEN_DIRENT_D_INO)) +#if defined (_POSIX_SOURCE) && (!defined (HAVE_STRUCT_DIRENT_D_INO) || defined (BROKEN_DIRENT_D_INO)) /* Posix does not require that the d_ino field be present, and some systems do not provide it. */ # define REAL_DIR_ENTRY(dp) 1 diff --git a/readline/readline.c b/readline/readline.c index 07fb58f..5eaaf47 100644 --- a/readline/readline.c +++ b/readline/readline.c @@ -1,7 +1,7 @@ /* readline.c -- a general facility for reading lines of input with emacs style editing and completion. */ -/* Copyright (C) 1987-2002 Free Software Foundation, Inc. +/* Copyright (C) 1987-2005 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -68,11 +68,11 @@ #include "xmalloc.h" #ifndef RL_LIBRARY_VERSION -# define RL_LIBRARY_VERSION "4.3" +# define RL_LIBRARY_VERSION "5.1" #endif #ifndef RL_READLINE_VERSION -# define RL_READLINE_VERSION 0x0403 +# define RL_READLINE_VERSION 0x0501 #endif extern void _rl_free_history_entry PARAMS((HIST_ENTRY *)); @@ -85,6 +85,10 @@ static void bind_arrow_keys_internal PARAMS((Keymap)); static void bind_arrow_keys PARAMS((void)); static void readline_default_bindings PARAMS((void)); +static void reset_default_bindings PARAMS((void)); + +static int _rl_subseq_result PARAMS((int, Keymap, int, int)); +static int _rl_subseq_getchar PARAMS((int)); /* **************************************************************** */ /* */ @@ -103,6 +107,7 @@ int rl_gnu_readline_p = 1; By default, it is the standard emacs keymap. */ Keymap _rl_keymap = emacs_standard_keymap; + /* The current style of editing. */ int rl_editing_mode = emacs_mode; @@ -218,6 +223,9 @@ char *_rl_comment_begin; /* Keymap holding the function currently being executed. */ Keymap rl_executing_keymap; +/* Keymap we're currently using to dispatch. */ +Keymap _rl_dispatching_keymap; + /* Non-zero means to erase entire line, including prompt, on empty input lines. */ int rl_erase_empty_line = 0; @@ -229,6 +237,9 @@ int rl_num_chars_to_read; char *rl_line_buffer = (char *)NULL; int rl_line_buffer_len = 0; +/* Key sequence `contexts' */ +_rl_keyseq_cxt *_rl_kscxt = 0; + /* Forward declarations used by the display, termcap, and history code. */ /* **************************************************************** */ @@ -250,6 +261,10 @@ int _rl_convert_meta_chars_to_ascii = 1; rather than as a meta-prefixed escape sequence. */ int _rl_output_meta_chars = 0; +/* Non-zero means to look at the termios special characters and bind + them to equivalent readline functions at startup. */ +int _rl_bind_stty_chars = 1; + /* **************************************************************** */ /* */ /* Top Level Functions */ @@ -267,6 +282,7 @@ rl_set_prompt (prompt) { FREE (rl_prompt); rl_prompt = prompt ? savestring (prompt) : (char *)NULL; + rl_display_prompt = rl_prompt ? rl_prompt : ""; rl_visible_prompt_length = rl_expand_prompt (rl_prompt); return 0; @@ -290,14 +306,16 @@ readline (prompt) rl_set_prompt (prompt); rl_initialize (); - (*rl_prep_term_function) (_rl_meta_flag); + if (rl_prep_term_function) + (*rl_prep_term_function) (_rl_meta_flag); #if defined (HANDLE_SIGNALS) rl_set_signals (); #endif value = readline_internal (); - (*rl_deprep_term_function) (); + if (rl_deprep_term_function) + (*rl_deprep_term_function) (); #if defined (HANDLE_SIGNALS) rl_clear_signals (); @@ -347,7 +365,7 @@ readline_internal_setup () #if defined (VI_MODE) if (rl_editing_mode == vi_mode) - rl_vi_insertion_mode (1, 0); + rl_vi_insertion_mode (1, 'i'); #endif /* VI_MODE */ if (rl_pre_input_hook) @@ -387,6 +405,36 @@ readline_internal_teardown (eof) return (eof ? (char *)NULL : savestring (the_line)); } +void +_rl_internal_char_cleanup () +{ +#if defined (VI_MODE) + /* In vi mode, when you exit insert mode, the cursor moves back + over the previous character. We explicitly check for that here. */ + if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap) + rl_vi_check (); +#endif /* VI_MODE */ + + if (rl_num_chars_to_read && rl_end >= rl_num_chars_to_read) + { + (*rl_redisplay_function) (); + _rl_want_redisplay = 0; + rl_newline (1, '\n'); + } + + if (rl_done == 0) + { + (*rl_redisplay_function) (); + _rl_want_redisplay = 0; + } + + /* If the application writer has told us to erase the entire line if + the only character typed was something bound to rl_newline, do so. */ + if (rl_erase_empty_line && rl_done && rl_last_func == rl_newline && + rl_point == 0 && rl_end == 0) + _rl_erase_entire_line (); +} + STATIC_CALLBACK int #if defined (READLINE_CALLBACKS) readline_internal_char () @@ -409,12 +457,21 @@ readline_internal_charloop () code = setjmp (readline_top_level); if (code) - (*rl_redisplay_function) (); + { + (*rl_redisplay_function) (); + _rl_want_redisplay = 0; + /* If we get here, we're not being called from something dispatched + from _rl_callback_read_char(), which sets up its own value of + readline_top_level (saving and restoring the old, of course), so + we can just return here. */ + if (RL_ISSTATE (RL_STATE_CALLBACK)) + return (0); + } if (rl_pending_input == 0) { /* Then initialize the argument and number of keys read. */ - _rl_init_argument (); + _rl_reset_argument (); rl_key_sequence_length = 0; } @@ -448,27 +505,7 @@ readline_internal_charloop () if (rl_pending_input == 0 && lk == _rl_last_command_was_kill) _rl_last_command_was_kill = 0; -#if defined (VI_MODE) - /* In vi mode, when you exit insert mode, the cursor moves back - over the previous character. We explicitly check for that here. */ - if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap) - rl_vi_check (); -#endif /* VI_MODE */ - - if (rl_num_chars_to_read && rl_end >= rl_num_chars_to_read) - { - (*rl_redisplay_function) (); - rl_newline (1, '\n'); - } - - if (rl_done == 0) - (*rl_redisplay_function) (); - - /* If the application writer has told us to erase the entire line if - the only character typed was something bound to rl_newline, do so. */ - if (rl_erase_empty_line && rl_done && rl_last_func == rl_newline && - rl_point == 0 && rl_end == 0) - _rl_erase_entire_line (); + _rl_internal_char_cleanup (); #if defined (READLINE_CALLBACKS) return 0; @@ -518,6 +555,107 @@ _rl_set_the_line () the_line = rl_line_buffer; } +#if defined (READLINE_CALLBACKS) +_rl_keyseq_cxt * +_rl_keyseq_cxt_alloc () +{ + _rl_keyseq_cxt *cxt; + + cxt = (_rl_keyseq_cxt *)xmalloc (sizeof (_rl_keyseq_cxt)); + + cxt->flags = cxt->subseq_arg = cxt->subseq_retval = 0; + + cxt->okey = 0; + cxt->ocxt = _rl_kscxt; + cxt->childval = 42; /* sentinel value */ + + return cxt; +} + +void +_rl_keyseq_cxt_dispose (cxt) + _rl_keyseq_cxt *cxt; +{ + free (cxt); +} + +void +_rl_keyseq_chain_dispose () +{ + _rl_keyseq_cxt *cxt; + + while (_rl_kscxt) + { + cxt = _rl_kscxt; + _rl_kscxt = _rl_kscxt->ocxt; + _rl_keyseq_cxt_dispose (cxt); + } +} +#endif + +static int +_rl_subseq_getchar (key) + int key; +{ + int k; + + if (key == ESC) + RL_SETSTATE(RL_STATE_METANEXT); + RL_SETSTATE(RL_STATE_MOREINPUT); + k = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + if (key == ESC) + RL_UNSETSTATE(RL_STATE_METANEXT); + + return k; +} + +#if defined (READLINE_CALLBACKS) +int +_rl_dispatch_callback (cxt) + _rl_keyseq_cxt *cxt; +{ + int nkey, r; + + /* For now */ +#if 1 + /* The first time this context is used, we want to read input and dispatch + on it. When traversing the chain of contexts back `up', we want to use + the value from the next context down. We're simulating recursion using + a chain of contexts. */ + if ((cxt->flags & KSEQ_DISPATCHED) == 0) + { + nkey = _rl_subseq_getchar (cxt->okey); + r = _rl_dispatch_subseq (nkey, cxt->dmap, cxt->subseq_arg); + cxt->flags |= KSEQ_DISPATCHED; + } + else + r = cxt->childval; +#else + r = _rl_dispatch_subseq (nkey, cxt->dmap, cxt->subseq_arg); +#endif + + /* For now */ + r = _rl_subseq_result (r, cxt->oldmap, cxt->okey, (cxt->flags & KSEQ_SUBSEQ)); + + if (r == 0) /* success! */ + { + _rl_keyseq_chain_dispose (); + RL_UNSETSTATE (RL_STATE_MULTIKEY); + return r; + } + + if (r != -3) /* magic value that says we added to the chain */ + _rl_kscxt = cxt->ocxt; + if (_rl_kscxt) + _rl_kscxt->childval = r; + if (r != -3) + _rl_keyseq_cxt_dispose (cxt); + + return r; +} +#endif /* READLINE_CALLBACKS */ + /* Do the command associated with KEY in MAP. If the associated command is really a keymap, then read another key, and dispatch into that map. */ @@ -526,6 +664,7 @@ _rl_dispatch (key, map) register int key; Keymap map; { + _rl_dispatching_keymap = map; return _rl_dispatch_subseq (key, map, 0); } @@ -538,6 +677,9 @@ _rl_dispatch_subseq (key, map, got_subseq) int r, newkey; char *macro; rl_command_func_t *func; +#if defined (READLINE_CALLBACKS) + _rl_keyseq_cxt *cxt; +#endif if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii) { @@ -571,13 +713,9 @@ _rl_dispatch_subseq (key, map, got_subseq) rl_executing_keymap = map; -#if 0 - _rl_suppress_redisplay = (map[key].function == rl_insert) && _rl_input_available (); -#endif - rl_dispatching = 1; RL_SETSTATE(RL_STATE_DISPATCHING); - r = (*map[key].function)(rl_numeric_arg * rl_arg_sign, key); + (*map[key].function)(rl_numeric_arg * rl_arg_sign, key); RL_UNSETSTATE(RL_STATE_DISPATCHING); rl_dispatching = 0; @@ -606,6 +744,10 @@ _rl_dispatch_subseq (key, map, got_subseq) } else { +#if defined (READLINE_CALLBACKS) + RL_UNSETSTATE (RL_STATE_MULTIKEY); + _rl_keyseq_chain_dispose (); +#endif _rl_abort_internal (); return -1; } @@ -627,44 +769,43 @@ _rl_dispatch_subseq (key, map, got_subseq) #endif rl_key_sequence_length++; + _rl_dispatching_keymap = FUNCTION_TO_KEYMAP (map, key); - if (key == ESC) - RL_SETSTATE(RL_STATE_METANEXT); - RL_SETSTATE(RL_STATE_MOREINPUT); - newkey = rl_read_key (); - RL_UNSETSTATE(RL_STATE_MOREINPUT); - if (key == ESC) - RL_UNSETSTATE(RL_STATE_METANEXT); + /* Allocate new context here. Use linked contexts (linked through + cxt->ocxt) to simulate recursion */ +#if defined (READLINE_CALLBACKS) + if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + /* Return 0 only the first time, to indicate success to + _rl_callback_read_char. The rest of the time, we're called + from _rl_dispatch_callback, so we return 3 to indicate + special handling is necessary. */ + r = RL_ISSTATE (RL_STATE_MULTIKEY) ? -3 : 0; + cxt = _rl_keyseq_cxt_alloc (); + + if (got_subseq) + cxt->flags |= KSEQ_SUBSEQ; + cxt->okey = key; + cxt->oldmap = map; + cxt->dmap = _rl_dispatching_keymap; + cxt->subseq_arg = got_subseq || cxt->dmap[ANYOTHERKEY].function; + + RL_SETSTATE (RL_STATE_MULTIKEY); + _rl_kscxt = cxt; + + return r; /* don't indicate immediate success */ + } +#endif + newkey = _rl_subseq_getchar (key); if (newkey < 0) { _rl_abort_internal (); return -1; } - r = _rl_dispatch_subseq (newkey, FUNCTION_TO_KEYMAP (map, key), got_subseq || map[ANYOTHERKEY].function); - - if (r == -2) - /* We didn't match anything, and the keymap we're indexed into - shadowed a function previously bound to that prefix. Call - the function. The recursive call to _rl_dispatch_subseq has - already taken care of pushing any necessary input back onto - the input queue with _rl_unget_char. */ - r = _rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key)); - else if (r && map[ANYOTHERKEY].function) - { - /* We didn't match (r is probably -1), so return something to - tell the caller that it should try ANYOTHERKEY for an - overridden function. */ - _rl_unget_char (key); - return -2; - } - else if (r && got_subseq) - { - /* OK, back up the chain. */ - _rl_unget_char (key); - return -1; - } + r = _rl_dispatch_subseq (newkey, _rl_dispatching_keymap, got_subseq || map[ANYOTHERKEY].function); + return _rl_subseq_result (r, map, key, got_subseq); } else { @@ -688,9 +829,69 @@ _rl_dispatch_subseq (key, map, got_subseq) _rl_vi_textmod_command (key)) _rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign); #endif + return (r); } +static int +_rl_subseq_result (r, map, key, got_subseq) + int r; + Keymap map; + int key, got_subseq; +{ + Keymap m; + int type, nt; + rl_command_func_t *func, *nf; + + if (r == -2) + /* We didn't match anything, and the keymap we're indexed into + shadowed a function previously bound to that prefix. Call + the function. The recursive call to _rl_dispatch_subseq has + already taken care of pushing any necessary input back onto + the input queue with _rl_unget_char. */ + { + m = _rl_dispatching_keymap; + type = m[ANYOTHERKEY].type; + func = m[ANYOTHERKEY].function; + if (type == ISFUNC && func == rl_do_lowercase_version) + r = _rl_dispatch (_rl_to_lower (key), map); + else if (type == ISFUNC && func == rl_insert) + { + /* If the function that was shadowed was self-insert, we + somehow need a keymap with map[key].func == self-insert. + Let's use this one. */ + nt = m[key].type; + nf = m[key].function; + + m[key].type = type; + m[key].function = func; + r = _rl_dispatch (key, m); + m[key].type = nt; + m[key].function = nf; + } + else + r = _rl_dispatch (ANYOTHERKEY, m); + } + else if (r && map[ANYOTHERKEY].function) + { + /* We didn't match (r is probably -1), so return something to + tell the caller that it should try ANYOTHERKEY for an + overridden function. */ + _rl_unget_char (key); + _rl_dispatching_keymap = map; + return -2; + } + else if (r && got_subseq) + { + /* OK, back up the chain. */ + _rl_unget_char (key); + _rl_dispatching_keymap = map; + return -1; + } + + return r; +} + /* **************************************************************** */ /* */ /* Initializations */ @@ -839,7 +1040,7 @@ readline_initialize_everything () /* If the completion parser's default word break characters haven't been set yet, then do so now. */ if (rl_completer_word_break_characters == (char *)NULL) - rl_completer_word_break_characters = rl_basic_word_break_characters; + rl_completer_word_break_characters = (char *)rl_basic_word_break_characters; } /* If this system allows us to look at the values of the regular @@ -848,7 +1049,20 @@ readline_initialize_everything () static void readline_default_bindings () { - rl_tty_set_default_bindings (_rl_keymap); + if (_rl_bind_stty_chars) + rl_tty_set_default_bindings (_rl_keymap); +} + +/* Reset the default bindings for the terminal special characters we're + interested in back to rl_insert and read the new ones. */ +static void +reset_default_bindings () +{ + if (_rl_bind_stty_chars) + { + rl_tty_unset_default_bindings (_rl_keymap); + rl_tty_set_default_bindings (_rl_keymap); + } } /* Bind some common arrow key sequences in MAP. */ @@ -862,42 +1076,33 @@ bind_arrow_keys_internal (map) _rl_keymap = map; #if defined (__MSDOS__) - _rl_bind_if_unbound ("\033[0A", rl_get_previous_history); - _rl_bind_if_unbound ("\033[0B", rl_backward_char); - _rl_bind_if_unbound ("\033[0C", rl_forward_char); - _rl_bind_if_unbound ("\033[0D", rl_get_next_history); + rl_bind_keyseq_if_unbound ("\033[0A", rl_get_previous_history); + rl_bind_keyseq_if_unbound ("\033[0B", rl_backward_char); + rl_bind_keyseq_if_unbound ("\033[0C", rl_forward_char); + rl_bind_keyseq_if_unbound ("\033[0D", rl_get_next_history); #endif -#ifdef __MINGW32__ - /* Under Windows, when an extend key (like an arrow key) is - pressed, getch() will return 340 (octal) followed by a code for - the extended key. We use macros to transform those into the - normal ANSI terminal sequences for these keys. */ - - /* Up arrow. */ - rl_macro_bind ("\340H", "\033[A", map); - /* Left arrow. */ - rl_macro_bind ("\340K", "\033[D", map); - /* Right arrow. */ - rl_macro_bind ("\340M", "\033[C", map); - /* Down arrow. */ - rl_macro_bind ("\340P", "\033[B", map); + rl_bind_keyseq_if_unbound ("\033[A", rl_get_previous_history); + rl_bind_keyseq_if_unbound ("\033[B", rl_get_next_history); + rl_bind_keyseq_if_unbound ("\033[C", rl_forward_char); + rl_bind_keyseq_if_unbound ("\033[D", rl_backward_char); + rl_bind_keyseq_if_unbound ("\033[H", rl_beg_of_line); + rl_bind_keyseq_if_unbound ("\033[F", rl_end_of_line); + + rl_bind_keyseq_if_unbound ("\033OA", rl_get_previous_history); + rl_bind_keyseq_if_unbound ("\033OB", rl_get_next_history); + rl_bind_keyseq_if_unbound ("\033OC", rl_forward_char); + rl_bind_keyseq_if_unbound ("\033OD", rl_backward_char); + rl_bind_keyseq_if_unbound ("\033OH", rl_beg_of_line); + rl_bind_keyseq_if_unbound ("\033OF", rl_end_of_line); + +#if defined (__MINGW32__) + rl_bind_keyseq_if_unbound ("\340H", rl_get_previous_history); + rl_bind_keyseq_if_unbound ("\340P", rl_get_next_history); + rl_bind_keyseq_if_unbound ("\340M", rl_forward_char); + rl_bind_keyseq_if_unbound ("\340K", rl_backward_char); #endif - _rl_bind_if_unbound ("\033[A", rl_get_previous_history); - _rl_bind_if_unbound ("\033[B", rl_get_next_history); - _rl_bind_if_unbound ("\033[C", rl_forward_char); - _rl_bind_if_unbound ("\033[D", rl_backward_char); - _rl_bind_if_unbound ("\033[H", rl_beg_of_line); - _rl_bind_if_unbound ("\033[F", rl_end_of_line); - - _rl_bind_if_unbound ("\033OA", rl_get_previous_history); - _rl_bind_if_unbound ("\033OB", rl_get_next_history); - _rl_bind_if_unbound ("\033OC", rl_forward_char); - _rl_bind_if_unbound ("\033OD", rl_backward_char); - _rl_bind_if_unbound ("\033OH", rl_beg_of_line); - _rl_bind_if_unbound ("\033OF", rl_end_of_line); - _rl_keymap = xkeymap; } @@ -950,9 +1155,7 @@ rl_save_state (sp) sp->macro = rl_executing_macro; sp->catchsigs = rl_catch_signals; -#if defined (SIGWINCH) sp->catchsigwinch = rl_catch_sigwinch; -#endif return (0); } @@ -986,9 +1189,7 @@ rl_restore_state (sp) rl_executing_macro = sp->macro; rl_catch_signals = sp->catchsigs; -#if defined (SIGWINCH) rl_catch_sigwinch = sp->catchsigwinch; -#endif return (0); } diff --git a/readline/readline.h b/readline/readline.h index f11b3d0..fade6d4 100644 --- a/readline/readline.h +++ b/readline/readline.h @@ -1,6 +1,6 @@ /* Readline.h -- the names of functions callable from within readline. */ -/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc. +/* Copyright (C) 1987-2005 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -40,9 +40,9 @@ extern "C" { #endif /* Hex-encoded Readline version number. */ -#define RL_READLINE_VERSION 0x0403 /* Readline 4.3 */ -#define RL_VERSION_MAJOR 4 -#define RL_VERSION_MINOR 3 +#define RL_READLINE_VERSION 0x0501 /* Readline 5.1 */ +#define RL_VERSION_MAJOR 5 +#define RL_VERSION_MINOR 1 /* Readline data structures. */ @@ -160,6 +160,7 @@ extern int rl_kill_line PARAMS((int, int)); extern int rl_backward_kill_line PARAMS((int, int)); extern int rl_kill_full_line PARAMS((int, int)); extern int rl_unix_word_rubout PARAMS((int, int)); +extern int rl_unix_filename_rubout PARAMS((int, int)); extern int rl_unix_line_discard PARAMS((int, int)); extern int rl_copy_region_to_kill PARAMS((int, int)); extern int rl_kill_region PARAMS((int, int)); @@ -240,6 +241,7 @@ extern int rl_vi_column PARAMS((int, int)); extern int rl_vi_delete_to PARAMS((int, int)); extern int rl_vi_change_to PARAMS((int, int)); extern int rl_vi_yank_to PARAMS((int, int)); +extern int rl_vi_rubout PARAMS((int, int)); extern int rl_vi_delete PARAMS((int, int)); extern int rl_vi_back_to_indent PARAMS((int, int)); extern int rl_vi_first_print PARAMS((int, int)); @@ -258,6 +260,8 @@ extern int rl_vi_check PARAMS((void)); extern int rl_vi_domove PARAMS((int, int *)); extern int rl_vi_bracktype PARAMS((int)); +extern void rl_vi_start_inserting PARAMS((int, int, int)); + /* VI-mode pseudo-bindable commands, used as utility functions. */ extern int rl_vi_fWord PARAMS((int, int)); extern int rl_vi_bWord PARAMS((int, int)); @@ -290,12 +294,22 @@ extern int rl_bind_key PARAMS((int, rl_command_func_t *)); extern int rl_bind_key_in_map PARAMS((int, rl_command_func_t *, Keymap)); extern int rl_unbind_key PARAMS((int)); extern int rl_unbind_key_in_map PARAMS((int, Keymap)); +extern int rl_bind_key_if_unbound PARAMS((int, rl_command_func_t *)); +extern int rl_bind_key_if_unbound_in_map PARAMS((int, rl_command_func_t *, Keymap)); extern int rl_unbind_function_in_map PARAMS((rl_command_func_t *, Keymap)); extern int rl_unbind_command_in_map PARAMS((const char *, Keymap)); -extern int rl_set_key PARAMS((const char *, rl_command_func_t *, Keymap)); +extern int rl_bind_keyseq PARAMS((const char *, rl_command_func_t *)); +extern int rl_bind_keyseq_in_map PARAMS((const char *, rl_command_func_t *, Keymap)); +extern int rl_bind_keyseq_if_unbound PARAMS((const char *, rl_command_func_t *)); +extern int rl_bind_keyseq_if_unbound_in_map PARAMS((const char *, rl_command_func_t *, Keymap)); extern int rl_generic_bind PARAMS((int, const char *, char *, Keymap)); + +extern char *rl_variable_value PARAMS((const char *)); extern int rl_variable_bind PARAMS((const char *, const char *)); +/* Backwards compatibility, use rl_bind_keyseq_in_map instead. */ +extern int rl_set_key PARAMS((const char *, rl_command_func_t *, Keymap)); + /* Backwards compatibility, use rl_generic_bind instead. */ extern int rl_macro_bind PARAMS((const char *, const char *, Keymap)); @@ -358,7 +372,7 @@ extern int rl_clear_message PARAMS((void)); extern int rl_reset_line_state PARAMS((void)); extern int rl_crlf PARAMS((void)); -#if (defined (__STDC__) || defined (__cplusplus)) && defined (USE_VARARGS) && defined (PREFER_STDARG) +#if defined (USE_VARARGS) && defined (PREFER_STDARG) extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2))); #else extern int rl_message (); @@ -384,11 +398,13 @@ extern char *rl_copy_text PARAMS((int, int)); extern void rl_prep_terminal PARAMS((int)); extern void rl_deprep_terminal PARAMS((void)); extern void rl_tty_set_default_bindings PARAMS((Keymap)); +extern void rl_tty_unset_default_bindings PARAMS((Keymap)); extern int rl_reset_terminal PARAMS((const char *)); extern void rl_resize_terminal PARAMS((void)); extern void rl_set_screen_size PARAMS((int, int)); extern void rl_get_screen_size PARAMS((int *, int *)); +extern void rl_reset_screen_size PARAMS((void)); extern char *rl_get_termcap PARAMS((const char *)); @@ -516,6 +532,11 @@ extern const char *rl_terminal_name; extern FILE *rl_instream; extern FILE *rl_outstream; +/* If non-zero, Readline gives values of LINES and COLUMNS from the environment + greater precedence than values fetched from the kernel when computing the + screen dimensions. */ +extern int rl_prefer_env_winsize; + /* If non-zero, then this is the address of a function to call just before readline_internal () prints the first prompt. */ extern rl_hook_func_t *rl_startup_hook; @@ -603,7 +624,12 @@ extern const char *rl_basic_word_break_characters; /* The list of characters that signal a break between words for rl_complete_internal. The default list is the contents of rl_basic_word_break_characters. */ -extern const char *rl_completer_word_break_characters; +extern /*const*/ char *rl_completer_word_break_characters; + +/* Hook function to allow an application to set the completion word + break characters before readline breaks up the line. Allows + position-dependent word break characters. */ +extern rl_cpvfunc_t *rl_completion_word_break_hook; /* List of characters which can be used to quote a substring of the line. Completion occurs on the entire substring, and within the substring @@ -687,6 +713,11 @@ extern int rl_attempted_completion_over; functions. */ extern int rl_completion_type; +/* Up to this many items will be displayed in response to a + possible-completions call. After that, we ask the user if she + is sure she wants to see them all. The default value is 100. */ +extern int rl_completion_query_items; + /* Character appended to completed words when at the end of the line. The default is a space. Nothing is added if this is '\0'. */ extern int rl_completion_append_character; @@ -695,10 +726,18 @@ extern int rl_completion_append_character; rl_completion_append_character will not be appended. */ extern int rl_completion_suppress_append; -/* Up to this many items will be displayed in response to a - possible-completions call. After that, we ask the user if she - is sure she wants to see them all. The default value is 100. */ -extern int rl_completion_query_items; +/* Set to any quote character readline thinks it finds before any application + completion function is called. */ +extern int rl_completion_quote_character; + +/* Set to a non-zero value if readline found quoting anywhere in the word to + be completed; set before any application completion function is called. */ +extern int rl_completion_found_quote; + +/* If non-zero, the completion functions don't append any closing quote. + This is set to 0 by rl_complete_internal and may be changed by an + application-specific completion function. */ +extern int rl_completion_suppress_quote; /* If non-zero, a slash will be appended to completed filenames that are symbolic links to directory names, subject to the value of the @@ -729,28 +768,33 @@ extern int rl_inhibit_completion; #define MULT_MATCH 2 /* Possible state values for rl_readline_state */ -#define RL_STATE_NONE 0x00000 /* no state; before first call */ - -#define RL_STATE_INITIALIZING 0x00001 /* initializing */ -#define RL_STATE_INITIALIZED 0x00002 /* initialization done */ -#define RL_STATE_TERMPREPPED 0x00004 /* terminal is prepped */ -#define RL_STATE_READCMD 0x00008 /* reading a command key */ -#define RL_STATE_METANEXT 0x00010 /* reading input after ESC */ -#define RL_STATE_DISPATCHING 0x00020 /* dispatching to a command */ -#define RL_STATE_MOREINPUT 0x00040 /* reading more input in a command function */ -#define RL_STATE_ISEARCH 0x00080 /* doing incremental search */ -#define RL_STATE_NSEARCH 0x00100 /* doing non-inc search */ -#define RL_STATE_SEARCH 0x00200 /* doing a history search */ -#define RL_STATE_NUMERICARG 0x00400 /* reading numeric argument */ -#define RL_STATE_MACROINPUT 0x00800 /* getting input from a macro */ -#define RL_STATE_MACRODEF 0x01000 /* defining keyboard macro */ -#define RL_STATE_OVERWRITE 0x02000 /* overwrite mode */ -#define RL_STATE_COMPLETING 0x04000 /* doing completion */ -#define RL_STATE_SIGHANDLER 0x08000 /* in readline sighandler */ -#define RL_STATE_UNDOING 0x10000 /* doing an undo */ -#define RL_STATE_INPUTPENDING 0x20000 /* rl_execute_next called */ - -#define RL_STATE_DONE 0x80000 /* done; accepted line */ +#define RL_STATE_NONE 0x000000 /* no state; before first call */ + +#define RL_STATE_INITIALIZING 0x000001 /* initializing */ +#define RL_STATE_INITIALIZED 0x000002 /* initialization done */ +#define RL_STATE_TERMPREPPED 0x000004 /* terminal is prepped */ +#define RL_STATE_READCMD 0x000008 /* reading a command key */ +#define RL_STATE_METANEXT 0x000010 /* reading input after ESC */ +#define RL_STATE_DISPATCHING 0x000020 /* dispatching to a command */ +#define RL_STATE_MOREINPUT 0x000040 /* reading more input in a command function */ +#define RL_STATE_ISEARCH 0x000080 /* doing incremental search */ +#define RL_STATE_NSEARCH 0x000100 /* doing non-inc search */ +#define RL_STATE_SEARCH 0x000200 /* doing a history search */ +#define RL_STATE_NUMERICARG 0x000400 /* reading numeric argument */ +#define RL_STATE_MACROINPUT 0x000800 /* getting input from a macro */ +#define RL_STATE_MACRODEF 0x001000 /* defining keyboard macro */ +#define RL_STATE_OVERWRITE 0x002000 /* overwrite mode */ +#define RL_STATE_COMPLETING 0x004000 /* doing completion */ +#define RL_STATE_SIGHANDLER 0x008000 /* in readline sighandler */ +#define RL_STATE_UNDOING 0x010000 /* doing an undo */ +#define RL_STATE_INPUTPENDING 0x020000 /* rl_execute_next called */ +#define RL_STATE_TTYCSAVED 0x040000 /* tty special chars saved */ +#define RL_STATE_CALLBACK 0x080000 /* using the callback interface */ +#define RL_STATE_VIMOTION 0x100000 /* reading vi motion arg */ +#define RL_STATE_MULTIKEY 0x200000 /* reading multiple-key command */ +#define RL_STATE_VICMDONCE 0x400000 /* entered vi command mode at least once */ + +#define RL_STATE_DONE 0x800000 /* done; accepted line */ #define RL_SETSTATE(x) (rl_readline_state |= (x)) #define RL_UNSETSTATE(x) (rl_readline_state &= ~(x)) @@ -785,6 +829,12 @@ struct readline_state { int catchsigs; int catchsigwinch; + /* search state */ + + /* completion state */ + + /* options state */ + /* reserved for future expansion, so the struct size doesn't change */ char reserved[64]; }; diff --git a/readline/rldefs.h b/readline/rldefs.h index b80db8c..0f6c874 100644 --- a/readline/rldefs.h +++ b/readline/rldefs.h @@ -2,7 +2,7 @@ for readline. This should be included after any files that define system-specific constants like _POSIX_VERSION or USG. */ -/* Copyright (C) 1987,1989 Free Software Foundation, Inc. +/* Copyright (C) 1987-2005 Free Software Foundation, Inc. This file contains the Readline Library (the Library), a set of routines for providing Emacs style line input to programs that ask @@ -32,15 +32,17 @@ #include "rlstdc.h" -#if defined (__MINGW32__) -# define NO_TTY_DRIVER -#elif defined (_POSIX_VERSION) && !defined (TERMIOS_MISSING) +#if defined (_POSIX_VERSION) && !defined (TERMIOS_MISSING) # define TERMIOS_TTY_DRIVER #else # if defined (HAVE_TERMIO_H) # define TERMIO_TTY_DRIVER # else -# define NEW_TTY_DRIVER +# if !defined (__MINGW32__) +# define NEW_TTY_DRIVER +# else +# define NO_TTY_DRIVER +# endif # endif #endif @@ -79,7 +81,7 @@ extern int _rl_stricmp PARAMS((char *, char *)); extern int _rl_strnicmp PARAMS((char *, char *, int)); #endif -#if defined (HAVE_STRPBRK) +#if defined (HAVE_STRPBRK) && !defined (HAVE_MULTIBYTE) # define _rl_strpbrk(a,b) strpbrk((a),(b)) #else extern char *_rl_strpbrk PARAMS((const char *, const char *)); diff --git a/readline/rlmbutil.h b/readline/rlmbutil.h index dab954f..cf6ef9e 100644 --- a/readline/rlmbutil.h +++ b/readline/rlmbutil.h @@ -45,12 +45,28 @@ #if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H) # include <wchar.h> # include <wctype.h> -# if defined (HAVE_MBSTATE_T) && defined (HAVE_MBSRTOWCS) +# if defined (HAVE_MBSTATE_T) && defined (HAVE_MBSRTOWCS) && defined (HAVE_MBRTOWC) && defined (HAVE_MBRLEN) && defined (HAVE_WCWIDTH) /* system is supposed to support XPG5 */ # define HANDLE_MULTIBYTE 1 # endif #endif +/* If we don't want multibyte chars even on a system that supports them, let + the configuring user turn multibyte support off. */ +#if defined (NO_MULTIBYTE_SUPPORT) +# undef HANDLE_MULTIBYTE +#endif + +/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ +#if HANDLE_MULTIBYTE && !defined (HAVE_MBSTATE_T) +# define wcsrtombs(dest, src, len, ps) (wcsrtombs) (dest, src, len, 0) +# define mbsrtowcs(dest, src, len, ps) (mbsrtowcs) (dest, src, len, 0) +# define wcrtomb(s, wc, ps) (wcrtomb) (s, wc, 0) +# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) +# define mbrlen(s, n, ps) (mbrlen) (s, n, 0) +# define mbstate_t int +#endif + /* Make sure MB_LEN_MAX is at least 16 on systems that claim to be able to handle multibyte chars (some systems define MB_LEN_MAX as 1) */ #ifdef HANDLE_MULTIBYTE @@ -91,6 +107,24 @@ extern int _rl_read_mbstring PARAMS((int, char *, int)); extern int _rl_is_mbchar_matched PARAMS((char *, int, int, char *, int)); +extern wchar_t _rl_char_value PARAMS((char *, int)); +extern int _rl_walphabetic PARAMS((wchar_t)); + +#define _rl_to_wupper(wc) (iswlower (wc) ? towupper (wc) : (wc)) +#define _rl_to_wlower(wc) (iswupper (wc) ? towlower (wc) : (wc)) + +#define MB_NEXTCHAR(b,s,c,f) \ + ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) \ + ? _rl_find_next_mbchar ((b), (s), (c), (f)) \ + : ((s) + (c))) +#define MB_PREVCHAR(b,s,f) \ + ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) \ + ? _rl_find_prev_mbchar ((b), (s), (f)) \ + : ((s) - 1)) + +#define MB_INVALIDCH(x) ((x) == (size_t)-1 || (x) == (size_t)-2) +#define MB_NULLWCH(x) ((x) == 0) + #else /* !HANDLE_MULTIBYTE */ #undef MB_LEN_MAX @@ -102,6 +136,19 @@ extern int _rl_is_mbchar_matched PARAMS((char *, int, int, char *, int)); #define _rl_find_prev_mbchar(b, i, f) (((i) == 0) ? (i) : ((i) - 1)) #define _rl_find_next_mbchar(b, i1, i2, f) ((i1) + (i2)) +#define _rl_char_value(buf,ind) ((buf)[(ind)]) + +#define _rl_walphabetic(c) (rl_alphabetic (c)) + +#define _rl_to_wupper(c) (_rl_to_upper (c)) +#define _rl_to_wlower(c) (_rl_to_lower (c)) + +#define MB_NEXTCHAR(b,s,c,f) ((s) + (c)) +#define MB_PREVCHAR(b,s,f) ((s) - 1) + +#define MB_INVALIDCH(x) (0) +#define MB_NULLWCH(x) (0) + #endif /* !HANDLE_MULTIBYTE */ extern int rl_byte_oriented; diff --git a/readline/rlprivate.h b/readline/rlprivate.h index ccb9144..1c216ea 100644 --- a/readline/rlprivate.h +++ b/readline/rlprivate.h @@ -1,7 +1,7 @@ /* rlprivate.h -- functions and variables global to the readline library, but not intended for use by applications. */ -/* Copyright (C) 1999 Free Software Foundation, Inc. +/* Copyright (C) 1999-2005 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -30,6 +30,95 @@ /************************************************************************* * * + * Global structs undocumented in texinfo manual and not in readline.h * + * * + *************************************************************************/ +/* search types */ +#define RL_SEARCH_ISEARCH 0x01 /* incremental search */ +#define RL_SEARCH_NSEARCH 0x02 /* non-incremental search */ +#define RL_SEARCH_CSEARCH 0x04 /* intra-line char search */ + +/* search flags */ +#define SF_REVERSE 0x01 +#define SF_FOUND 0x02 +#define SF_FAILED 0x04 + +typedef struct __rl_search_context +{ + int type; + int sflags; + + char *search_string; + int search_string_index; + int search_string_size; + + char **lines; + char *allocated_line; + int hlen; + int hindex; + + int save_point; + int save_mark; + int save_line; + int last_found_line; + char *prev_line_found; + + UNDO_LIST *save_undo_list; + + int history_pos; + int direction; + + int lastc; +#if defined (HANDLE_MULTIBYTE) + char mb[MB_LEN_MAX]; +#endif + + char *sline; + int sline_len; + int sline_index; + + char *search_terminators; +} _rl_search_cxt; + +/* Callback data for reading numeric arguments */ +#define NUM_SAWMINUS 0x01 +#define NUM_SAWDIGITS 0x02 +#define NUM_READONE 0x04 + +typedef int _rl_arg_cxt; + +/* A context for reading key sequences longer than a single character when + using the callback interface. */ +#define KSEQ_DISPATCHED 0x01 +#define KSEQ_SUBSEQ 0x02 +#define KSEQ_RECURSIVE 0x04 + +typedef struct __rl_keyseq_context +{ + int flags; + int subseq_arg; + int subseq_retval; /* XXX */ + Keymap dmap; + + Keymap oldmap; + int okey; + struct __rl_keyseq_context *ocxt; + int childval; +} _rl_keyseq_cxt; + + /* fill in more as needed */ +/* `Generic' callback data and functions */ +typedef struct __rl_callback_generic_arg +{ + int count; + int i1, i2; + /* add here as needed */ +} _rl_callback_generic_arg; + +typedef int _rl_callback_func_t PARAMS((_rl_callback_generic_arg *)); + +/************************************************************************* + * * * Global functions undocumented in texinfo manual and not in readline.h * * * *************************************************************************/ @@ -54,6 +143,8 @@ extern int readline_echoing_p; extern int rl_key_sequence_length; extern int rl_byte_oriented; +extern _rl_keyseq_cxt *_rl_kscxt; + /* display.c */ extern int rl_display_fixed; @@ -100,10 +191,19 @@ extern void readline_internal_setup PARAMS((void)); extern char *readline_internal_teardown PARAMS((int)); extern int readline_internal_char PARAMS((void)); +extern _rl_keyseq_cxt *_rl_keyseq_cxt_alloc PARAMS((void)); +extern void _rl_keyseq_cxt_dispose PARAMS((_rl_keyseq_cxt *)); +extern void _rl_keyseq_chain_dispose PARAMS((void)); + +extern int _rl_dispatch_callback PARAMS((_rl_keyseq_cxt *)); + +/* callback.c */ +extern _rl_callback_generic_arg *_rl_callback_data_alloc PARAMS((int)); +extern void _rl_callback_data_dispose PARAMS((_rl_callback_generic_arg *)); + #endif /* READLINE_CALLBACKS */ /* bind.c */ -extern void _rl_bind_if_unbound PARAMS((const char *, rl_command_func_t *)); /* complete.c */ extern char _rl_find_completion_word PARAMS((int *, int *)); @@ -131,6 +231,16 @@ extern int _rl_input_available PARAMS((void)); extern int _rl_input_queued PARAMS((int)); extern void _rl_insert_typein PARAMS((int)); extern int _rl_unget_char PARAMS((int)); +extern int _rl_pushed_input_available PARAMS((void)); + +/* isearch.c */ +extern _rl_search_cxt *_rl_scxt_alloc PARAMS((int, int)); +extern void _rl_scxt_dispose PARAMS((_rl_search_cxt *, int)); + +extern int _rl_isearch_dispatch PARAMS((_rl_search_cxt *, int)); +extern int _rl_isearch_callback PARAMS((_rl_search_cxt *)); + +extern int _rl_search_getchar PARAMS((_rl_search_cxt *)); /* macro.c */ extern void _rl_with_macro_input PARAMS((char *)); @@ -141,7 +251,12 @@ extern void _rl_add_macro_char PARAMS((int)); extern void _rl_kill_kbd_macro PARAMS((void)); /* misc.c */ -extern int _rl_init_argument PARAMS((void)); +extern int _rl_arg_overflow PARAMS((void)); +extern void _rl_arg_init PARAMS((void)); +extern int _rl_arg_getchar PARAMS((void)); +extern int _rl_arg_callback PARAMS((_rl_arg_cxt)); +extern void _rl_reset_argument PARAMS((void)); + extern void _rl_start_using_history PARAMS((void)); extern int _rl_free_saved_history_line PARAMS((void)); extern void _rl_set_insert_mode PARAMS((int, int)); @@ -157,11 +272,15 @@ extern void _rl_init_line_state PARAMS((void)); extern void _rl_set_the_line PARAMS((void)); extern int _rl_dispatch PARAMS((int, Keymap)); extern int _rl_dispatch_subseq PARAMS((int, Keymap, int)); +extern void _rl_internal_char_cleanup PARAMS((void)); /* rltty.c */ extern int _rl_disable_tty_signals PARAMS((void)); extern int _rl_restore_tty_signals PARAMS((void)); +/* search.c */ +extern int _rl_nsearch_callback PARAMS((_rl_search_cxt *)); + /* terminal.c */ extern void _rl_get_screen_size PARAMS((int, int)); extern int _rl_init_terminal_io PARAMS((const char *)); @@ -217,8 +336,13 @@ extern void _rl_vi_done_inserting PARAMS((void)); extern const char *_rl_possible_control_prefixes[]; extern const char *_rl_possible_meta_prefixes[]; +/* callback.c */ +extern _rl_callback_func_t *_rl_callback_func; +extern _rl_callback_generic_arg *_rl_callback_data; + /* complete.c */ extern int _rl_complete_show_all; +extern int _rl_complete_show_unmodified; extern int _rl_complete_mark_directories; extern int _rl_complete_mark_symlink_dirs; extern int _rl_print_completions_horizontally; @@ -230,11 +354,14 @@ extern int _rl_page_completions; extern int _rl_vis_botlin; extern int _rl_last_c_pos; extern int _rl_suppress_redisplay; +extern int _rl_want_redisplay; extern char *rl_display_prompt; /* isearch.c */ extern char *_rl_isearch_terminators; +extern _rl_search_cxt *_rl_iscxt; + /* macro.c */ extern char *_rl_executing_macro; @@ -242,6 +369,8 @@ extern char *_rl_executing_macro; extern int _rl_history_preserve_point; extern int _rl_history_saved_point; +extern _rl_arg_cxt _rl_argcxt; + /* readline.c */ extern int _rl_horizontal_scroll_mode; extern int _rl_mark_modified_lines; @@ -249,6 +378,7 @@ extern int _rl_bell_preference; extern int _rl_meta_flag; extern int _rl_convert_meta_chars_to_ascii; extern int _rl_output_meta_chars; +extern int _rl_bind_stty_chars; extern char *_rl_comment_begin; extern unsigned char _rl_parsing_conditionalized_out; extern Keymap _rl_keymap; @@ -258,6 +388,9 @@ extern int _rl_last_command_was_kill; extern int _rl_eof_char; extern procenv_t readline_top_level; +/* search.c */ +extern _rl_search_cxt *_rl_nscxt; + /* terminal.c */ extern int _rl_enable_keypad; extern int _rl_enable_meta; @@ -281,4 +414,7 @@ extern int _rl_term_autowrap; extern int _rl_doing_an_undo; extern int _rl_undo_group_level; +/* vi_mode.c */ +extern int _rl_vi_last_command; + #endif /* _RL_PRIVATE_H_ */ diff --git a/readline/rlstdc.h b/readline/rlstdc.h index d6a22b3..847fa9c 100644 --- a/readline/rlstdc.h +++ b/readline/rlstdc.h @@ -37,7 +37,7 @@ #endif #ifndef __attribute__ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) # define __attribute__(x) # endif #endif diff --git a/readline/rltty.c b/readline/rltty.c index 2ccb9d1..9a0326e 100644 --- a/readline/rltty.c +++ b/readline/rltty.c @@ -1,7 +1,7 @@ /* rltty.c -- functions to prepare and restore the terminal for readline's use. */ -/* Copyright (C) 1992 Free Software Foundation, Inc. +/* Copyright (C) 1992-2005 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -188,6 +188,8 @@ static int set_tty_settings PARAMS((int, TIOTYPE *)); static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *)); +static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t)); + static void save_tty_chars (tiop) TIOTYPE *tiop; @@ -229,12 +231,11 @@ get_tty_settings (tty, tiop) int tty; TIOTYPE *tiop; { -#if defined (TIOCGWINSZ) set_winsize (tty); -#endif tiop->flags = tiop->lflag = 0; + errno = 0; if (ioctl (tty, TIOCGETP, &(tiop->sgttyb)) < 0) return -1; tiop->flags |= SGTTY_SET; @@ -404,6 +405,9 @@ static int set_tty_settings PARAMS((int, TIOTYPE *)); static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *)); +static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t)); +static void _rl_bind_tty_special_chars PARAMS((Keymap, TIOTYPE)); + #if defined (FLUSHO) # define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO) #else @@ -515,10 +519,9 @@ get_tty_settings (tty, tiop) int tty; TIOTYPE *tiop; { -#if defined (TIOCGWINSZ) set_winsize (tty); -#endif + errno = 0; if (_get_tty_settings (tty, tiop) < 0) return -1; @@ -632,10 +635,9 @@ prepare_terminal_settings (meta_flag, oldtio, tiop) #endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */ } -#endif /* NEW_TTY_DRIVER */ +#endif /* !NEW_TTY_DRIVER */ -/* Put the terminal in CBREAK mode so that we can detect key - presses. */ +/* Put the terminal in CBREAK mode so that we can detect key presses. */ #if defined (NO_TTY_DRIVER) void rl_prep_terminal (meta_flag) @@ -650,7 +652,6 @@ rl_deprep_terminal () } #else /* ! NO_TTY_DRIVER */ -/* Put the terminal in CBREAK mode so that we can detect key presses. */ void rl_prep_terminal (meta_flag) int meta_flag; @@ -668,13 +669,43 @@ rl_prep_terminal (meta_flag) if (get_tty_settings (tty, &tio) < 0) { +#if defined (ENOTSUP) + /* MacOS X, at least, lies about the value of errno if tcgetattr fails. */ + if (errno == ENOTTY || errno == ENOTSUP) +#else + if (errno == ENOTTY) +#endif + readline_echoing_p = 1; /* XXX */ release_sigint (); return; } otio = tio; + if (_rl_bind_stty_chars) + { +#if defined (VI_MODE) + /* If editing in vi mode, make sure we restore the bindings in the + insertion keymap no matter what keymap we ended up in. */ + if (rl_editing_mode == vi_mode) + rl_tty_unset_default_bindings (vi_insertion_keymap); + else +#endif + rl_tty_unset_default_bindings (_rl_keymap); + } save_tty_chars (&otio); + RL_SETSTATE(RL_STATE_TTYCSAVED); + if (_rl_bind_stty_chars) + { +#if defined (VI_MODE) + /* If editing in vi mode, make sure we set the bindings in the + insertion keymap no matter what keymap we ended up in. */ + if (rl_editing_mode == vi_mode) + _rl_bind_tty_special_chars (vi_insertion_keymap, tio); + else +#endif + _rl_bind_tty_special_chars (_rl_keymap, tio); + } prepare_terminal_settings (meta_flag, otio, &tio); @@ -809,71 +840,105 @@ rl_stop_output (count, key) /* */ /* **************************************************************** */ -/* Set the system's default editing characters to their readline equivalents - in KMAP. Should be static, now that we have rl_tty_set_default_bindings. */ -void -rltty_set_default_bindings (kmap) - Keymap kmap; -{ #if !defined (NO_TTY_DRIVER) - TIOTYPE ttybuff; - int tty = fileno (rl_instream); +#define SET_SPECIAL(sc, func) set_special_char(kmap, &ttybuff, sc, func) +#endif -#if defined (NEW_TTY_DRIVER) +#if defined (NO_TTY_DRIVER) -#define SET_SPECIAL(sc, func) \ - do \ - { \ - int ic; \ - ic = sc; \ - if (ic != -1 && kmap[(unsigned char)ic].type == ISFUNC) \ - kmap[(unsigned char)ic].function = func; \ - } \ - while (0) +#define SET_SPECIAL(sc, func) +#define RESET_SPECIAL(c) - if (get_tty_settings (tty, &ttybuff) == 0) +#elif defined (NEW_TTY_DRIVER) +static void +set_special_char (kmap, tiop, sc, func) + Keymap kmap; + TIOTYPE *tiop; + int sc; + rl_command_func_t *func; +{ + if (sc != -1 && kmap[(unsigned char)sc].type == ISFUNC) + kmap[(unsigned char)sc].function = func; +} + +#define RESET_SPECIAL(c) \ + if (c != -1 && kmap[(unsigned char)c].type == ISFUNC) + kmap[(unsigned char)c].function = rl_insert; + +static void +_rl_bind_tty_special_chars (kmap, ttybuff) + Keymap kmap; + TIOTYPE ttybuff; +{ + if (ttybuff.flags & SGTTY_SET) { - if (ttybuff.flags & SGTTY_SET) - { - SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout); - SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard); - } + SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout); + SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard); + } # if defined (TIOCGLTC) - if (ttybuff.flags & LTCHARS_SET) - { - SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout); - SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert); - } -# endif /* TIOCGLTC */ + if (ttybuff.flags & LTCHARS_SET) + { + SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout); + SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert); } +# endif /* TIOCGLTC */ +} #else /* !NEW_TTY_DRIVER */ +static void +set_special_char (kmap, tiop, sc, func) + Keymap kmap; + TIOTYPE *tiop; + int sc; + rl_command_func_t *func; +{ + unsigned char uc; -#define SET_SPECIAL(sc, func) \ - do \ - { \ - unsigned char uc; \ - uc = ttybuff.c_cc[sc]; \ - if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \ - kmap[uc].function = func; \ - } \ - while (0) + uc = tiop->c_cc[sc]; + if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) + kmap[uc].function = func; +} - if (get_tty_settings (tty, &ttybuff) == 0) - { - SET_SPECIAL (VERASE, rl_rubout); - SET_SPECIAL (VKILL, rl_unix_line_discard); +/* used later */ +#define RESET_SPECIAL(uc) \ + if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \ + kmap[uc].function = rl_insert; + +static void +_rl_bind_tty_special_chars (kmap, ttybuff) + Keymap kmap; + TIOTYPE ttybuff; +{ + SET_SPECIAL (VERASE, rl_rubout); + SET_SPECIAL (VKILL, rl_unix_line_discard); # if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER) - SET_SPECIAL (VLNEXT, rl_quoted_insert); + SET_SPECIAL (VLNEXT, rl_quoted_insert); # endif /* VLNEXT && TERMIOS_TTY_DRIVER */ # if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER) - SET_SPECIAL (VWERASE, rl_unix_word_rubout); + SET_SPECIAL (VWERASE, rl_unix_word_rubout); # endif /* VWERASE && TERMIOS_TTY_DRIVER */ - } +} + #endif /* !NEW_TTY_DRIVER */ + +/* Set the system's default editing characters to their readline equivalents + in KMAP. Should be static, now that we have rl_tty_set_default_bindings. */ +void +rltty_set_default_bindings (kmap) + Keymap kmap; +{ +#if !defined (NO_TTY_DRIVER) + TIOTYPE ttybuff; + int tty; + static int called = 0; + + tty = fileno (rl_instream); + + if (get_tty_settings (tty, &ttybuff) == 0) + _rl_bind_tty_special_chars (kmap, ttybuff); #endif } @@ -886,6 +951,30 @@ rl_tty_set_default_bindings (kmap) rltty_set_default_bindings (kmap); } +/* Rebind all of the tty special chars that readline worries about back + to self-insert. Call this before saving the current terminal special + chars with save_tty_chars(). This only works on POSIX termios or termio + systems. */ +void +rl_tty_unset_default_bindings (kmap) + Keymap kmap; +{ + /* Don't bother before we've saved the tty special chars at least once. */ + if (RL_ISSTATE(RL_STATE_TTYCSAVED) == 0) + return; + + RESET_SPECIAL (_rl_tty_chars.t_erase); + RESET_SPECIAL (_rl_tty_chars.t_kill); + +# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER) + RESET_SPECIAL (_rl_tty_chars.t_lnext); +# endif /* VLNEXT && TERMIOS_TTY_DRIVER */ + +# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER) + RESET_SPECIAL (_rl_tty_chars.t_werase); +# endif /* VWERASE && TERMIOS_TTY_DRIVER */ +} + #if defined (HANDLE_SIGNALS) #if defined (NEW_TTY_DRIVER) || defined (NO_TTY_DRIVER) diff --git a/readline/rltty.h b/readline/rltty.h index 029a3fb..142e96b 100644 --- a/readline/rltty.h +++ b/readline/rltty.h @@ -61,22 +61,22 @@ #endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */ typedef struct _rl_tty_chars { - char t_eof; - char t_eol; - char t_eol2; - char t_erase; - char t_werase; - char t_kill; - char t_reprint; - char t_intr; - char t_quit; - char t_susp; - char t_dsusp; - char t_start; - char t_stop; - char t_lnext; - char t_flush; - char t_status; + unsigned char t_eof; + unsigned char t_eol; + unsigned char t_eol2; + unsigned char t_erase; + unsigned char t_werase; + unsigned char t_kill; + unsigned char t_reprint; + unsigned char t_intr; + unsigned char t_quit; + unsigned char t_susp; + unsigned char t_dsusp; + unsigned char t_start; + unsigned char t_stop; + unsigned char t_lnext; + unsigned char t_flush; + unsigned char t_status; } _RL_TTY_CHARS; #endif /* _RLTTY_H_ */ diff --git a/readline/rltypedefs.h b/readline/rltypedefs.h index f3280e9..862bdb8 100644 --- a/readline/rltypedefs.h +++ b/readline/rltypedefs.h @@ -1,6 +1,6 @@ /* rltypedefs.h -- Type declarations for readline functions. */ -/* Copyright (C) 2000 Free Software Foundation, Inc. +/* Copyright (C) 2000-2004 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -79,6 +79,12 @@ typedef void rl_voidfunc_t PARAMS((void)); typedef void rl_vintfunc_t PARAMS((int)); typedef void rl_vcpfunc_t PARAMS((char *)); typedef void rl_vcppfunc_t PARAMS((char **)); + +typedef char *rl_cpvfunc_t PARAMS((void)); +typedef char *rl_cpifunc_t PARAMS((int)); +typedef char *rl_cpcpfunc_t PARAMS((char *)); +typedef char *rl_cpcppfunc_t PARAMS((char **)); + #endif /* _RL_FUNCTION_TYPEDEF */ #ifdef __cplusplus diff --git a/readline/savestring.c b/readline/savestring.c index c7ebeb1..820428d 100644 --- a/readline/savestring.c +++ b/readline/savestring.c @@ -1,6 +1,6 @@ /* savestring.c */ -/* Copyright (C) 1998 Free Software Foundation, Inc. +/* Copyright (C) 1998,2003 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -19,6 +19,7 @@ is generally kept in a file called COPYING or LICENSE. If you do not have a copy of the license, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ +#define READLINE_LIBRARY #include <config.h> #ifdef HAVE_STRING_H diff --git a/readline/search.c b/readline/search.c index 7e0d60b..8013916 100644 --- a/readline/search.c +++ b/readline/search.c @@ -1,6 +1,6 @@ /* search.c - code for non-incremental searching in emacs and vi modes. */ -/* Copyright (C) 1992 Free Software Foundation, Inc. +/* Copyright (C) 1992-2005 Free Software Foundation, Inc. This file is part of the Readline Library (the Library), a set of routines for providing Emacs style line input to programs that ask @@ -53,6 +53,8 @@ #endif #define abs(x) (((x) >= 0) ? (x) : -(x)) +_rl_search_cxt *_rl_nscxt = 0; + extern HIST_ENTRY *_rl_saved_line_for_history; /* Functions imported from the rest of the library. */ @@ -68,13 +70,19 @@ static int rl_history_search_pos; static char *history_search_string; static int history_string_size; +static UNDO_LIST *noninc_saved_undo_list; static void make_history_line_current PARAMS((HIST_ENTRY *)); static int noninc_search_from_pos PARAMS((char *, int, int)); -static void noninc_dosearch PARAMS((char *, int)); -static void noninc_search PARAMS((int, int)); +static int noninc_dosearch PARAMS((char *, int)); +static int noninc_search PARAMS((int, int)); static int rl_history_search_internal PARAMS((int, int)); static void rl_history_search_reinit PARAMS((void)); +static _rl_search_cxt *_rl_nsearch_init PARAMS((int, int)); +static int _rl_nsearch_cleanup PARAMS((_rl_search_cxt *, int)); +static void _rl_nsearch_abort PARAMS((_rl_search_cxt *)); +static int _rl_nsearch_dispatch PARAMS((_rl_search_cxt *, int)); + /* Make the data from the history entry ENTRY be the contents of the current line. This doesn't do anything with rl_point; the caller must set it. */ @@ -82,8 +90,16 @@ static void make_history_line_current (entry) HIST_ENTRY *entry; { - rl_replace_line (entry->line, 0); - rl_undo_list = (UNDO_LIST *)entry->data; + _rl_replace_text (entry->line, 0, rl_end); + _rl_fix_point (1); +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode) + /* POSIX.2 says that the `U' command doesn't affect the copy of any + command lines to the edit line. We're going to implement that by + making the undo list start after the matching line is copied to the + current editing buffer. */ + rl_free_undo_list (); +#endif if (_rl_saved_line_for_history) _rl_free_history_entry (_rl_saved_line_for_history); @@ -125,8 +141,8 @@ noninc_search_from_pos (string, pos, dir) /* Search for a line in the history containing STRING. If DIR is < 0, the search is backwards through previous entries, else through subsequent - entries. */ -static void + entries. Returns 1 if the search was successful, 0 otherwise. */ +static int noninc_dosearch (string, dir) char *string; int dir; @@ -137,7 +153,7 @@ noninc_dosearch (string, dir) if (string == 0 || *string == '\0' || noninc_history_pos < 0) { rl_ding (); - return; + return 0; } pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir); @@ -148,7 +164,7 @@ noninc_dosearch (string, dir) rl_clear_message (); rl_point = 0; rl_ding (); - return; + return 0; } noninc_history_pos = pos; @@ -159,7 +175,7 @@ noninc_dosearch (string, dir) #if defined (VI_MODE) if (rl_editing_mode != vi_mode) #endif - history_set_pos (oldpos); + history_set_pos (oldpos); make_history_line_current (entry); @@ -167,27 +183,29 @@ noninc_dosearch (string, dir) rl_mark = rl_end; rl_clear_message (); + return 1; } -/* Search non-interactively through the history list. DIR < 0 means to - search backwards through the history of previous commands; otherwise - the search is for commands subsequent to the current position in the - history list. PCHAR is the character to use for prompting when reading - the search string; if not specified (0), it defaults to `:'. */ -static void -noninc_search (dir, pchar) - int dir; - int pchar; +static _rl_search_cxt * +_rl_nsearch_init (dir, pchar) + int dir, pchar; { - int saved_point, saved_mark, c; + _rl_search_cxt *cxt; char *p; -#if defined (HANDLE_MULTIBYTE) - char mb[MB_LEN_MAX]; -#endif + + cxt = _rl_scxt_alloc (RL_SEARCH_NSEARCH, 0); + if (dir < 0) + cxt->sflags |= SF_REVERSE; /* not strictly needed */ + + cxt->direction = dir; + cxt->history_pos = cxt->save_line; rl_maybe_save_line (); - saved_point = rl_point; - saved_mark = rl_mark; + + /* Clear the undo list, since reading the search string should create its + own undo list, and the whole list will end up being freed when we + finish reading the search string. */ + rl_undo_list = 0; /* Use the line buffer to read the search string. */ rl_line_buffer[0] = 0; @@ -197,99 +215,169 @@ noninc_search (dir, pchar) rl_message (p, 0, 0); free (p); -#define SEARCH_RETURN rl_restore_prompt (); RL_UNSETSTATE(RL_STATE_NSEARCH); return - RL_SETSTATE(RL_STATE_NSEARCH); - /* Read the search string. */ - while (1) + + _rl_nscxt = cxt; + + return cxt; +} + +static int +_rl_nsearch_cleanup (cxt, r) + _rl_search_cxt *cxt; + int r; +{ + _rl_scxt_dispose (cxt, 0); + _rl_nscxt = 0; + + RL_UNSETSTATE(RL_STATE_NSEARCH); + + return (r != 1); +} + +static void +_rl_nsearch_abort (cxt) + _rl_search_cxt *cxt; +{ + rl_maybe_unsave_line (); + rl_clear_message (); + rl_point = cxt->save_point; + rl_mark = cxt->save_mark; + rl_restore_prompt (); + + RL_UNSETSTATE (RL_STATE_NSEARCH); +} + +/* Process just-read character C according to search context CXT. Return -1 + if the caller should abort the search, 0 if we should break out of the + loop, and 1 if we should continue to read characters. */ +static int +_rl_nsearch_dispatch (cxt, c) + _rl_search_cxt *cxt; + int c; +{ + switch (c) { - RL_SETSTATE(RL_STATE_MOREINPUT); - c = rl_read_key (); - RL_UNSETSTATE(RL_STATE_MOREINPUT); + case CTRL('W'): + rl_unix_word_rubout (1, c); + break; -#if defined (HANDLE_MULTIBYTE) - if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - c = _rl_read_mbstring (c, mb, MB_LEN_MAX); -#endif + case CTRL('U'): + rl_unix_line_discard (1, c); + break; - if (c == 0) - break; + case RETURN: + case NEWLINE: + return 0; - switch (c) + case CTRL('H'): + case RUBOUT: + if (rl_point == 0) { - case CTRL('H'): - case RUBOUT: - if (rl_point == 0) - { - rl_maybe_unsave_line (); - rl_clear_message (); - rl_point = saved_point; - rl_mark = saved_mark; - SEARCH_RETURN; - } - _rl_rubout_char (1, c); - break; - - case CTRL('W'): - rl_unix_word_rubout (1, c); - break; - - case CTRL('U'): - rl_unix_line_discard (1, c); - break; - - case RETURN: - case NEWLINE: - goto dosearch; - /* NOTREACHED */ - break; - - case CTRL('C'): - case CTRL('G'): - rl_maybe_unsave_line (); - rl_clear_message (); - rl_point = saved_point; - rl_mark = saved_mark; - rl_ding (); - SEARCH_RETURN; + _rl_nsearch_abort (cxt); + return -1; + } + _rl_rubout_char (1, c); + break; + + case CTRL('C'): + case CTRL('G'): + rl_ding (); + _rl_nsearch_abort (cxt); + return -1; - default: + default: #if defined (HANDLE_MULTIBYTE) - if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - rl_insert_text (mb); - else + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + rl_insert_text (cxt->mb); + else #endif - _rl_insert_char (1, c); - break; - } - (*rl_redisplay_function) (); + _rl_insert_char (1, c); + break; } - dosearch: - rl_mark = saved_mark; + (*rl_redisplay_function) (); + return 1; +} + +/* Perform one search according to CXT, using NONINC_SEARCH_STRING. Return + -1 if the search should be aborted, any other value means to clean up + using _rl_nsearch_cleanup (). Returns 1 if the search was successful, + 0 otherwise. */ +static int +_rl_nsearch_dosearch (cxt) + _rl_search_cxt *cxt; +{ + rl_mark = cxt->save_mark; /* If rl_point == 0, we want to re-use the previous search string and start from the saved history position. If there's no previous search string, punt. */ if (rl_point == 0) { - if (!noninc_search_string) + if (noninc_search_string == 0) { rl_ding (); - SEARCH_RETURN; + rl_restore_prompt (); + RL_UNSETSTATE (RL_STATE_NSEARCH); + return -1; } } else { /* We want to start the search from the current history position. */ - noninc_history_pos = where_history (); + noninc_history_pos = cxt->save_line; FREE (noninc_search_string); noninc_search_string = savestring (rl_line_buffer); + + /* If we don't want the subsequent undo list generated by the search + matching a history line to include the contents of the search string, + we need to clear rl_line_buffer here. For now, we just clear the + undo list generated by reading the search string. (If the search + fails, the old undo list will be restored by rl_maybe_unsave_line.) */ + rl_free_undo_list (); } rl_restore_prompt (); - noninc_dosearch (noninc_search_string, dir); - RL_UNSETSTATE(RL_STATE_NSEARCH); + return (noninc_dosearch (noninc_search_string, cxt->direction)); +} + +/* Search non-interactively through the history list. DIR < 0 means to + search backwards through the history of previous commands; otherwise + the search is for commands subsequent to the current position in the + history list. PCHAR is the character to use for prompting when reading + the search string; if not specified (0), it defaults to `:'. */ +static int +noninc_search (dir, pchar) + int dir; + int pchar; +{ + _rl_search_cxt *cxt; + int c, r; + + cxt = _rl_nsearch_init (dir, pchar); + + if (RL_ISSTATE (RL_STATE_CALLBACK)) + return (0); + + /* Read the search string. */ + r = 0; + while (1) + { + c = _rl_search_getchar (cxt); + + if (c == 0) + break; + + r = _rl_nsearch_dispatch (cxt, c); + if (r < 0) + return 1; + else if (r == 0) + break; + } + + r = _rl_nsearch_dosearch (cxt); + return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1)); } /* Search forward through the history list for a string. If the vi-mode @@ -298,8 +386,7 @@ int rl_noninc_forward_search (count, key) int count, key; { - noninc_search (1, (key == '?') ? '?' : 0); - return 0; + return noninc_search (1, (key == '?') ? '?' : 0); } /* Reverse search the history list for a string. If the vi-mode code @@ -308,8 +395,7 @@ int rl_noninc_reverse_search (count, key) int count, key; { - noninc_search (-1, (key == '/') ? '/' : 0); - return 0; + return noninc_search (-1, (key == '/') ? '/' : 0); } /* Search forward through the history list for the last string searched @@ -318,13 +404,15 @@ int rl_noninc_forward_search_again (count, key) int count, key; { + int r; + if (!noninc_search_string) { rl_ding (); return (-1); } - noninc_dosearch (noninc_search_string, 1); - return 0; + r = noninc_dosearch (noninc_search_string, 1); + return (r != 1); } /* Reverse search in the history list for the last string searched @@ -333,15 +421,34 @@ int rl_noninc_reverse_search_again (count, key) int count, key; { + int r; + if (!noninc_search_string) { rl_ding (); return (-1); } - noninc_dosearch (noninc_search_string, -1); - return 0; + r = noninc_dosearch (noninc_search_string, -1); + return (r != 1); } +#if defined (READLINE_CALLBACKS) +int +_rl_nsearch_callback (cxt) + _rl_search_cxt *cxt; +{ + int c, r; + + c = _rl_search_getchar (cxt); + r = _rl_nsearch_dispatch (cxt, c); + if (r != 0) + return 1; + + r = _rl_nsearch_dosearch (cxt); + return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1)); +} +#endif + static int rl_history_search_internal (count, dir) int count, dir; diff --git a/readline/shell.c b/readline/shell.c index 35b1c1d..346f811 100644 --- a/readline/shell.c +++ b/readline/shell.c @@ -27,7 +27,6 @@ #endif #include <sys/types.h> -#include <stdio.h> #if defined (HAVE_UNISTD_H) # include <unistd.h> @@ -49,8 +48,10 @@ # include <limits.h> #endif +#if defined (HAVE_FCNTL_H) #include <fcntl.h> -#ifdef HAVE_PWD_H +#endif +#if defined (HAVE_PWD_H) #include <pwd.h> #endif @@ -60,9 +61,9 @@ #include "rlshell.h" #include "xmalloc.h" -#if !defined (HAVE_GETPW_DECLS) +#if defined (HAVE_GETPWUID) && !defined (HAVE_GETPW_DECLS) extern struct passwd *getpwuid PARAMS((uid_t)); -#endif /* !HAVE_GETPW_DECLS */ +#endif /* HAVE_GETPWUID && !HAVE_GETPW_DECLS */ #ifndef NULL # define NULL 0 @@ -125,23 +126,27 @@ sh_set_lines_and_columns (lines, cols) { char *b; -#if defined (HAVE_PUTENV) - b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("LINES=") + 1); - sprintf (b, "LINES=%d", lines); - putenv (b); - b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("COLUMNS=") + 1); - sprintf (b, "COLUMNS=%d", cols); - putenv (b); -#else /* !HAVE_PUTENV */ -# if defined (HAVE_SETENV) +#if defined (HAVE_SETENV) b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1); sprintf (b, "%d", lines); setenv ("LINES", b, 1); + free (b); + b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1); sprintf (b, "%d", cols); setenv ("COLUMNS", b, 1); -# endif /* HAVE_SETENV */ -#endif /* !HAVE_PUTENV */ + free (b); +#else /* !HAVE_SETENV */ +# if defined (HAVE_PUTENV) + b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("LINES=") + 1); + sprintf (b, "LINES=%d", lines); + putenv (b); + + b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("COLUMNS=") + 1); + sprintf (b, "COLUMNS=%d", cols); + putenv (b); +# endif /* HAVE_PUTENV */ +#endif /* !HAVE_SETENV */ } char * @@ -158,7 +163,7 @@ sh_get_home_dir () struct passwd *entry; home_dir = (char *)NULL; -#ifdef HAVE_GETPWUID +#if defined (HAVE_GETPWUID) entry = getpwuid (getuid ()); if (entry) home_dir = entry->pw_dir; @@ -176,7 +181,7 @@ int sh_unset_nodelay_mode (fd) int fd; { -#ifdef HAVE_FNCTL +#if defined (HAVE_FCNTL) int flags, bflags; if ((flags = fcntl (fd, F_GETFL, 0)) < 0) diff --git a/readline/shlib/Makefile.in b/readline/shlib/Makefile.in index 22748c4..40039c3 100644 --- a/readline/shlib/Makefile.in +++ b/readline/shlib/Makefile.in @@ -1,7 +1,7 @@ ## -*- text -*- ## # Makefile for the GNU readline library shared library support. # -# Copyright (C) 1998 Free Software Foundation, Inc. +# Copyright (C) 1998-2003 Free Software Foundation, Inc. # 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 @@ -17,6 +17,14 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. +PACKAGE = @PACKAGE_NAME@ +VERSION = @PACKAGE_VERSION@ + +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_VERSION = @PACKAGE_VERSION@ + RL_LIBRARY_VERSION = @LIBVERSION@ RL_LIBRARY_NAME = readline @@ -45,7 +53,10 @@ host_os = @host_os@ prefix = @prefix@ exec_prefix = @exec_prefix@ includedir = @includedir@ +bindir = @bindir@ libdir = @libdir@ +datadir = @datadir@ +localedir = $(datadir)/locale # Support an alternate destination root directory for package building DESTDIR = @@ -55,7 +66,7 @@ LOCAL_CFLAGS = @LOCAL_CFLAGS@ -DRL_LIBRARY_VERSION='"$(RL_LIBRARY_VERSION)"' CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ @LOCAL_LDFLAGS@ @CFLAGS@ -DEFS = @DEFS@ +DEFS = @DEFS@ @CROSS_COMPILE@ LOCAL_DEFS = @LOCAL_DEFS@ # @@ -72,14 +83,20 @@ SHOBJ_LDFLAGS = @SHOBJ_LDFLAGS@ SHOBJ_XLDFLAGS = @SHOBJ_XLDFLAGS@ SHOBJ_LIBS = @SHOBJ_LIBS@ -SHLIB_XLDFLAGS = @SHLIB_XLDFLAGS@ +SHLIB_XLDFLAGS = @LDFLAGS@ @SHLIB_XLDFLAGS@ SHLIB_LIBS = @SHLIB_LIBS@ + +SHLIB_DOT = @SHLIB_DOT@ +SHLIB_LIBPREF = @SHLIB_LIBPREF@ SHLIB_LIBSUFF = @SHLIB_LIBSUFF@ SHLIB_LIBVERSION = @SHLIB_LIBVERSION@ +SHLIB_DLLVERSION = @SHLIB_DLLVERSION@ SHLIB_STATUS = @SHLIB_STATUS@ +TERMCAP_LIB = @TERMCAP_LIB@ + # shared library versioning SHLIB_MAJOR= @SHLIB_MAJOR@ # shared library systems like SVR4's do not use minor versions @@ -99,8 +116,8 @@ CCFLAGS = $(DEFS) $(LOCAL_DEFS) $(CPPFLAGS) $(INCLUDES) $(LOCAL_CFLAGS) $(CFLAGS # The name of the main library target. -SHARED_READLINE = libreadline.$(SHLIB_LIBVERSION) -SHARED_HISTORY = libhistory.$(SHLIB_LIBVERSION) +SHARED_READLINE = $(SHLIB_LIBPREF)readline$(SHLIB_DOT)$(SHLIB_LIBVERSION) +SHARED_HISTORY = $(SHLIB_LIBPREF)history$(SHLIB_DOT)$(SHLIB_LIBVERSION) SHARED_LIBS = $(SHARED_READLINE) $(SHARED_HISTORY) WCWIDTH_OBJ = @WCWIDTH_OBJ@ @@ -117,7 +134,7 @@ CSOURCES = $(topdir)/readline.c $(topdir)/funmap.c $(topdir)/keymaps.c \ $(topdir)/histfile.c $(topdir)/nls.c $(topdir)/search.c \ $(topdir)/shell.c $(topdir)/savestring.c $(topdir)/tilde.c \ $(topdir)/text.c $(topdir)/misc.c $(topdir)/compat.c \ - $(topdir)/mbutil.c $(WCWIDTH_SRC) + $(topdir)/mbutil.c $(topdir)/support/wcwidth.c # The header files for this library. HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h histlib.h \ @@ -170,13 +187,13 @@ installdirs: $(topdir)/support/mkdirs -$(SHELL) $(topdir)/support/mkdirs $(DESTDIR)$(libdir) install: installdirs $(SHLIB_STATUS) - $(SHELL) $(topdir)/support/shlib-install -O $(host_os) -d $(DESTDIR)$(libdir) -i "$(INSTALL_DATA)" $(SHARED_HISTORY) - $(SHELL) $(topdir)/support/shlib-install -O $(host_os) -d $(DESTDIR)$(libdir) -i "$(INSTALL_DATA)" $(SHARED_READLINE) + $(SHELL) $(topdir)/support/shlib-install -O $(host_os) -d $(DESTDIR)$(libdir) -b $(DESTDIR)$(bindir) -i "$(INSTALL_DATA)" $(SHARED_HISTORY) + $(SHELL) $(topdir)/support/shlib-install -O $(host_os) -d $(DESTDIR)$(libdir) -b $(DESTDIR)$(bindir) -i "$(INSTALL_DATA)" $(SHARED_READLINE) @echo install: you may need to run ldconfig uninstall: - $(SHELL) $(topdir)/support/shlib-install -O $(host_os) -d $(DESTDIR)$(libdir) -U $(SHARED_HISTORY) - $(SHELL) $(topdir)/support/shlib-install -O $(host_os) -d $(DESTDIR)$(libdir) -U $(SHARED_READLINE) + $(SHELL) $(topdir)/support/shlib-install -O $(host_os) -d $(DESTDIR)$(libdir) -b $(DESTDIR)$(bindir) -U $(SHARED_HISTORY) + $(SHELL) $(topdir)/support/shlib-install -O $(host_os) -d $(DESTDIR)$(libdir) -b $(DESTDIR)$(bindir) -U $(SHARED_READLINE) @echo uninstall: you may need to run ldconfig clean mostlyclean: force @@ -396,7 +413,7 @@ search.so: $(topdir)/search.c shell.so: $(topdir)/shell.c signals.so: $(topdir)/signals.c terminal.so: $(topdir)/terminal.c -text.so: $(topdir)/terminal.c +text.so: $(topdir)/text.c tilde.so: $(topdir)/tilde.c undo.so: $(topdir)/undo.c util.so: $(topdir)/util.c @@ -430,7 +447,7 @@ search.so: search.c signals.so: signals.c shell.so: shell.c terminal.so: terminal.c -text.so: terminal.c +text.so: text.c tilde.so: tilde.c undo.so: undo.c util.so: util.c diff --git a/readline/signals.c b/readline/signals.c index fa3e26a..f344ed8 100644 --- a/readline/signals.c +++ b/readline/signals.c @@ -1,6 +1,6 @@ /* signals.c -- signal handling support for readline. */ -/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc. +/* Copyright (C) 1987-2005 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -73,6 +73,10 @@ typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt # define sigemptyset(m) #endif /* !HAVE_POSIX_SIGNALS */ +#ifndef SA_RESTART +# define SA_RESTART 0 +#endif + static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *)); static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *)); @@ -85,12 +89,12 @@ int rl_catch_signals = 1; /* If non-zero, readline will install a signal handler for SIGWINCH. */ #ifdef SIGWINCH int rl_catch_sigwinch = 1; +#else +int rl_catch_sigwinch = 0; /* for the readline state struct in readline.c */ #endif static int signals_set_flag; -#ifdef SIGWINCH static int sigwinch_set_flag; -#endif /* **************************************************************** */ /* */ @@ -127,11 +131,11 @@ rl_signal_handler (sig) #if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS) /* Since the signal will not be blocked while we are in the signal handler, ignore it until rl_clear_signals resets the catcher. */ - if (sig == SIGINT -#ifdef SIGALRM - || sig == SIGALRM -#endif - ) +# if defined (SIGALRM) + if (sig == SIGINT || sig == SIGALRM) +# else + if (sig == SIGINT) +# endif rl_set_sighandler (sig, SIG_IGN, &dummy_cxt); #endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */ @@ -141,16 +145,16 @@ rl_signal_handler (sig) rl_free_line_state (); /* FALLTHROUGH */ + case SIGTERM: #if defined (SIGTSTP) case SIGTSTP: case SIGTTOU: case SIGTTIN: #endif /* SIGTSTP */ -#ifdef SIGALRM +#if defined (SIGALRM) case SIGALRM: #endif - case SIGTERM: -#ifdef SIGQUIT +#if defined (SIGQUIT) case SIGQUIT: #endif rl_cleanup_after_signal (); @@ -168,13 +172,10 @@ rl_signal_handler (sig) signal (sig, SIG_ACK); #endif - /* If we have the POSIX kill function, use it; otherwise, fall - back to the ISO C raise function. (Windows is an example of - a platform that has raise, but not kill.) */ -#ifdef HAVE_KILL +#if defined (HAVE_KILL) kill (getpid (), sig); #else - raise (sig); + raise (sig); /* assume we have raise */ #endif /* Let the signal that we just sent through. */ @@ -250,7 +251,7 @@ rl_set_sighandler (sig, handler, ohandler) struct sigaction act; act.sa_handler = handler; - act.sa_flags = 0; /* XXX - should we set SA_RESTART for SIGWINCH? */ + act.sa_flags = (sig == SIGWINCH) ? SA_RESTART : 0; sigemptyset (&act.sa_mask); sigemptyset (&ohandler->sa_mask); sigaction (sig, &act, &old_handler); @@ -292,11 +293,11 @@ rl_set_signals () { rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int); rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term); -#ifdef SIGQUIT +#if defined (SIGQUIT) rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit); #endif -#ifdef SIGALRM +#if defined (SIGALRM) oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm); if (oh == (SigHandler *)SIG_IGN) rl_sigaction (SIGALRM, &old_alrm, &dummy); @@ -347,10 +348,10 @@ rl_clear_signals () rl_sigaction (SIGINT, &old_int, &dummy); rl_sigaction (SIGTERM, &old_term, &dummy); -#ifdef SIGQUIT +#if defined (SIGQUIT) rl_sigaction (SIGQUIT, &old_quit, &dummy); #endif -#ifdef SIGALRM +#if defined (SIGALRM) rl_sigaction (SIGALRM, &old_alrm, &dummy); #endif @@ -387,7 +388,8 @@ void rl_cleanup_after_signal () { _rl_clean_up_for_exit (); - (*rl_deprep_term_function) (); + if (rl_deprep_term_function) + (*rl_deprep_term_function) (); rl_clear_signals (); rl_clear_pending_input (); } @@ -396,7 +398,8 @@ rl_cleanup_after_signal () void rl_reset_after_signal () { - (*rl_prep_term_function) (_rl_meta_flag); + if (rl_prep_term_function) + (*rl_prep_term_function) (_rl_meta_flag); rl_set_signals (); } @@ -417,7 +420,7 @@ rl_free_line_state () _rl_kill_kbd_macro (); rl_clear_message (); - _rl_init_argument (); + _rl_reset_argument (); } #endif /* HANDLE_SIGNALS */ diff --git a/readline/support/shlib-install b/readline/support/shlib-install index 654cfa9..2cd252a 100755 --- a/readline/support/shlib-install +++ b/readline/support/shlib-install @@ -3,7 +3,7 @@ # shlib-install - install a shared library and do any necessary host-specific # post-installation configuration (like ldconfig) # -# usage: shlib-install [-D] -O host_os -d installation-dir -i install-prog [-U] library +# usage: shlib-install [-D] -O host_os -d installation-dir [-b bin-dir] -i install-prog [-U] library # # Chet Ramey # chet@po.cwru.edu @@ -15,7 +15,7 @@ INSTALLDIR=/usr/local/lib LDCONFIG=ldconfig PROGNAME=`basename $0` -USAGE="$PROGNAME [-D] -O host_os -d installation-dir -i install-prog [-U] library" +USAGE="$PROGNAME [-D] -O host_os -d installation-dir [-b bin-dir] -i install-prog [-U] library" # process options @@ -23,6 +23,7 @@ while [ $# -gt 0 ]; do case "$1" in -O) shift; host_os="$1"; shift ;; -d) shift; INSTALLDIR="$1"; shift ;; + -b) shift; BINDIR="$1" ; shift ;; -i) shift; INSTALLPROG="$1" ; shift ;; -D) echo=echo ; shift ;; -U) uninstall=true ; shift ;; @@ -64,11 +65,30 @@ fi # post-install/uninstall # HP-UX and Darwin/MacOS X require that a shared library have execute permission +# Cygwin installs both a dll (which must go in $BINDIR) and an implicit +# link library (in $libdir) case "$host_os" in hpux*|darwin*|macosx*) if [ -z "$uninstall" ]; then chmod 555 ${INSTALLDIR}/${LIBNAME} fi ;; +cygwin*) + IMPLIBNAME=`echo ${LIBNAME} \ + | sed -e 's,^cyg,lib,' -e 's,[0-9]*.dll$,.dll.a,'` + if [ -z "$uninstall" ]; then + ${echo} $RM ${BINDIR}/${LIBNAME}.${OLDSUFF} + if [ -f "$BINDIR/$LIBNAME" ]; then + ${echo} $MV $BINDIR/$LIBNAME $BINDIR/$LIBNAME.$OLDSUFF + fi + ${echo} $MV ${INSTALLDIR}/${LIBNAME} ${BINDIR}/${LIBNAME} + ${echo} chmod a+x ${BINDIR}/${LIBNAME} + ${echo} eval ${INSTALLPROG} ${LIBNAME}.a \ + ${INSTALLDIR}/${IMPLIBNAME} + else + ${echo} ${RM} ${BINDIR}/${LIBNAME} + ${echo} ${RM} ${INSTALLDIR}/${IMPLIBNAME} + fi ;; + *) ;; esac @@ -88,24 +108,38 @@ case "$LIBNAME" in LINK1=`echo $LIBNAME | sed 's:\(.*\)\.[0-9]\.[0-9]:\1:'` # libname.dylib esac -INSTALL_LINK1='cd $INSTALLDIR ; ln -s $LIBNAME $LINK1' -INSTALL_LINK2='cd $INSTALLDIR ; ln -s $LIBNAME $LINK2' +INSTALL_LINK1='${echo} cd $INSTALLDIR && ${echo} ${LN} $LIBNAME $LINK1' +INSTALL_LINK2='${echo} cd $INSTALLDIR && ${echo} ${LN} $LIBNAME $LINK2' # # Create symlinks to the installed library. This section is incomplete. # case "$host_os" in -*linux*|bsdi4*|*gnu*|darwin*|macosx*) +*linux*) + # libname.so.M -> libname.so.M.N + ${echo} ${RM} ${INSTALLDIR}/$LINK2 + if [ -z "$uninstall" ]; then + eval $INSTALL_LINK2 + fi + + # libname.so -> libname.so.M + ${echo} ${RM} ${INSTALLDIR}/$LINK1 + if [ -z "$uninstall" ]; then + ${echo} cd $INSTALLDIR && ${echo} ${LN} $LINK2 $LINK1 + fi + ;; + +bsdi4*|*gnu*|darwin*|macosx*|k*bsd*-gnu) # libname.so.M -> libname.so.M.N ${echo} ${RM} ${INSTALLDIR}/$LINK2 if [ -z "$uninstall" ]; then - ${echo} ln -s $LIBNAME ${INSTALLDIR}/$LINK2 + eval $INSTALL_LINK2 fi # libname.so -> libname.so.M.N ${echo} ${RM} ${INSTALLDIR}/$LINK1 if [ -z "$uninstall" ]; then - ${echo} ln -s $LIBNAME ${INSTALLDIR}/$LINK1 + eval $INSTALL_LINK1 fi ;; @@ -113,7 +147,7 @@ solaris2*|aix4.[2-9]*|osf*|irix[56]*|sysv[45]*|dgux*) # libname.so -> libname.so.M ${echo} ${RM} ${INSTALLDIR}/$LINK1 if [ -z "$uninstall" ]; then - ${echo} ln -s $LIBNAME ${INSTALLDIR}/$LINK1 + eval $INSTALL_LINK1 fi ;; @@ -124,19 +158,19 @@ freebsd[3-9]*|freebsdelf[3-9]*|freebsdaout[3-9]*) # libname.so -> libname.so.M ${echo} ${RM} ${INSTALLDIR}/$LINK1 if [ -z "$uninstall" ]; then - ${echo} ln -s $LIBNAME ${INSTALLDIR}/$LINK1 + eval $INSTALL_LINK1 fi else # libname.so.M -> libname.so.M.N ${echo} ${RM} ${INSTALLDIR}/$LINK2 if [ -z "$uninstall" ]; then - ${echo} ln -s $LIBNAME ${INSTALLDIR}/$LINK2 + eval $INSTALL_LINK2 fi # libname.so -> libname.so.M.N ${echo} ${RM} ${INSTALLDIR}/$LINK1 if [ -z "$uninstall" ]; then - ${echo} ln -s $LIBNAME ${INSTALLDIR}/$LINK1 + eval $INSTALL_LINK1 fi fi ;; @@ -145,11 +179,16 @@ hpux1*) # libname.sl -> libname.M ${echo} ${RM} ${INSTALLDIR}/$LINK1.sl if [ -z "$uninstall" ]; then -# ${echo} ln -s $LIBNAME ${INSTALLDIR}/${LINK1}.sl - ${echo} ln -s $LIBNAME ${INSTALLDIR}/${LINK1} + eval $INSTALL_LINK1 fi ;; +cygwin*) + # Links to .dlls don't work. Hence shobj-conf used DLLVERSION.dll + # instead of so.SHLIB_MAJOR.SHLIB_MINOR. The postinstall above + # took care of everything else. + ;; + *) ;; esac diff --git a/readline/support/shobj-conf b/readline/support/shobj-conf index 6bd7fb1..0e306bc 100755 --- a/readline/support/shobj-conf +++ b/readline/support/shobj-conf @@ -41,9 +41,13 @@ SHOBJ_LIBS= SHLIB_XLDFLAGS= SHLIB_LIBS= + +SHLIB_DOT='.' +SHLIB_LIBPREF='lib' SHLIB_LIBSUFF='so' SHLIB_LIBVERSION='$(SHLIB_LIBSUFF)' +SHLIB_DLLVERSION='$(SHLIB_MAJOR)' PROGNAME=`basename $0` USAGE="$PROGNAME [-C compiler] -c host_cpu -o host_os -v host_vendor" @@ -78,10 +82,14 @@ sunos4*) sunos5*-*gcc*|solaris2*-*gcc*) SHOBJ_CFLAGS=-fpic SHOBJ_LD='${CC}' - # This line works for the Solaris linker in /usr/ccs/bin/ld - SHOBJ_LDFLAGS='-shared -Wl,-i -Wl,-h,$@' - # This line works for the GNU ld -# SHOBJ_LDFLAGS='-shared -Wl,-h,$@' + ld_used=`gcc -print-prog-name=ld` + if ${ld_used} -V 2>&1 | grep GNU >/dev/null 2>&1; then + # This line works for the GNU ld + SHOBJ_LDFLAGS='-shared -Wl,-h,$@' + else + # This line works for the Solaris linker in /usr/ccs/bin/ld + SHOBJ_LDFLAGS='-shared -Wl,-i -Wl,-h,$@' + fi # SHLIB_XLDFLAGS='-R $(libdir)' SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' @@ -97,7 +105,7 @@ sunos5*|solaris2*) ;; # All versions of Linux or the semi-mythical GNU Hurd. -linux*|gnu*) +linux*-*|gnu*-*|k*bsd*-gnu-*) SHOBJ_CFLAGS=-fPIC SHOBJ_LD='${CC}' SHOBJ_LDFLAGS='-shared -Wl,-soname,$@' @@ -116,7 +124,7 @@ freebsd2* | netbsd*) ;; # FreeBSD-3.x ELF -freebsd[3-9]*|freebsdelf[3-9]*|freebsdaout[3-9]*) +freebsd[3-9]*|freebsdelf[3-9]*|freebsdaout[3-9]*|dragonfly*) SHOBJ_CFLAGS=-fpic SHOBJ_LD='${CC}' @@ -138,17 +146,23 @@ darwin*|macosx*) SHOBJ_STATUS=unsupported SHLIB_STATUS=supported - SHOBJ_CFLAGS='-dynamic -fno-common' + SHOBJ_CFLAGS='-fno-common' - SHOBJ_LD=/usr/bin/libtool + SHOBJ_LD='${CC}' SHLIB_LIBVERSION='$(SHLIB_MAJOR)$(SHLIB_MINOR).$(SHLIB_LIBSUFF)' SHLIB_LIBSUFF='dylib' - SHOBJ_LDFLAGS='-dynamic' - SHLIB_XLDFLAGS='-arch_only `/usr/bin/arch` -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v' + case "${host_os}" in + darwin[78]*) SHOBJ_LDFLAGS='' + SHLIB_XLDFLAGS='-dynamiclib -arch_only `/usr/bin/arch` -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v' + ;; + *) SHOBJ_LDFLAGS='-dynamic' + SHLIB_XLDFLAGS='-arch_only `/usr/bin/arch` -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v' + ;; + esac - SHLIB_LIBS='-lSystem' + SHLIB_LIBS='-lncurses' # see if -lcurses works on MacOS X 10.1 ;; openbsd*) @@ -296,6 +310,8 @@ hpux10*-*gcc*) # must use gcc; the bundled cc cannot compile PIC code SHOBJ_CFLAGS='-fpic' SHOBJ_LD='${CC}' + # if you have problems linking here, moving the `-Wl,+h,$@' from + # SHLIB_XLDFLAGS to SHOBJ_LDFLAGS has been reported to work SHOBJ_LDFLAGS='-shared -Wl,-b -Wl,+s' SHLIB_XLDFLAGS='-Wl,+h,$@ -Wl,+b,$(libdir)' @@ -400,7 +416,39 @@ sysv5uw7*) SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' ;; - + +sysv5UnixWare*-*gcc*) + SHOBJ_CFLAGS=-fpic + SHOBJ_LD='${CC}' + SHOBJ_LDFLAGS='-shared' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +sysv5UnixWare*) + SHOBJ_CFLAGS='-K PIC' + SHOBJ_LD=ld + SHOBJ_LDFLAGS='-G -dy -z text -h $@' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +sysv5OpenUNIX*-*gcc*) + SHOBJ_CFLAGS=-fpic + SHOBJ_LD='${CC}' + SHOBJ_LDFLAGS='-shared' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +sysv5OpenUNIX*) + SHOBJ_CFLAGS='-K PIC' + SHOBJ_LD=ld + SHOBJ_LDFLAGS='-G -dy -z text -h $@' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + dgux*-*gcc*) SHOBJ_CFLAGS=-fpic SHOBJ_LD='${CC}' @@ -422,6 +470,24 @@ msdos*) SHLIB_STATUS=unsupported ;; +cygwin*) + SHOBJ_LD='$(CC)' + SHOBJ_LDFLAGS='-shared -Wl,--enable-auto-import -Wl,--enable-auto-image-base -Wl,--export-all -Wl,--out-implib=$(@).a' + SHLIB_LIBPREF='cyg' + SHLIB_LIBSUFF='dll' + SHLIB_LIBVERSION='$(SHLIB_DLLVERSION).$(SHLIB_LIBSUFF)' + SHLIB_LIBS='$(TERMCAP_LIB)' + + SHLIB_DOT= + # For official cygwin releases, DLLVERSION will be defined in the + # environment of configure, and will be incremented any time the API + # changes in a non-backwards compatible manner. Otherwise, it is just + # SHLIB_MAJOR. + if [ -n "$DLLVERSION" ] ; then + SHLIB_DLLVERSION="$DLLVERSION" + fi + ;; + # # Rely on correct gcc configuration for everything else # @@ -449,8 +515,14 @@ echo SHOBJ_LIBS=\'"$SHOBJ_LIBS"\' echo SHLIB_XLDFLAGS=\'"$SHLIB_XLDFLAGS"\' echo SHLIB_LIBS=\'"$SHLIB_LIBS"\' + +echo SHLIB_DOT=\'"$SHLIB_DOT"\' + +echo SHLIB_LIBPREF=\'"$SHLIB_LIBPREF"\' echo SHLIB_LIBSUFF=\'"$SHLIB_LIBSUFF"\' + echo SHLIB_LIBVERSION=\'"$SHLIB_LIBVERSION"\' +echo SHLIB_DLLVERSION=\'"$SHLIB_DLLVERSION"\' echo SHOBJ_STATUS=\'"$SHOBJ_STATUS"\' echo SHLIB_STATUS=\'"$SHLIB_STATUS"\' diff --git a/readline/terminal.c b/readline/terminal.c index ce45d28..21732a7 100644 --- a/readline/terminal.c +++ b/readline/terminal.c @@ -1,6 +1,6 @@ /* terminal.c -- controlling the terminal with termcap. */ -/* Copyright (C) 1996 Free Software Foundation, Inc. +/* Copyright (C) 1996-2005 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -78,6 +78,8 @@ #define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay) #define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc) +int rl_prefer_env_winsize; + /* **************************************************************** */ /* */ /* Terminal and Termcap */ @@ -87,9 +89,6 @@ #ifndef __MSDOS__ static char *term_buffer = (char *)NULL; static char *term_string_buffer = (char *)NULL; - -/* Non-zero means this terminal can't really do anything. */ -static int dumb_term; #endif /* !__MSDOS__ */ static int tcap_initialized; @@ -134,7 +133,7 @@ char *_rl_term_up; static char *_rl_visible_bell; /* Non-zero means the terminal can auto-wrap lines. */ -int _rl_term_autowrap; +int _rl_term_autowrap = -1; /* Non-zero means that this terminal has a meta key. */ static int term_has_meta; @@ -159,6 +158,9 @@ static char *_rl_term_kh; static char *_rl_term_kH; static char *_rl_term_at7; /* @7 */ +/* Delete key */ +static char *_rl_term_kD; + /* Insert key */ static char *_rl_term_kI; @@ -205,12 +207,14 @@ _rl_get_screen_size (tty, ignore_env) #if defined (TIOCGWINSZ) struct winsize window_size; #endif /* TIOCGWINSZ */ + int wr, wc; + wr = wc = -1; #if defined (TIOCGWINSZ) if (ioctl (tty, TIOCGWINSZ, &window_size) == 0) { - _rl_screenwidth = (int) window_size.ws_col; - _rl_screenheight = (int) window_size.ws_row; + wc = (int) window_size.ws_col; + wr = (int) window_size.ws_row; } #endif /* TIOCGWINSZ */ @@ -232,13 +236,25 @@ _rl_get_screen_size (tty, ignore_env) _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight); #endif + if (ignore_env || rl_prefer_env_winsize == 0) + { + _rl_screenwidth = wc; + _rl_screenheight = wr; + } + else + _rl_screenwidth = _rl_screenheight = -1; + /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV - is unset. */ + is unset. If we prefer the environment, check it first before + assigning the value returned by the kernel. */ if (_rl_screenwidth <= 0) { if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS"))) _rl_screenwidth = atoi (ss); + if (_rl_screenwidth <= 0) + _rl_screenwidth = wc; + #if defined (__DJGPP__) if (_rl_screenwidth <= 0) _rl_screenwidth = ScreenCols (); @@ -255,6 +271,9 @@ _rl_get_screen_size (tty, ignore_env) if (ignore_env == 0 && (ss = sh_get_env_value ("LINES"))) _rl_screenheight = atoi (ss); + if (_rl_screenheight <= 0) + _rl_screenheight = wr; + #if defined (__DJGPP__) if (_rl_screenheight <= 0) _rl_screenheight = ScreenRows (); @@ -286,16 +305,20 @@ void _rl_set_screen_size (rows, cols) int rows, cols; { - if (rows == 0 || cols == 0) - return; + if (_rl_term_autowrap == -1) + _rl_init_terminal_io (rl_terminal_name); - _rl_screenheight = rows; - _rl_screenwidth = cols; - - if (_rl_term_autowrap == 0) - _rl_screenwidth--; + if (rows > 0) + _rl_screenheight = rows; + if (cols > 0) + { + _rl_screenwidth = cols; + if (_rl_term_autowrap == 0) + _rl_screenwidth--; + } - _rl_screenchars = _rl_screenwidth * _rl_screenheight; + if (rows > 0 || cols > 0) + _rl_screenchars = _rl_screenwidth * _rl_screenheight; } void @@ -314,6 +337,12 @@ rl_get_screen_size (rows, cols) if (cols) *cols = _rl_screenwidth; } + +void +rl_reset_screen_size () +{ + _rl_get_screen_size (fileno (rl_instream), 0); +} void rl_resize_terminal () @@ -347,6 +376,7 @@ static struct _tc_string tc_strings[] = { "ei", &_rl_term_ei }, { "ic", &_rl_term_ic }, { "im", &_rl_term_im }, + { "kD", &_rl_term_kD }, /* delete */ { "kH", &_rl_term_kH }, /* home down ?? */ { "kI", &_rl_term_kI }, /* insert */ { "kd", &_rl_term_kd }, @@ -381,11 +411,7 @@ get_term_capabilities (bp) register int i; for (i = 0; i < NUM_TC_STRINGS; i++) -# ifdef __LCC__ *(tc_strings[i].tc_value) = tgetstr ((char *)tc_strings[i].tc_var, bp); -# else - *(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp); -# endif #endif tcap_initialized = 1; } @@ -401,7 +427,6 @@ _rl_init_terminal_io (terminal_name) term = terminal_name ? terminal_name : sh_get_env_value ("TERM"); _rl_term_clrpag = _rl_term_cr = _rl_term_clreol = (char *)NULL; tty = rl_instream ? fileno (rl_instream) : 0; - _rl_screenwidth = _rl_screenheight = 0; if (term == 0) term = "dumb"; @@ -451,12 +476,17 @@ _rl_init_terminal_io (terminal_name) _rl_term_autowrap = 0; /* used by _rl_get_screen_size */ + /* Allow calling application to set default height and width, using + rl_set_screen_size */ + if (_rl_screenwidth <= 0 || _rl_screenheight <= 0) + { #if defined (__EMX__) - _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight); - _rl_screenwidth--; + _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight); + _rl_screenwidth--; #else /* !__EMX__ */ - _rl_get_screen_size (tty, 0); + _rl_get_screen_size (tty, 0); #endif /* !__EMX__ */ + } /* Defaults. */ if (_rl_screenwidth <= 0 || _rl_screenheight <= 0) @@ -471,7 +501,7 @@ _rl_init_terminal_io (terminal_name) _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL; _rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL; _rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL; - _rl_term_kh = _rl_term_kH = _rl_term_kI = (char *)NULL; + _rl_term_kh = _rl_term_kH = _rl_term_kI = _rl_term_kD = (char *)NULL; _rl_term_ks = _rl_term_ke = _rl_term_at7 = (char *)NULL; _rl_term_mm = _rl_term_mo = (char *)NULL; _rl_term_ve = _rl_term_vs = (char *)NULL; @@ -503,7 +533,10 @@ _rl_init_terminal_io (terminal_name) _rl_term_autowrap = tgetflag ("am") && tgetflag ("xn"); - _rl_get_screen_size (tty, 0); + /* Allow calling application to set default height and width, using + rl_set_screen_size */ + if (_rl_screenwidth <= 0 || _rl_screenheight <= 0) + _rl_get_screen_size (tty, 0); /* "An application program can assume that the terminal can do character insertion if *any one of* the capabilities `IC', @@ -542,13 +575,15 @@ bind_termcap_arrow_keys (map) xkeymap = _rl_keymap; _rl_keymap = map; - _rl_bind_if_unbound (_rl_term_ku, rl_get_previous_history); - _rl_bind_if_unbound (_rl_term_kd, rl_get_next_history); - _rl_bind_if_unbound (_rl_term_kr, rl_forward); - _rl_bind_if_unbound (_rl_term_kl, rl_backward); + rl_bind_keyseq_if_unbound (_rl_term_ku, rl_get_previous_history); + rl_bind_keyseq_if_unbound (_rl_term_kd, rl_get_next_history); + rl_bind_keyseq_if_unbound (_rl_term_kr, rl_forward_char); + rl_bind_keyseq_if_unbound (_rl_term_kl, rl_backward_char); + + rl_bind_keyseq_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */ + rl_bind_keyseq_if_unbound (_rl_term_at7, rl_end_of_line); /* End */ - _rl_bind_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */ - _rl_bind_if_unbound (_rl_term_at7, rl_end_of_line); /* End */ + rl_bind_keyseq_if_unbound (_rl_term_kD, rl_delete); _rl_keymap = xkeymap; } @@ -575,6 +610,7 @@ int rl_reset_terminal (terminal_name) const char *terminal_name; { + _rl_screenwidth = _rl_screenheight = 0; _rl_init_terminal_io (terminal_name); return 0; } @@ -656,8 +692,8 @@ rl_ding () tputs (_rl_visible_bell, 1, _rl_output_character_function); break; } -#endif /* FALLTHROUGH */ +#endif case AUDIBLE_BELL: fprintf (stderr, "\007"); fflush (stderr); diff --git a/readline/text.c b/readline/text.c index 2a7b724..bb87604 100644 --- a/readline/text.c +++ b/readline/text.c @@ -1,6 +1,6 @@ /* text.c -- text handling commands for readline. */ -/* Copyright (C) 1987-2002 Free Software Foundation, Inc. +/* Copyright (C) 1987-2005 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -62,6 +62,11 @@ static int rl_change_case PARAMS((int, int)); static int _rl_char_search PARAMS((int, int, int)); +#if defined (READLINE_CALLBACKS) +static int _rl_insert_next_callback PARAMS((_rl_callback_generic_arg *)); +static int _rl_char_search_callback PARAMS((_rl_callback_generic_arg *)); +#endif + /* **************************************************************** */ /* */ /* Insert and Delete */ @@ -170,6 +175,9 @@ _rl_fix_point (fix_mark_too) } #undef _RL_FIX_POINT +/* Replace the contents of the line buffer between START and END with + TEXT. The operation is undoable. To replace the entire line in an + undoable mode, use _rl_replace_text(text, 0, rl_end); */ int _rl_replace_text (text, start, end) const char *text; @@ -417,8 +425,7 @@ rl_end_of_line (count, key) return 0; } -/* XXX - these might need changes for multibyte characters */ -/* Move forward a word. We do what Emacs does. */ +/* Move forward a word. We do what Emacs does. Handles multibyte chars. */ int rl_forward_word (count, key) int count, key; @@ -435,68 +442,80 @@ rl_forward_word (count, key) /* If we are not in a word, move forward until we are in one. Then, move forward until we hit a non-alphabetic character. */ - c = rl_line_buffer[rl_point]; - if (rl_alphabetic (c) == 0) + c = _rl_char_value (rl_line_buffer, rl_point); + + if (_rl_walphabetic (c) == 0) { - while (++rl_point < rl_end) + rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); + while (rl_point < rl_end) { - c = rl_line_buffer[rl_point]; - if (rl_alphabetic (c)) + c = _rl_char_value (rl_line_buffer, rl_point); + if (_rl_walphabetic (c)) break; + rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); } } if (rl_point == rl_end) return 0; - while (++rl_point < rl_end) + rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); + while (rl_point < rl_end) { - c = rl_line_buffer[rl_point]; - if (rl_alphabetic (c) == 0) + c = _rl_char_value (rl_line_buffer, rl_point); + if (_rl_walphabetic (c) == 0) break; + rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); } + --count; } return 0; } -/* Move backward a word. We do what Emacs does. */ +/* Move backward a word. We do what Emacs does. Handles multibyte chars. */ int rl_backward_word (count, key) int count, key; { - int c; + int c, p; if (count < 0) return (rl_forward_word (-count, key)); while (count) { - if (!rl_point) + if (rl_point == 0) return 0; /* Like rl_forward_word (), except that we look at the characters just before point. */ - c = rl_line_buffer[rl_point - 1]; - if (rl_alphabetic (c) == 0) + p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); + c = _rl_char_value (rl_line_buffer, p); + + if (_rl_walphabetic (c) == 0) { - while (--rl_point) + rl_point = p; + while (rl_point > 0) { - c = rl_line_buffer[rl_point - 1]; - if (rl_alphabetic (c)) + p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); + c = _rl_char_value (rl_line_buffer, p); + if (_rl_walphabetic (c)) break; + rl_point = p; } } while (rl_point) { - c = rl_line_buffer[rl_point - 1]; - if (rl_alphabetic (c) == 0) + p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); + c = _rl_char_value (rl_line_buffer, p); + if (_rl_walphabetic (c) == 0) break; else - --rl_point; + rl_point = p; } --count; @@ -753,10 +772,8 @@ _rl_insert_char (count, c) return 0; } -#if defined (HANDLE_MULTIBYTE) if (MB_CUR_MAX == 1 || rl_byte_oriented) { -#endif /* We are inserting a single character. If there is pending input, then make a string of all of the pending characters that are bound to rl_insert, and insert @@ -772,8 +789,8 @@ _rl_insert_char (count, c) str[0] = c; rl_insert_text (str); } -#if defined (HANDLE_MULTIBYTE) } +#if defined (HANDLE_MULTIBYTE) else { rl_insert_text (incoming); @@ -801,13 +818,10 @@ _rl_overwrite_char (count, c) k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX); #endif + rl_begin_undo_group (); + for (i = 0; i < count; i++) { - rl_begin_undo_group (); - - if (rl_point < rl_end) - rl_delete (1, c); - #if defined (HANDLE_MULTIBYTE) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) rl_insert_text (mbkey); @@ -815,9 +829,12 @@ _rl_overwrite_char (count, c) #endif _rl_insert_char (1, c); - rl_end_undo_group (); + if (rl_point < rl_end) + rl_delete (1, c); } + rl_end_undo_group (); + return 0; } @@ -830,27 +847,63 @@ rl_insert (count, c) } /* Insert the next typed character verbatim. */ -int -rl_quoted_insert (count, key) - int count, key; +static int +_rl_insert_next (count) + int count; { int c; -#if defined (HANDLE_SIGNALS) - _rl_disable_tty_signals (); -#endif - RL_SETSTATE(RL_STATE_MOREINPUT); c = rl_read_key (); RL_UNSETSTATE(RL_STATE_MOREINPUT); #if defined (HANDLE_SIGNALS) - _rl_restore_tty_signals (); + if (RL_ISSTATE (RL_STATE_CALLBACK) == 0) + _rl_restore_tty_signals (); #endif return (_rl_insert_char (count, c)); } +#if defined (READLINE_CALLBACKS) +static int +_rl_insert_next_callback (data) + _rl_callback_generic_arg *data; +{ + int count; + + count = data->count; + + /* Deregister function, let rl_callback_read_char deallocate data */ + _rl_callback_func = 0; + _rl_want_redisplay = 1; + + return _rl_insert_next (count); +} +#endif + +int +rl_quoted_insert (count, key) + int count, key; +{ + /* Let's see...should the callback interface futz with signal handling? */ +#if defined (HANDLE_SIGNALS) + if (RL_ISSTATE (RL_STATE_CALLBACK) == 0) + _rl_disable_tty_signals (); +#endif + +#if defined (READLINE_CALLBACKS) + if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + _rl_callback_data = _rl_callback_data_alloc (count); + _rl_callback_func = _rl_insert_next_callback; + return (0); + } +#endif + + return _rl_insert_next (count); +} + /* Insert a tab character. */ int rl_tab_insert (count, key) @@ -877,7 +930,8 @@ rl_newline (count, key) if (rl_editing_mode == vi_mode) { _rl_vi_done_inserting (); - _rl_vi_reset_last (); + if (_rl_vi_textmod_command (_rl_vi_last_command) == 0) /* XXX */ + _rl_vi_reset_last (); } #endif /* VI_MODE */ @@ -935,9 +989,12 @@ _rl_overwrite_rubout (count, key) rl_delete_text (opoint, rl_point); /* Emacs puts point at the beginning of the sequence of spaces. */ - opoint = rl_point; - _rl_insert_char (l, ' '); - rl_point = opoint; + if (rl_point < rl_end) + { + opoint = rl_point; + _rl_insert_char (l, ' '); + rl_point = opoint; + } rl_end_undo_group (); @@ -981,43 +1038,17 @@ _rl_rubout_char (count, key) return -1; } + orig_point = rl_point; if (count > 1 || rl_explicit_arg) { - orig_point = rl_point; -#if defined (HANDLE_MULTIBYTE) - if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - rl_backward_char (count, key); - else -#endif - rl_backward_byte (count, key); + rl_backward_char (count, key); rl_kill_text (orig_point, rl_point); } - else + else if (MB_CUR_MAX == 1 || rl_byte_oriented) { -#if defined (HANDLE_MULTIBYTE) - if (MB_CUR_MAX == 1 || rl_byte_oriented) - { -#endif - c = rl_line_buffer[--rl_point]; - rl_delete_text (rl_point, rl_point + 1); -#if defined (HANDLE_MULTIBYTE) - } - else - { - int orig_point; - - orig_point = rl_point; - rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO); - c = rl_line_buffer[rl_point]; - rl_delete_text (rl_point, orig_point); - } -#endif /* HANDLE_MULTIBYTE */ - - /* I don't think that the hack for end of line is needed for - multibyte chars. */ -#if defined (HANDLE_MULTIBYTE) - if (MB_CUR_MAX == 1 || rl_byte_oriented) -#endif + c = rl_line_buffer[--rl_point]; + rl_delete_text (rl_point, orig_point); + /* The erase-at-end-of-line hack is of questionable merit now. */ if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos) { int l; @@ -1025,6 +1056,11 @@ _rl_rubout_char (count, key) _rl_erase_at_end_of_line (l); } } + else + { + rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO); + rl_delete_text (rl_point, orig_point); + } return 0; } @@ -1035,8 +1071,6 @@ int rl_delete (count, key) int count, key; { - int r; - if (count < 0) return (_rl_rubout_char (-count, key)); @@ -1049,27 +1083,22 @@ rl_delete (count, key) if (count > 1 || rl_explicit_arg) { int orig_point = rl_point; -#if defined (HANDLE_MULTIBYTE) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) rl_forward_char (count, key); else -#endif rl_forward_byte (count, key); - r = rl_kill_text (orig_point, rl_point); + rl_kill_text (orig_point, rl_point); rl_point = orig_point; - return r; } else { int new_point; - if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - new_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); - else - new_point = rl_point + 1; - - return (rl_delete_text (rl_point, new_point)); + + new_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); + rl_delete_text (rl_point, new_point); } + return 0; } /* Delete the character under the cursor, unless the insertion @@ -1106,6 +1135,10 @@ rl_delete_horizontal_space (count, ignore) rl_delete_text (start, rl_point); rl_point = start; } + + if (rl_point < 0) + rl_point = 0; + return 0; } @@ -1199,42 +1232,80 @@ static int rl_change_case (count, op) int count, op; { - register int start, end; - int inword, c; + int start, next, end; + int inword, c, nc, nop; +#if defined (HANDLE_MULTIBYTE) + wchar_t wc, nwc; + char mb[MB_LEN_MAX+1]; + int mblen, p; + mbstate_t ps; +#endif start = rl_point; rl_forward_word (count, 0); end = rl_point; + if (op != UpCase && op != DownCase && op != CapCase) + { + rl_ding (); + return -1; + } + if (count < 0) SWAP (start, end); +#if defined (HANDLE_MULTIBYTE) + memset (&ps, 0, sizeof (mbstate_t)); +#endif + /* We are going to modify some text, so let's prepare to undo it. */ rl_modifying (start, end); - for (inword = 0; start < end; start++) + inword = 0; + while (start < end) { - c = rl_line_buffer[start]; - switch (op) - { - case UpCase: - rl_line_buffer[start] = _rl_to_upper (c); - break; + c = _rl_char_value (rl_line_buffer, start); + /* This assumes that the upper and lower case versions are the same width. */ + next = MB_NEXTCHAR (rl_line_buffer, start, 1, MB_FIND_NONZERO); - case DownCase: - rl_line_buffer[start] = _rl_to_lower (c); - break; - - case CapCase: - rl_line_buffer[start] = (inword == 0) ? _rl_to_upper (c) : _rl_to_lower (c); - inword = rl_alphabetic (rl_line_buffer[start]); - break; + if (_rl_walphabetic (c) == 0) + { + inword = 0; + start = next; + continue; + } - default: - rl_ding (); - return -1; + if (op == CapCase) + { + nop = inword ? DownCase : UpCase; + inword = 1; } + else + nop = op; + if (MB_CUR_MAX == 1 || rl_byte_oriented || isascii (c)) + { + nc = (nop == UpCase) ? _rl_to_upper (c) : _rl_to_lower (c); + rl_line_buffer[start] = nc; + } +#if defined (HANDLE_MULTIBYTE) + else + { + mbrtowc (&wc, rl_line_buffer + start, end - start, &ps); + nwc = (nop == UpCase) ? _rl_to_wupper (wc) : _rl_to_wlower (wc); + if (nwc != wc) /* just skip unchanged characters */ + { + mblen = wcrtomb (mb, nwc, &ps); + if (mblen > 0) + mb[mblen] = '\0'; + /* Assume the same width */ + strncpy (rl_line_buffer + start, mb, mblen); + } + } +#endif + + start = next; } + rl_point = end; return 0; } @@ -1314,11 +1385,11 @@ rl_transpose_chars (count, key) { #if defined (HANDLE_MULTIBYTE) char *dummy; - int i, prev_point; + int i; #else char dummy[2]; #endif - int char_length; + int char_length, prev_point; if (count == 0) return 0; @@ -1333,20 +1404,12 @@ rl_transpose_chars (count, key) if (rl_point == rl_end) { - if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO); - else - --rl_point; + rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); count = 1; } -#if defined (HANDLE_MULTIBYTE) prev_point = rl_point; - if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO); - else -#endif - rl_point--; + rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); #if defined (HANDLE_MULTIBYTE) char_length = prev_point - rl_point; @@ -1480,10 +1543,33 @@ _rl_char_search (count, fdir, bdir) } #endif /* !HANDLE_MULTIBYTE */ +#if defined (READLINE_CALLBACKS) +static int +_rl_char_search_callback (data) + _rl_callback_generic_arg *data; +{ + _rl_callback_func = 0; + _rl_want_redisplay = 1; + + return (_rl_char_search (data->count, data->i1, data->i2)); +} +#endif + int rl_char_search (count, key) int count, key; { +#if defined (READLINE_CALLBACKS) + if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + _rl_callback_data = _rl_callback_data_alloc (count); + _rl_callback_data->i1 = FFIND; + _rl_callback_data->i2 = BFIND; + _rl_callback_func = _rl_char_search_callback; + return (0); + } +#endif + return (_rl_char_search (count, FFIND, BFIND)); } @@ -1491,6 +1577,17 @@ int rl_backward_char_search (count, key) int count, key; { +#if defined (READLINE_CALLBACKS) + if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + _rl_callback_data = _rl_callback_data_alloc (count); + _rl_callback_data->i1 = BFIND; + _rl_callback_data->i2 = FFIND; + _rl_callback_func = _rl_char_search_callback; + return (0); + } +#endif + return (_rl_char_search (count, BFIND, FFIND)); } diff --git a/readline/tilde.c b/readline/tilde.c index 60fc7fc..32f3d3c 100644 --- a/readline/tilde.c +++ b/readline/tilde.c @@ -43,9 +43,9 @@ #endif /* HAVE_STDLIB_H */ #include <sys/types.h> -#ifdef HAVE_PWD_H +#if defined (HAVE_PWD_H) #include <pwd.h> -#endif /* HAVE_PWD_H */ +#endif #include "tilde.h" @@ -55,10 +55,14 @@ static void *xmalloc (), *xrealloc (); # include "xmalloc.h" #endif /* TEST || STATIC_MALLOC */ -#if defined (HAVE_GETPWNAM) && !defined (HAVE_GETPW_DECLS) +#if !defined (HAVE_GETPW_DECLS) +# if defined (HAVE_GETPWUID) extern struct passwd *getpwuid PARAMS((uid_t)); +# endif +# if defined (HAVE_GETPWNAM) extern struct passwd *getpwnam PARAMS((const char *)); -#endif /* defined (HAVE_GETPWNAM) && !HAVE_GETPW_DECLS */ +# endif +#endif /* !HAVE_GETPW_DECLS */ #if !defined (savestring) #define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x)) @@ -279,6 +283,39 @@ isolate_tilde_prefix (fname, lenp) return ret; } +#if 0 +/* Public function to scan a string (FNAME) beginning with a tilde and find + the portion of the string that should be passed to the tilde expansion + function. Right now, it just calls tilde_find_suffix and allocates new + memory, but it can be expanded to do different things later. */ +char * +tilde_find_word (fname, flags, lenp) + const char *fname; + int flags, *lenp; +{ + int x; + char *r; + + x = tilde_find_suffix (fname); + if (x == 0) + { + r = savestring (fname); + if (lenp) + *lenp = 0; + } + else + { + r = (char *)xmalloc (1 + x); + strncpy (r, fname, x); + r[x] = '\0'; + if (lenp) + *lenp = x; + } + + return r; +} +#endif + /* Return a string that is PREFIX concatenated with SUFFIX starting at SUFFIND. */ static char * @@ -349,8 +386,11 @@ tilde_expand_word (filename) /* No preexpansion hook, or the preexpansion hook failed. Look in the password database. */ dirname = (char *)NULL; -#ifdef HAVE_GETPWNAM +#if defined (HAVE_GETPWNAM) user_entry = getpwnam (username); +#else + user_entry = 0; +#endif if (user_entry == 0) { /* If the calling program has a special syntax for expanding tildes, @@ -370,12 +410,12 @@ tilde_expand_word (filename) if (dirname == 0) dirname = savestring (filename); } +#if defined (HAVE_GETPWENT) else { free (username); dirname = glue_prefix_and_suffix (user_entry->pw_dir, filename, user_len); } - endpwent (); #endif return (dirname); diff --git a/readline/tilde.h b/readline/tilde.h index f8182c9..c58ce20 100644 --- a/readline/tilde.h +++ b/readline/tilde.h @@ -71,6 +71,9 @@ extern char *tilde_expand PARAMS((const char *)); tilde. If there is no expansion, call tilde_expansion_failure_hook. */ extern char *tilde_expand_word PARAMS((const char *)); +/* Find the portion of the string beginning with ~ that should be expanded. */ +extern char *tilde_find_word PARAMS((const char *, int, int *)); + #ifdef __cplusplus } #endif diff --git a/readline/undo.c b/readline/undo.c index 25c287b..fedfa12 100644 --- a/readline/undo.c +++ b/readline/undo.c @@ -237,7 +237,12 @@ rl_revert_line (count, key) { while (rl_undo_list) rl_do_undo (); +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode) + rl_point = rl_mark = 0; /* rl_end should be set correctly */ +#endif } + return 0; } diff --git a/readline/util.c b/readline/util.c index c7bd360..e44ef64 100644 --- a/readline/util.c +++ b/readline/util.c @@ -1,6 +1,6 @@ /* util.c -- readline utility functions */ -/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc. +/* Copyright (C) 1987-2005 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -44,6 +44,7 @@ /* System-specific feature definitions and include files. */ #include "rldefs.h" +#include "rlmbutil.h" #if defined (TIOCSTAT_IN_SYS_IOCTL) # include <sys/ioctl.h> @@ -78,13 +79,29 @@ rl_alphabetic (c) strchr (pathname_alphabetic_chars, c) != NULL); } +#if defined (HANDLE_MULTIBYTE) +int +_rl_walphabetic (wc) + wchar_t wc; +{ + int c; + + if (iswalnum (wc)) + return (1); + + c = wc & 0177; + return (_rl_allow_pathname_alphabetic_chars && + strchr (pathname_alphabetic_chars, c) != NULL); +} +#endif + /* How to abort things. */ int _rl_abort_internal () { rl_ding (); rl_clear_message (); - _rl_init_argument (); + _rl_reset_argument (); rl_clear_pending_input (); RL_UNSETSTATE (RL_STATE_MACRODEF); @@ -250,7 +267,7 @@ _rl_strpbrk (string1, string2) { v = _rl_get_char_len (string1, &ps); if (v > 1) - string += v - 1; /* -1 to account for auto-increment in loop */ + string1 += v - 1; /* -1 to account for auto-increment in loop */ } #endif } diff --git a/readline/vi_keymap.c b/readline/vi_keymap.c index 53a67c6..4b48c75 100644 --- a/readline/vi_keymap.c +++ b/readline/vi_keymap.c @@ -130,7 +130,7 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = { { ISFUNC, rl_revert_line }, /* U */ { ISFUNC, (rl_command_func_t *)0x0 }, /* V */ { ISFUNC, rl_vi_next_word }, /* W */ - { ISFUNC, rl_rubout }, /* X */ + { ISFUNC, rl_vi_rubout }, /* X */ { ISFUNC, rl_vi_yank_to }, /* Y */ { ISFUNC, (rl_command_func_t *)0x0 }, /* Z */ diff --git a/readline/vi_mode.c b/readline/vi_mode.c index 8930364..ac5fd74 100644 --- a/readline/vi_mode.c +++ b/readline/vi_mode.c @@ -1,7 +1,7 @@ /* vi_mode.c -- A vi emulation mode for Bash. Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */ -/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc. +/* Copyright (C) 1987-2005 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -63,6 +63,8 @@ #define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0) #endif +int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */ + /* Non-zero means enter insertion mode. */ static int _rl_vi_doing_insert; @@ -83,12 +85,12 @@ static int vi_continued_command; static char *vi_insert_buffer; static int vi_insert_buffer_size; -static int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */ static int _rl_vi_last_repeat = 1; static int _rl_vi_last_arg_sign = 1; static int _rl_vi_last_motion; #if defined (HANDLE_MULTIBYTE) static char _rl_vi_last_search_mbchar[MB_LEN_MAX]; +static int _rl_vi_last_search_mblen; #else static int _rl_vi_last_search_char; #endif @@ -106,8 +108,22 @@ static int vi_mark_chars['z' - 'a' + 1]; static void _rl_vi_stuff_insert PARAMS((int)); static void _rl_vi_save_insert PARAMS((UNDO_LIST *)); + +static int _rl_vi_arg_dispatch PARAMS((int)); static int rl_digit_loop1 PARAMS((void)); +static int _rl_vi_set_mark PARAMS((void)); +static int _rl_vi_goto_mark PARAMS((void)); + +static int _rl_vi_callback_getchar PARAMS((char *, int)); + +#if defined (READLINE_CALLBACKS) +static int _rl_vi_callback_set_mark PARAMS((_rl_callback_generic_arg *)); +static int _rl_vi_callback_goto_mark PARAMS((_rl_callback_generic_arg *)); +static int _rl_vi_callback_change_char PARAMS((_rl_callback_generic_arg *)); +static int _rl_vi_callback_char_search PARAMS((_rl_callback_generic_arg *)); +#endif + void _rl_vi_initialize_line () { @@ -115,6 +131,8 @@ _rl_vi_initialize_line () for (i = 0; i < sizeof (vi_mark_chars) / sizeof (int); i++) vi_mark_chars[i] = -1; + + RL_UNSETSTATE(RL_STATE_VICMDONCE); } void @@ -135,6 +153,16 @@ _rl_vi_set_last (key, repeat, sign) _rl_vi_last_arg_sign = sign; } +/* A convenience function that calls _rl_vi_set_last to save the last command + information and enters insertion mode. */ +void +rl_vi_start_inserting (key, repeat, sign) + int key, repeat, sign; +{ + _rl_vi_set_last (key, repeat, sign); + rl_vi_insertion_mode (1, key); +} + /* Is the command C a VI mode text modification command? */ int _rl_vi_textmod_command (c) @@ -261,10 +289,12 @@ rl_vi_search (count, key) switch (key) { case '?': + _rl_free_saved_history_line (); rl_noninc_forward_search (count, key); break; case '/': + _rl_free_saved_history_line (); rl_noninc_reverse_search (count, key); break; @@ -297,10 +327,8 @@ rl_vi_complete (ignore, key) rl_complete (0, key); if (key == '*' || key == '\\') - { - _rl_vi_set_last (key, 1, rl_arg_sign); - rl_vi_insertion_mode (1, key); - } + rl_vi_start_inserting (key, 1, rl_arg_sign); + return (0); } @@ -310,8 +338,7 @@ rl_vi_tilde_expand (ignore, key) int ignore, key; { rl_tilde_expand (0, key); - _rl_vi_set_last (key, 1, rl_arg_sign); /* XXX */ - rl_vi_insertion_mode (1, key); + rl_vi_start_inserting (key, 1, rl_arg_sign); return (0); } @@ -429,7 +456,8 @@ rl_vi_eWord (count, ignore) /* Move to the next non-whitespace character (to the start of the next word). */ - while (++rl_point < rl_end && whitespace (rl_line_buffer[rl_point])); + while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) + rl_point++; if (rl_point && rl_point < rl_end) { @@ -640,7 +668,7 @@ _rl_vi_done_inserting () } else { - if (_rl_vi_last_key_before_insert == 'i' && rl_undo_list) + if ((_rl_vi_last_key_before_insert == 'i' || _rl_vi_last_key_before_insert == 'a') && rl_undo_list) _rl_vi_save_insert (rl_undo_list); /* XXX - Other keys probably need to be checked. */ else if (_rl_vi_last_key_before_insert == 'C') @@ -660,6 +688,13 @@ rl_vi_movement_mode (count, key) _rl_keymap = vi_movement_keymap; _rl_vi_done_inserting (); + + /* This is how POSIX.2 says `U' should behave -- everything up until the + first time you go into command mode should not be undone. */ + if (RL_ISSTATE (RL_STATE_VICMDONCE) == 0) + rl_free_undo_list (); + + RL_SETSTATE (RL_STATE_VICMDONCE); return (0); } @@ -681,7 +716,7 @@ _rl_vi_change_mbchar_case (count) { wchar_t wc; char mb[MB_LEN_MAX+1]; - int mblen; + int mblen, p; mbstate_t ps; memset (&ps, 0, sizeof (mbstate_t)); @@ -704,11 +739,14 @@ _rl_vi_change_mbchar_case (count) /* Vi is kind of strange here. */ if (wc) { - mblen = wctomb (mb, wc); + p = rl_point; + mblen = wcrtomb (mb, wc, &ps); if (mblen >= 0) mb[mblen] = '\0'; rl_begin_undo_group (); - rl_delete (1, 0); + rl_vi_delete (1, 0); + if (rl_point < p) /* Did we retreat at EOL? */ + rl_point++; /* XXX - should we advance more than 1 for mbchar? */ rl_insert_text (mb); rl_end_undo_group (); rl_vi_check (); @@ -725,12 +763,13 @@ int rl_vi_change_case (count, ignore) int count, ignore; { - char c = 0; + int c, p; /* Don't try this on an empty line. */ if (rl_point >= rl_end) return (0); + c = 0; #if defined (HANDLE_MULTIBYTE) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) return (_rl_vi_change_mbchar_case (count)); @@ -752,8 +791,11 @@ rl_vi_change_case (count, ignore) /* Vi is kind of strange here. */ if (c) { + p = rl_point; rl_begin_undo_group (); - rl_delete (1, c); + rl_vi_delete (1, c); + if (rl_point < p) /* Did we retreat at EOL? */ + rl_point++; _rl_insert_char (1, c); rl_end_undo_group (); rl_vi_check (); @@ -771,7 +813,9 @@ rl_vi_put (count, key) if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end)) rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); - rl_yank (1, key); + while (count--) + rl_yank (1, key); + rl_backward_char (1, key); return (0); } @@ -819,7 +863,10 @@ rl_vi_domove (key, nextkey) { save = rl_numeric_arg; rl_numeric_arg = _rl_digit_value (c); + rl_explicit_arg = 1; + RL_SETSTATE (RL_STATE_NUMERICARG|RL_STATE_VIMOTION); rl_digit_loop1 (); + RL_UNSETSTATE (RL_STATE_VIMOTION); rl_numeric_arg *= save; RL_SETSTATE(RL_STATE_MOREINPUT); c = rl_read_key (); /* real command */ @@ -892,52 +939,59 @@ rl_vi_domove (key, nextkey) return (0); } +/* Process C as part of the current numeric argument. Return -1 if the + argument should be aborted, 0 if we should not read any more chars, and + 1 if we should continue to read chars. */ +static int +_rl_vi_arg_dispatch (c) + int c; +{ + int key; + + key = c; + if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument) + { + rl_numeric_arg *= 4; + return 1; + } + + c = UNMETA (c); + + if (_rl_digit_p (c)) + { + if (rl_explicit_arg) + rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c); + else + rl_numeric_arg = _rl_digit_value (c); + rl_explicit_arg = 1; + return 1; + } + else + { + rl_clear_message (); + rl_stuff_char (key); + return 0; + } +} + /* A simplified loop for vi. Don't dispatch key at end. Don't recognize minus sign? Should this do rl_save_prompt/rl_restore_prompt? */ static int rl_digit_loop1 () { - int key, c; + int c, r; - RL_SETSTATE(RL_STATE_NUMERICARG); while (1) { - if (rl_numeric_arg > 1000000) - { - rl_explicit_arg = rl_numeric_arg = 0; - rl_ding (); - rl_clear_message (); - RL_UNSETSTATE(RL_STATE_NUMERICARG); - return 1; - } - rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg); - RL_SETSTATE(RL_STATE_MOREINPUT); - key = c = rl_read_key (); - RL_UNSETSTATE(RL_STATE_MOREINPUT); + if (_rl_arg_overflow ()) + return 1; - if (c >= 0 && _rl_keymap[c].type == ISFUNC && - _rl_keymap[c].function == rl_universal_argument) - { - rl_numeric_arg *= 4; - continue; - } + c = _rl_arg_getchar (); - c = UNMETA (c); - if (_rl_digit_p (c)) - { - if (rl_explicit_arg) - rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c); - else - rl_numeric_arg = _rl_digit_value (c); - rl_explicit_arg = 1; - } - else - { - rl_clear_message (); - rl_stuff_char (key); - break; - } + r = _rl_vi_arg_dispatch (c); + if (r <= 0) + break; } RL_UNSETSTATE(RL_STATE_NUMERICARG); @@ -1017,8 +1071,7 @@ rl_vi_change_to (count, key) /* `C' does not save the text inserted for undoing or redoing. */ if (_rl_uppercase_p (key) == 0) _rl_vi_doing_insert = 1; - _rl_vi_set_last (key, count, rl_arg_sign); - rl_vi_insertion_mode (1, key); + rl_vi_start_inserting (key, rl_numeric_arg, rl_arg_sign); } return (0); @@ -1028,8 +1081,9 @@ int rl_vi_yank_to (count, key) int count, key; { - int c, save = rl_point; + int c, save; + save = rl_point; if (_rl_uppercase_p (key)) rl_stuff_char ('$'); @@ -1054,11 +1108,45 @@ rl_vi_yank_to (count, key) } int +rl_vi_rubout (count, key) + int count, key; +{ + int p, opoint; + + if (count < 0) + return (rl_vi_delete (-count, key)); + + if (rl_point == 0) + { + rl_ding (); + return -1; + } + + opoint = rl_point; + if (count > 1 && MB_CUR_MAX > 1 && rl_byte_oriented == 0) + rl_backward_char (count, key); + else if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO); + else + rl_point -= count; + + if (rl_point < 0) + rl_point = 0; + + rl_kill_text (rl_point, opoint); + + return (0); +} + +int rl_vi_delete (count, key) int count, key; { int end; + if (count < 0) + return (rl_vi_rubout (-count, key)); + if (rl_end == 0) { rl_ding (); @@ -1077,6 +1165,7 @@ rl_vi_delete (count, key) if (rl_point > 0 && rl_point == rl_end) rl_backward_char (1, key); + return (0); } @@ -1097,64 +1186,102 @@ rl_vi_first_print (count, key) return (rl_vi_back_to_indent (1, key)); } +static int _rl_cs_dir, _rl_cs_orig_dir; + +#if defined (READLINE_CALLBACKS) +static int +_rl_vi_callback_char_search (data) + _rl_callback_generic_arg *data; +{ +#if defined (HANDLE_MULTIBYTE) + _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX); +#else + RL_SETSTATE(RL_STATE_MOREINPUT); + _rl_vi_last_search_char = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); +#endif + + _rl_callback_func = 0; + _rl_want_redisplay = 1; + +#if defined (HANDLE_MULTIBYTE) + return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_mbchar, _rl_vi_last_search_mblen)); +#else + return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_char)); +#endif +} +#endif + int rl_vi_char_search (count, key) int count, key; { #if defined (HANDLE_MULTIBYTE) static char *target; - static int mb_len; + static int tlen; #else static char target; #endif - static int orig_dir, dir; if (key == ';' || key == ',') - dir = key == ';' ? orig_dir : -orig_dir; + _rl_cs_dir = (key == ';') ? _rl_cs_orig_dir : -_rl_cs_orig_dir; else { - if (vi_redoing) -#if defined (HANDLE_MULTIBYTE) - target = _rl_vi_last_search_mbchar; -#else - target = _rl_vi_last_search_char; -#endif - else - { -#if defined (HANDLE_MULTIBYTE) - mb_len = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX); - target = _rl_vi_last_search_mbchar; -#else - RL_SETSTATE(RL_STATE_MOREINPUT); - _rl_vi_last_search_char = target = rl_read_key (); - RL_UNSETSTATE(RL_STATE_MOREINPUT); -#endif - } - switch (key) { case 't': - orig_dir = dir = FTO; + _rl_cs_orig_dir = _rl_cs_dir = FTO; break; case 'T': - orig_dir = dir = BTO; + _rl_cs_orig_dir = _rl_cs_dir = BTO; break; case 'f': - orig_dir = dir = FFIND; + _rl_cs_orig_dir = _rl_cs_dir = FFIND; break; case 'F': - orig_dir = dir = BFIND; + _rl_cs_orig_dir = _rl_cs_dir = BFIND; break; } + + if (vi_redoing) + { + /* set target and tlen below */ + } +#if defined (READLINE_CALLBACKS) + else if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + _rl_callback_data = _rl_callback_data_alloc (count); + _rl_callback_data->i1 = _rl_cs_dir; + _rl_callback_func = _rl_vi_callback_char_search; + return (0); + } +#endif + else + { +#if defined (HANDLE_MULTIBYTE) + _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX); +#else + RL_SETSTATE(RL_STATE_MOREINPUT); + _rl_vi_last_search_char = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); +#endif + } } #if defined (HANDLE_MULTIBYTE) - return (_rl_char_search_internal (count, dir, target, mb_len)); + target = _rl_vi_last_search_mbchar; + tlen = _rl_vi_last_search_mblen; +#else + target = _rl_vi_last_search_char; +#endif + +#if defined (HANDLE_MULTIBYTE) + return (_rl_char_search_internal (count, _rl_cs_dir, target, tlen)); #else - return (_rl_char_search_internal (count, dir, target)); + return (_rl_char_search_internal (count, _rl_cs_dir, target)); #endif } @@ -1265,60 +1392,109 @@ rl_vi_bracktype (c) } } -/* XXX - think about reading an entire mbchar with _rl_read_mbchar and - inserting it in one bunch instead of the loop below (like in - rl_vi_char_search or _rl_vi_change_mbchar_case. Set c to mbchar[0] - for test against 033 or ^C. Make sure that _rl_read_mbchar does - this right. */ -int -rl_vi_change_char (count, key) - int count, key; +static int +_rl_vi_change_char (count, c, mb) + int count, c; + char *mb; { - int c; - - if (vi_redoing) - c = _rl_vi_last_replacement; - else - { - RL_SETSTATE(RL_STATE_MOREINPUT); - _rl_vi_last_replacement = c = rl_read_key (); - RL_UNSETSTATE(RL_STATE_MOREINPUT); - } + int p; if (c == '\033' || c == CTRL ('C')) return -1; + rl_begin_undo_group (); while (count-- && rl_point < rl_end) { - rl_begin_undo_group (); - - rl_delete (1, c); + p = rl_point; + rl_vi_delete (1, c); + if (rl_point < p) /* Did we retreat at EOL? */ + rl_point++; #if defined (HANDLE_MULTIBYTE) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - while (_rl_insert_char (1, c)) - { - RL_SETSTATE (RL_STATE_MOREINPUT); - c = rl_read_key (); - RL_UNSETSTATE (RL_STATE_MOREINPUT); - } + rl_insert_text (mb); else #endif _rl_insert_char (1, c); - if (count == 0) - rl_backward_char (1, c); - - rl_end_undo_group (); } + + /* The cursor shall be left on the last character changed. */ + rl_backward_char (1, c); + + rl_end_undo_group (); + return (0); } +static int +_rl_vi_callback_getchar (mb, mblen) + char *mb; + int mblen; +{ + int c; + + RL_SETSTATE(RL_STATE_MOREINPUT); + c = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + c = _rl_read_mbstring (c, mb, mblen); +#endif + + return c; +} + +#if defined (READLINE_CALLBACKS) +static int +_rl_vi_callback_change_char (data) + _rl_callback_generic_arg *data; +{ + int c; + char mb[MB_LEN_MAX]; + + _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX); + + _rl_callback_func = 0; + _rl_want_redisplay = 1; + + return (_rl_vi_change_char (data->count, c, mb)); +} +#endif + +int +rl_vi_change_char (count, key) + int count, key; +{ + int c; + char mb[MB_LEN_MAX]; + + if (vi_redoing) + { + c = _rl_vi_last_replacement; + mb[0] = c; + mb[1] = '\0'; + } +#if defined (READLINE_CALLBACKS) + else if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + _rl_callback_data = _rl_callback_data_alloc (count); + _rl_callback_func = _rl_vi_callback_change_char; + return (0); + } +#endif + else + _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX); + + return (_rl_vi_change_char (count, c, mb)); +} + int rl_vi_subst (count, key) int count, key; { /* If we are redoing, rl_vi_change_to will stuff the last motion char */ if (vi_redoing == 0) - rl_stuff_char ((key == 'S') ? 'c' : ' '); /* `S' == `cc', `s' == `c ' */ + rl_stuff_char ((key == 'S') ? 'c' : 'l'); /* `S' == `cc', `s' == `cl' */ return (rl_vi_change_to (count, 'c')); } @@ -1434,9 +1610,8 @@ rl_vi_possible_completions() #endif /* Functions to save and restore marks. */ -int -rl_vi_set_mark (count, key) - int count, key; +static int +_rl_vi_set_mark () { int ch; @@ -1454,10 +1629,37 @@ rl_vi_set_mark (count, key) return 0; } +#if defined (READLINE_CALLBACKS) +static int +_rl_vi_callback_set_mark (data) + _rl_callback_generic_arg *data; +{ + _rl_callback_func = 0; + _rl_want_redisplay = 1; + + return (_rl_vi_set_mark ()); +} +#endif + int -rl_vi_goto_mark (count, key) +rl_vi_set_mark (count, key) int count, key; { +#if defined (READLINE_CALLBACKS) + if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + _rl_callback_data = 0; + _rl_callback_func = _rl_vi_callback_set_mark; + return (0); + } +#endif + + return (_rl_vi_set_mark ()); +} + +static int +_rl_vi_goto_mark () +{ int ch; RL_SETSTATE(RL_STATE_MOREINPUT); @@ -1485,4 +1687,31 @@ rl_vi_goto_mark (count, key) return 0; } +#if defined (READLINE_CALLBACKS) +static int +_rl_vi_callback_goto_mark (data) + _rl_callback_generic_arg *data; +{ + _rl_callback_func = 0; + _rl_want_redisplay = 1; + + return (_rl_vi_goto_mark ()); +} +#endif + +int +rl_vi_goto_mark (count, key) + int count, key; +{ +#if defined (READLINE_CALLBACKS) + if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + _rl_callback_data = 0; + _rl_callback_func = _rl_vi_callback_goto_mark; + return (0); + } +#endif + + return (_rl_vi_goto_mark ()); +} #endif /* VI_MODE */ diff --git a/sim/ChangeLog b/sim/ChangeLog index c5b1af0..d7d51b0 100644 --- a/sim/ChangeLog +++ b/sim/ChangeLog @@ -1,3 +1,17 @@ +2006-05-05 Andreas Schwab <schwab@suse.de> + + * configure.ac (CFLAGS_FOR_BUILD): Set and substitute. + * configure: Regenerate. + + * Makefile.in (CFLAGS_FOR_BUILD): Define. + (CC_FOR_BUILD): Don't override. + (FLAGS_TO_PASS): Pass CFLAGS_FOR_BUILD. + +2006-05-04 Daniel Jacobowitz <dan@codesourcery.com> + + * MAINTAINERS: Add an "Authorized committers" section, and list + DJ Delorie for v850. + 2006-04-08 Hans-Peter Nilsson <hp@axis.com> * cris/crisv32f.c (MY (deliver_interrupt)): Set CCS to new_ccs. diff --git a/sim/MAINTAINERS b/sim/MAINTAINERS index 395a88f..8969e5c 100644 --- a/sim/MAINTAINERS +++ b/sim/MAINTAINERS @@ -20,6 +20,9 @@ common Ben Elliston <bje@gnu.org> common Frank Ch. Eigler <fche@redhat.com> * (target, then global maintainers) + Authorized committers for particular sims: +v850 DJ Delorie <dj@redhat.com> + Past sim maintainers: mips Andrew Cagney <ac131313@redhat.com> diff --git a/sim/Makefile.in b/sim/Makefile.in index fdbcded..3960620 100644 --- a/sim/Makefile.in +++ b/sim/Makefile.in @@ -56,6 +56,7 @@ AR_FLAGS = rc CC = @CC@ CFLAGS = @CFLAGS@ CC_FOR_BUILD = @CC_FOR_BUILD@ +CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ MAKEINFO = makeinfo RANLIB = @RANLIB@ @@ -65,10 +66,6 @@ INCDIR = $(srcdir)/../include CSEARCH = -I. -I$(srcdir) -I$(INCDIR) DEP = mkdep -# compilers to use to create programs which must be run in the build -# environment. -CC_FOR_BUILD = $(CC) - #### Makefile fragments come in here. # @target_makefile_frag@ ### @@ -93,6 +90,7 @@ FLAGS_TO_PASS = \ "CC=$(CC)" \ "CC_FOR_BUILD=$(CC_FOR_BUILD)" \ "CFLAGS=$(CFLAGS)" \ + "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \ "RANLIB=$(RANLIB)" \ "MAKEINFO=$(MAKEINFO)" \ "INSTALL=$(INSTALL)" \ diff --git a/sim/configure b/sim/configure index 3708628..8346c59 100755 --- a/sim/configure +++ b/sim/configure @@ -291,7 +291,7 @@ ac_subdirs_all="$ac_subdirs_all v850" ac_subdirs_all="$ac_subdirs_all testsuite" ac_subdirs_all="$ac_subdirs_all common" ac_subdirs_all="$ac_subdirs_all igen" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AR ac_ct_AR RANLIB ac_ct_RANLIB build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os HDEFINES CC_FOR_BUILD subdirs LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AR ac_ct_AR RANLIB ac_ct_RANLIB build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os HDEFINES CC_FOR_BUILD CFLAGS_FOR_BUILD subdirs LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -3387,6 +3387,8 @@ else CC_FOR_BUILD=gcc fi +CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-${CFLAGS}} + # If a cpu ever has more than one simulator to choose from, use # --enable-sim=... to choose. @@ -4223,6 +4225,7 @@ s,@target_vendor@,$target_vendor,;t t s,@target_os@,$target_os,;t t s,@HDEFINES@,$HDEFINES,;t t s,@CC_FOR_BUILD@,$CC_FOR_BUILD,;t t +s,@CFLAGS_FOR_BUILD@,$CFLAGS_FOR_BUILD,;t t s,@subdirs@,$subdirs,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t diff --git a/sim/configure.ac b/sim/configure.ac index fc1ac57..205482b 100644 --- a/sim/configure.ac +++ b/sim/configure.ac @@ -23,6 +23,8 @@ else CC_FOR_BUILD=gcc fi AC_SUBST(CC_FOR_BUILD) +CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-${CFLAGS}} +AC_SUBST(CFLAGS_FOR_BUILD) # If a cpu ever has more than one simulator to choose from, use # --enable-sim=... to choose. diff --git a/sim/ppc/ChangeLog b/sim/ppc/ChangeLog index 4268294..5720159 100644 --- a/sim/ppc/ChangeLog +++ b/sim/ppc/ChangeLog @@ -1,3 +1,18 @@ +2006-05-05 Andreas Schwab <schwab@suse.de> + + * configure.ac (CFLAGS_FOR_BUILD): Set and substitute. + * configure: Regenerate. + + * Makefile.in (CFLAGS_FOR_BUILD): Define. + (BUILD_CFLAGS): Use it instead of hardcoding "-g -O". + (gentmap): Fix typo BUILD_FLAGS -> BUILD_CFLAGS. + +2006-04-23 Andreas Schwab <schwab@suse.de> + + * Makefile.in (tmp-ld-decode): Fix dependencies. + (tmp-ld-cache): Likewise. + (tmp-ld-insn): Likewise. + 2006-02-01 Mark Mitchell <mark@codesourcery.com> * emul_netbsd.c (emul_netbsd_create): Quote file-name property. diff --git a/sim/ppc/Makefile.in b/sim/ppc/Makefile.in index 79fec05..410d993 100644 --- a/sim/ppc/Makefile.in +++ b/sim/ppc/Makefile.in @@ -63,6 +63,7 @@ AR_FLAGS = rc CC = @CC@ CFLAGS = @CFLAGS@ CC_FOR_BUILD = @CC_FOR_BUILD@ +CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ BISON = bison MAKEINFO = makeinfo RANLIB = @RANLIB@ @@ -116,7 +117,7 @@ SIM_FPU_CFLAGS = @sim_fpu_cflags@ STD_CFLAGS = $(CFLAGS) $(INLINE_CFLAGS) $(CONFIG_CFLAGS) $(WARNING_CFLAGS) $(SIM_CFLAGS) $(HDEFINES) $(TDEFINES) $(INCLUDES) $(INTL_CFLAGS) $(SIM_FPU_CFLAGS) NOWARN_CFLAGS = $(CFLAGS) $(INLINE_CFLAGS) $(CONFIG_CFLAGS) $(SIM_CFLAGS) $(HDEFINES) $(TDEFINES) $(INCLUDES) $(SIM_FPU_CFLAGS) -BUILD_CFLAGS = -g -O $(INCLUDES) $(WARNING_CFLAGS) +BUILD_CFLAGS = $(CFLAGS_FOR_BUILD) $(INCLUDES) $(WARNING_CFLAGS) BUILD_LDFLAGS = @@ -627,7 +628,7 @@ mon.o: mon.c $(BASICS_H) $(CPU_H) $(MON_H) # GDB after 4.16 expects the default_callback structure to be setup. # As a kludge, build the common stuff here for now. gentmap: ../common/gentmap.c Makefile targ-vals.def - $(CC_FOR_BUILD) $(BUILD_FLAGS) -I. -I../common -I$(srcdir)/../common -o gentmap $< $(BUILD_LIBS) + $(CC_FOR_BUILD) $(BUILD_CFLAGS) -I. -I../common -I$(srcdir)/../common -o gentmap $< $(BUILD_LIBS) targ-vals.def: $(srcdir)/../common/nltvals.def rm -f targ-vals.def tmp-def @@ -745,17 +746,17 @@ tmp-filter: filter.c $(MISC_H) misc.o ld-decode.o: ld-decode.c $(MISC_H) $(LF_H) $(TABLE_H) $(LD_DECODE_H) $(CC_FOR_BUILD) $(BUILD_CFLAGS) -c $(srcdir)/ld-decode.c -tmp-ld-decode: ld-decode.o misc.o lf.o table.o filter_host.o +tmp-ld-decode: ld-decode.c misc.o lf.o table.o filter_host.o $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o tmp-ld-decode -DMAIN $(srcdir)/ld-decode.c misc.o lf.o table.o filter_host.o $(BUILD_LIBS) ld-cache.o: ld-cache.c $(MISC_H) $(LF_H) $(TABLE_H) $(LD_CACHE_H) $(CC_FOR_BUILD) $(BUILD_CFLAGS) -c $(srcdir)/ld-cache.c -tmp-ld-cache: ld-cache.o misc.o lf.o table.o filter_host.o +tmp-ld-cache: ld-cache.c misc.o lf.o table.o filter_host.o $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o tmp-ld-cache -DMAIN $(srcdir)/ld-cache.c misc.o lf.o table.o filter_host.o $(BUILD_LIBS) ld-insn.o: ld-insn.c $(MISC_H) $(LF_H) $(TABLE_H) $(FILTER_H) $(LD_DECODE_H) $(LD_CACHE_H) $(LD_INSN_H) $(IGEN_H) $(CC_FOR_BUILD) $(BUILD_CFLAGS) -c $(srcdir)/ld-insn.c -tmp-ld-insn: ld-insn.o misc.o lf.o table.o ld-decode.o filter_host.o filter.o +tmp-ld-insn: ld-insn.c ld-cache.o misc.o lf.o table.o ld-decode.o filter_host.o filter.o $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o tmp-ld-insn -DMAIN $(srcdir)/ld-insn.c ld-cache.o misc.o lf.o table.o ld-decode.o filter_host.o filter.o $(BUILD_LIBS) gen-model.o: gen-model.c $(MISC_H) $(LF_H) $(TABLE_H) $(FILTER_H) $(LD_CACHE_H) $(LD_DECODE_H) $(LD_INSN_H) $(GEN_MODEL_H) diff --git a/sim/ppc/configure b/sim/ppc/configure index 9e592fa..7bb5fd8 100755 --- a/sim/ppc/configure +++ b/sim/ppc/configure @@ -309,7 +309,7 @@ ac_includes_default="\ # include <unistd.h> #endif" -ac_subst_vars='sim_environment sim_alignment sim_assert sim_bitsize sim_endian sim_hostendian sim_float sim_scache sim_default_model sim_hw_cflags sim_hw_objs sim_hw sim_inline sim_packages sim_regparm sim_reserved_bits sim_smp sim_stdcall sim_xor_endian WARN_CFLAGS WERROR_CFLAGS SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT SET_MAKE RANLIB ac_ct_RANLIB CPP EGREP ALLOCA USE_NLS MSGFMT GMSGFMT XGETTEXT USE_INCLUDED_LIBINTL CATALOGS CATOBJEXT DATADIRNAME GMOFILES INSTOBJEXT INTLDEPS INTLLIBS INTLOBJS POFILES POSUB INCLUDE_LOCALE_H GT_NO GT_YES MKINSTALLDIRS l build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os LIBOBJS CC_FOR_BUILD HDEFINES AR sim_cflags sim_warnings sim_line_nr sim_config sim_opcode sim_switch sim_dup sim_decode_mechanism sim_jump sim_filter sim_icache sim_hw_src sim_hw_obj sim_pk_src sim_pk_obj sim_bswap sim_igen_smp sim_hostbitsize sim_env sim_timebase sim_trace sim_reserved sim_monitor sim_model sim_model_issue sim_stdio sim_termio sim_devzero sim_callback sim_targ_vals sim_fpu_cflags sim_fpu LTLIBOBJS' +ac_subst_vars='sim_environment sim_alignment sim_assert sim_bitsize sim_endian sim_hostendian sim_float sim_scache sim_default_model sim_hw_cflags sim_hw_objs sim_hw sim_inline sim_packages sim_regparm sim_reserved_bits sim_smp sim_stdcall sim_xor_endian WARN_CFLAGS WERROR_CFLAGS SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT SET_MAKE RANLIB ac_ct_RANLIB CPP EGREP ALLOCA USE_NLS MSGFMT GMSGFMT XGETTEXT USE_INCLUDED_LIBINTL CATALOGS CATOBJEXT DATADIRNAME GMOFILES INSTOBJEXT INTLDEPS INTLLIBS INTLOBJS POFILES POSUB INCLUDE_LOCALE_H GT_NO GT_YES MKINSTALLDIRS l build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os LIBOBJS CC_FOR_BUILD CFLAGS_FOR_BUILD HDEFINES AR sim_cflags sim_warnings sim_line_nr sim_config sim_opcode sim_switch sim_dup sim_decode_mechanism sim_jump sim_filter sim_icache sim_hw_src sim_hw_obj sim_pk_src sim_pk_obj sim_bswap sim_igen_smp sim_hostbitsize sim_env sim_timebase sim_trace sim_reserved sim_monitor sim_model sim_model_issue sim_stdio sim_termio sim_devzero sim_callback sim_targ_vals sim_fpu_cflags sim_fpu LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -2381,6 +2381,7 @@ if test "x$cross_compiling" = "xno"; then else CC_FOR_BUILD=gcc fi +CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-${CFLAGS}} ALL_LINGUAS= echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 @@ -8992,6 +8993,7 @@ fi + AR=${AR-ar} if test -n "$ac_tool_prefix"; then @@ -9808,6 +9810,7 @@ s,@target_vendor@,$target_vendor,;t t s,@target_os@,$target_os,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@CC_FOR_BUILD@,$CC_FOR_BUILD,;t t +s,@CFLAGS_FOR_BUILD@,$CFLAGS_FOR_BUILD,;t t s,@HDEFINES@,$HDEFINES,;t t s,@AR@,$AR,;t t s,@sim_cflags@,$sim_cflags,;t t diff --git a/sim/ppc/configure.ac b/sim/ppc/configure.ac index c51553f..83a12fb 100644 --- a/sim/ppc/configure.ac +++ b/sim/ppc/configure.ac @@ -12,6 +12,7 @@ if test "x$cross_compiling" = "xno"; then else CC_FOR_BUILD=gcc fi +CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-${CFLAGS}} dnl We don't use gettext, but bfd does. So we do the appropriate checks dnl to see if there are intl libraries we should link against. @@ -747,6 +748,7 @@ dnl Check for exe extension AC_EXEEXT AC_SUBST(CC_FOR_BUILD) +AC_SUBST(CFLAGS_FOR_BUILD) AC_SUBST(CFLAGS) AC_SUBST(HDEFINES) AR=${AR-ar} |